mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-18 03:35:07 +02:00
Fixed a bug with spec maps.
This commit is contained in:
@@ -2315,6 +2315,8 @@ struct glRaytracingLightingState_t
|
||||
bool externalDenoiser;
|
||||
ID3D12Resource* emissiveTexture;
|
||||
DXGI_FORMAT emissiveFormat;
|
||||
ID3D12Resource* specularTexture;
|
||||
DXGI_FORMAT specularFormat;
|
||||
bool uploadToCurrentFrameResource;
|
||||
bool initialized;
|
||||
|
||||
@@ -2341,6 +2343,8 @@ struct glRaytracingLightingState_t
|
||||
externalDenoiser = false;
|
||||
emissiveTexture = nullptr;
|
||||
emissiveFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
specularTexture = nullptr;
|
||||
specularFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
uploadToCurrentFrameResource = false;
|
||||
initialized = false;
|
||||
}
|
||||
@@ -2364,14 +2368,15 @@ enum glRaytracingLightingDescriptorIndex_t
|
||||
GLR_DESC_HISTORY_SRV = 9,
|
||||
GLR_DESC_TEMPORAL_SRV = 10,
|
||||
GLR_DESC_EMISSIVE_SRV = 11,
|
||||
GLR_DESC_PATHTRACE_UAV = 12,
|
||||
GLR_DESC_DENOISE_A_UAV = 13,
|
||||
GLR_DESC_DENOISE_B_UAV = 14,
|
||||
GLR_DESC_OUTPUT_UAV = 15,
|
||||
GLR_DESC_TEMPORAL_UAV = 16,
|
||||
GLR_DESC_HISTORY_UAV = 17,
|
||||
GLR_DESC_COUNT = 18,
|
||||
GLR_DESC_SRV_COUNT = 12,
|
||||
GLR_DESC_SPECULAR_SRV = 12,
|
||||
GLR_DESC_PATHTRACE_UAV = 13,
|
||||
GLR_DESC_DENOISE_A_UAV = 14,
|
||||
GLR_DESC_DENOISE_B_UAV = 15,
|
||||
GLR_DESC_OUTPUT_UAV = 16,
|
||||
GLR_DESC_TEMPORAL_UAV = 17,
|
||||
GLR_DESC_HISTORY_UAV = 18,
|
||||
GLR_DESC_COUNT = 19,
|
||||
GLR_DESC_SRV_COUNT = 13,
|
||||
GLR_DESC_UAV_COUNT = 6
|
||||
};
|
||||
|
||||
@@ -2466,6 +2471,7 @@ Texture2D<float4> gNormalTex : register(t3);
|
||||
Texture2D<float4> gPositionTex : register(t4);
|
||||
RaytracingAccelerationStructure gSceneBVH : register(t5);
|
||||
Texture2D<float4> gEmissiveTex : register(t11);
|
||||
Texture2D<float4> gSpecularTex : register(t12);
|
||||
RWTexture2D<float4> gOutputTex : register(u0);
|
||||
|
||||
static const uint GL_RAYTRACING_LIGHT_TYPE_POINT = 0;
|
||||
@@ -3252,10 +3258,8 @@ float Doom3SpecularLookup(float x)
|
||||
float3 Doom3PseudoSpecularMask(float3 baseAlbedo)
|
||||
{
|
||||
// Doom 3 normally uses a dedicated specular map.
|
||||
// This pass does not have one bound, so DO NOT square diffuse albedo.
|
||||
// Squaring albedo makes dark Doom 3 textures lose all specular response.
|
||||
//
|
||||
// Use luminance only as a weak hint, with a neutral floor.
|
||||
// This fallback is only used for pixels whose specular G-buffer says no
|
||||
// specular map was written by the raster pass.
|
||||
float lum = dot(saturate(baseAlbedo), float3(0.299, 0.587, 0.114));
|
||||
|
||||
float specStrength = lerp(0.22, 0.72, saturate(lum * 1.35));
|
||||
@@ -3268,6 +3272,18 @@ float3 Doom3PseudoSpecularMask(float3 baseAlbedo)
|
||||
return max(tintedSpec, float3(0.18, 0.18, 0.18));
|
||||
}
|
||||
|
||||
float3 LoadSceneSpecularAlbedo(uint2 pixel, float3 baseAlbedo)
|
||||
{
|
||||
float4 specSample = gSpecularTex.Load(int3(pixel, 0));
|
||||
|
||||
// The raster G-buffer writer stores alpha as a validity bit. This matters
|
||||
// for black specular maps: black should mean zero specular, not "missing map".
|
||||
if (specSample.a > 0.5)
|
||||
return saturate(specSample.rgb);
|
||||
|
||||
return Doom3PseudoSpecularMask(baseAlbedo);
|
||||
}
|
||||
|
||||
float3 ComputeSpecular(
|
||||
float3 N,
|
||||
float3 V,
|
||||
@@ -3276,7 +3292,7 @@ float3 ComputeSpecular(
|
||||
float lightIntensity,
|
||||
float atten,
|
||||
float shadow,
|
||||
float3 baseAlbedo)
|
||||
float3 specularAlbedo)
|
||||
{
|
||||
if (gEnableSpecular == 0)
|
||||
return 0.0;
|
||||
@@ -3301,7 +3317,7 @@ float3 ComputeSpecular(
|
||||
|
||||
float specTerm = Doom3SpecularLookup(NdotH);
|
||||
|
||||
float3 specMask = Doom3PseudoSpecularMask(baseAlbedo);
|
||||
float3 specMask = saturate(specularAlbedo);
|
||||
|
||||
// Doom 3's interaction pass is strongly additive. Keep it punchy,
|
||||
// but clamp enough to avoid fireflies with stochastic light sampling.
|
||||
@@ -3611,7 +3627,7 @@ float3 EstimatePathTracedSky(float3 worldPos, float3 N, inout uint rng)
|
||||
return accum * 0.55;
|
||||
}
|
||||
|
||||
float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3 V, float3 baseAlbedo, Light Lgt, inout uint rng, out float3 specularOut)
|
||||
float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3 V, float3 baseAlbedo, float3 specularAlbedo, Light Lgt, inout uint rng, out float3 specularOut)
|
||||
{
|
||||
specularOut = 0.0;
|
||||
|
||||
@@ -3663,7 +3679,7 @@ float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3
|
||||
shadow = TraceVisibilityBiased(worldPos, N, L, dist);
|
||||
|
||||
if (Lgt.pointRadiusPad <= 0.5)
|
||||
specAccum += ComputeSpecular(N, V, L, Lgt.color, Lgt.intensity, atten, shadow, baseAlbedo);
|
||||
specAccum += ComputeSpecular(N, V, L, Lgt.color, Lgt.intensity, atten, shadow, specularAlbedo);
|
||||
|
||||
diffuseAccum += Lgt.color * (Lgt.intensity * atten * NdotLWrap * shadow);
|
||||
}
|
||||
@@ -3673,7 +3689,7 @@ float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3
|
||||
return diffuseAccum * invSamples;
|
||||
}
|
||||
|
||||
float3 PathTraceDirectSpotLight(float3 worldPos, float3 N, float3 V, float3 baseAlbedo, Light Lgt, inout uint rng, out float3 specularOut)
|
||||
float3 PathTraceDirectSpotLight(float3 worldPos, float3 N, float3 V, float3 baseAlbedo, float3 specularAlbedo, Light Lgt, inout uint rng, out float3 specularOut)
|
||||
{
|
||||
specularOut = 0.0;
|
||||
|
||||
@@ -3693,12 +3709,12 @@ float3 PathTraceDirectSpotLight(float3 worldPos, float3 N, float3 V, float3 base
|
||||
shadow = TraceVisibilityBiased(worldPos, N, L, dist);
|
||||
|
||||
if (Lgt.pointRadiusPad <= 0.5)
|
||||
specularOut = ComputeSpecular(N, V, L, Lgt.color, Lgt.intensity, atten, shadow, baseAlbedo);
|
||||
specularOut = ComputeSpecular(N, V, L, Lgt.color, Lgt.intensity, atten, shadow, specularAlbedo);
|
||||
|
||||
return Lgt.color * (Lgt.intensity * atten * NdotLWrap * shadow);
|
||||
}
|
||||
|
||||
float3 PathTraceDirectRectLight(uint2 pixel, float3 worldPos, float3 N, float3 V, float3 baseAlbedo, Light Lgt, inout uint rng, out float3 specularOut)
|
||||
float3 PathTraceDirectRectLight(uint2 pixel, float3 worldPos, float3 N, float3 V, float3 baseAlbedo, float3 specularAlbedo, Light Lgt, inout uint rng, out float3 specularOut)
|
||||
{
|
||||
specularOut = 0.0;
|
||||
|
||||
@@ -3764,7 +3780,7 @@ float3 PathTraceDirectRectLight(uint2 pixel, float3 worldPos, float3 N, float3 V
|
||||
Lgt.intensity * faceTerm,
|
||||
1.0,
|
||||
shadow,
|
||||
baseAlbedo) * atten;
|
||||
specularAlbedo) * atten;
|
||||
}
|
||||
|
||||
diffuseAccum += clamp(Lgt.color * (Lgt.intensity * NdotL * faceTerm * atten * shadow), 0.0, 4.0);
|
||||
@@ -3961,21 +3977,22 @@ float3 EstimateShadowedBounceLight(uint2 hitPixel, float3 hitPos, float3 hitN, f
|
||||
{
|
||||
float3 spec = 0.0;
|
||||
float3 diffuse = 0.0;
|
||||
float3 hitSpecularAlbedo = LoadSceneSpecularAlbedo(hitPixel, hitAlbedo);
|
||||
|
||||
// Use the same visibility-capable direct-light samplers as the primary hit.
|
||||
// This supplies proper next-event estimation at secondary hits instead of the
|
||||
// old unoccluded light-list approximation.
|
||||
if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_POINT)
|
||||
{
|
||||
diffuse = PathTraceDirectPointLight(hitPixel, hitPos, hitN, hitV, hitAlbedo, Lgt, rng, spec);
|
||||
diffuse = PathTraceDirectPointLight(hitPixel, hitPos, hitN, hitV, hitAlbedo, hitSpecularAlbedo, Lgt, rng, spec);
|
||||
}
|
||||
else if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_SPOT)
|
||||
{
|
||||
diffuse = PathTraceDirectSpotLight(hitPos, hitN, hitV, hitAlbedo, Lgt, rng, spec);
|
||||
diffuse = PathTraceDirectSpotLight(hitPos, hitN, hitV, hitAlbedo, hitSpecularAlbedo, Lgt, rng, spec);
|
||||
}
|
||||
else if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_RECT)
|
||||
{
|
||||
diffuse = PathTraceDirectRectLight(hitPixel, hitPos, hitN, hitV, hitAlbedo, Lgt, rng, spec);
|
||||
diffuse = PathTraceDirectRectLight(hitPixel, hitPos, hitN, hitV, hitAlbedo, hitSpecularAlbedo, Lgt, rng, spec);
|
||||
}
|
||||
|
||||
return clamp(diffuse, 0.0, 12.0);
|
||||
@@ -4369,6 +4386,7 @@ float3 PathTraceDeterministicLighting(
|
||||
float3 N,
|
||||
float3 V,
|
||||
float3 baseAlbedo,
|
||||
float3 specularAlbedo,
|
||||
bool isSkeletal,
|
||||
float cavity,
|
||||
float ao,
|
||||
@@ -4411,15 +4429,15 @@ float3 PathTraceDeterministicLighting(
|
||||
|
||||
if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_POINT)
|
||||
{
|
||||
diffuse = PathTraceDirectPointLight(pixel, worldPos, N, V, baseAlbedo, Lgt, directRng, spec);
|
||||
diffuse = PathTraceDirectPointLight(pixel, worldPos, N, V, baseAlbedo, specularAlbedo, Lgt, directRng, spec);
|
||||
}
|
||||
else if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_SPOT)
|
||||
{
|
||||
diffuse = PathTraceDirectSpotLight(worldPos, N, V, baseAlbedo, Lgt, directRng, spec);
|
||||
diffuse = PathTraceDirectSpotLight(worldPos, N, V, baseAlbedo, specularAlbedo, Lgt, directRng, spec);
|
||||
}
|
||||
else if (Lgt.type == GL_RAYTRACING_LIGHT_TYPE_RECT)
|
||||
{
|
||||
diffuse = PathTraceDirectRectLight(pixel, worldPos, N, V, baseAlbedo, Lgt, directRng, spec);
|
||||
diffuse = PathTraceDirectRectLight(pixel, worldPos, N, V, baseAlbedo, specularAlbedo, Lgt, directRng, spec);
|
||||
}
|
||||
|
||||
lightingAccum += diffuse;
|
||||
@@ -4452,6 +4470,7 @@ void RayGen()
|
||||
}
|
||||
|
||||
float3 baseAlbedo = albedoSample.rgb;
|
||||
float3 specularAlbedo = LoadSceneSpecularAlbedo(pixel, baseAlbedo);
|
||||
float4 positionSample = gPositionTex.Load(int3(pixel, 0));
|
||||
float3 worldPos = positionSample.xyz;
|
||||
float4 normalSample = LoadSceneNormal(pixel);
|
||||
@@ -4502,6 +4521,7 @@ void RayGen()
|
||||
N,
|
||||
V,
|
||||
baseAlbedo,
|
||||
specularAlbedo,
|
||||
isSkeletal,
|
||||
cavity,
|
||||
ao,
|
||||
@@ -5780,6 +5800,30 @@ static void glRaytracingLightingCreatePerPassDescriptors(
|
||||
g_glRaytracingCmd.device->CreateShaderResourceView(g_glRaytracingLighting.emissiveTexture, &emissiveSrv,
|
||||
glRaytracingOffsetCpu(base, g_glRaytracingLighting.descriptorStride, GLR_DESC_EMISSIVE_SRV));
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC specularSrv = {};
|
||||
specularSrv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
specularSrv.Texture2D.MipLevels = 1;
|
||||
ID3D12Resource* specularResource = g_glRaytracingLighting.specularTexture;
|
||||
if (specularResource)
|
||||
{
|
||||
specularSrv.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
specularSrv.Format = g_glRaytracingLighting.specularFormat;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bind a harmless fallback descriptor when the shim has not provided a
|
||||
// specular G-buffer. The shader sees alpha zero and uses the legacy fallback.
|
||||
specularResource = pass->albedoTexture;
|
||||
specularSrv.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2,
|
||||
D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0);
|
||||
specularSrv.Format = pass->albedoFormat;
|
||||
}
|
||||
g_glRaytracingCmd.device->CreateShaderResourceView(specularResource, &specularSrv,
|
||||
glRaytracingOffsetCpu(base, g_glRaytracingLighting.descriptorStride, GLR_DESC_SPECULAR_SRV));
|
||||
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC rayOutputUav = {};
|
||||
rayOutputUav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
|
||||
rayOutputUav.Format = GL_RAYTRACING_DENOISE_FORMAT;
|
||||
@@ -6428,6 +6472,16 @@ void glRaytracingLightingSetEmissiveInput(ID3D12Resource* texture, DXGI_FORMAT f
|
||||
: format;
|
||||
}
|
||||
|
||||
void glRaytracingLightingSetSpecularInput(ID3D12Resource* texture, DXGI_FORMAT format)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
||||
|
||||
g_glRaytracingLighting.specularTexture = texture;
|
||||
g_glRaytracingLighting.specularFormat = (format == DXGI_FORMAT_UNKNOWN)
|
||||
? DXGI_FORMAT_R8G8B8A8_UNORM
|
||||
: format;
|
||||
}
|
||||
|
||||
bool glRaytracingLightingExecuteForScene(const glRaytracingLightingPassDesc_t* pass, glRaytracingSceneHandle_t worldHandle)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
||||
|
||||
Reference in New Issue
Block a user