mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
IES profile support and fixed numerous editor crashes.
This commit is contained in:
@@ -2469,9 +2469,12 @@ struct glRaytracingMeshMetadata_t
|
||||
float averageColor[4];
|
||||
};
|
||||
|
||||
static const uint32_t GL_RAYTRACING_MAX_IES_TEXTURES = 8;
|
||||
|
||||
struct glRaytracingLightingState_t
|
||||
{
|
||||
std::vector<glRaytracingLight_t> cpuLights;
|
||||
std::vector<glRaytracingLight_t> uploadLights;
|
||||
glRaytracingLightingConstants_t constants;
|
||||
|
||||
ComPtr<ID3D12DescriptorHeap> descriptorHeap;
|
||||
@@ -2522,6 +2525,9 @@ struct glRaytracingLightingState_t
|
||||
DXGI_FORMAT emissiveFormat;
|
||||
ID3D12Resource* specularTexture;
|
||||
DXGI_FORMAT specularFormat;
|
||||
uint32_t iesTextureIds[GL_RAYTRACING_MAX_IES_TEXTURES];
|
||||
ID3D12Resource* iesTextures[GL_RAYTRACING_MAX_IES_TEXTURES];
|
||||
DXGI_FORMAT iesFormats[GL_RAYTRACING_MAX_IES_TEXTURES];
|
||||
bool uploadToCurrentFrameResource;
|
||||
bool initialized;
|
||||
|
||||
@@ -2553,6 +2559,12 @@ struct glRaytracingLightingState_t
|
||||
emissiveFormat = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
specularTexture = nullptr;
|
||||
specularFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
for (uint32_t i = 0; i < GL_RAYTRACING_MAX_IES_TEXTURES; ++i)
|
||||
{
|
||||
iesTextureIds[i] = 0;
|
||||
iesTextures[i] = nullptr;
|
||||
iesFormats[i] = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
}
|
||||
uploadToCurrentFrameResource = false;
|
||||
initialized = false;
|
||||
}
|
||||
@@ -2577,14 +2589,15 @@ enum glRaytracingLightingDescriptorIndex_t
|
||||
GLR_DESC_EMISSIVE_SRV = 11,
|
||||
GLR_DESC_SPECULAR_SRV = 12,
|
||||
GLR_DESC_MESH_METADATA_SRV = 13,
|
||||
GLR_DESC_PATHTRACE_UAV = 14,
|
||||
GLR_DESC_DENOISE_A_UAV = 15,
|
||||
GLR_DESC_DENOISE_B_UAV = 16,
|
||||
GLR_DESC_OUTPUT_UAV = 17,
|
||||
GLR_DESC_TEMPORAL_UAV = 18,
|
||||
GLR_DESC_HISTORY_UAV = 19,
|
||||
GLR_DESC_COUNT = 20,
|
||||
GLR_DESC_SRV_COUNT = 14,
|
||||
GLR_DESC_IES_TEXTURES_SRV = 14,
|
||||
GLR_DESC_PATHTRACE_UAV = GLR_DESC_IES_TEXTURES_SRV + GL_RAYTRACING_MAX_IES_TEXTURES,
|
||||
GLR_DESC_DENOISE_A_UAV = GLR_DESC_PATHTRACE_UAV + 1,
|
||||
GLR_DESC_DENOISE_B_UAV = GLR_DESC_PATHTRACE_UAV + 2,
|
||||
GLR_DESC_OUTPUT_UAV = GLR_DESC_PATHTRACE_UAV + 3,
|
||||
GLR_DESC_TEMPORAL_UAV = GLR_DESC_PATHTRACE_UAV + 4,
|
||||
GLR_DESC_HISTORY_UAV = GLR_DESC_PATHTRACE_UAV + 5,
|
||||
GLR_DESC_COUNT = GLR_DESC_PATHTRACE_UAV + 6,
|
||||
GLR_DESC_SRV_COUNT = 14 + GL_RAYTRACING_MAX_IES_TEXTURES,
|
||||
GLR_DESC_UAV_COUNT = 6
|
||||
};
|
||||
|
||||
@@ -2631,6 +2644,10 @@ struct Light
|
||||
// as the influence range for rect lights, and as the far clip distance for spot lights.
|
||||
float3 pointRadius;
|
||||
float pointRadiusPad; // non-zero disables specular for this light
|
||||
|
||||
uint iesTextureIndex; // 0 = none, 1..8 = gIesTextures index + 1
|
||||
float iesStrength;
|
||||
float2 iesPad;
|
||||
};
|
||||
|
||||
struct MeshMetadata
|
||||
@@ -2686,6 +2703,7 @@ RaytracingAccelerationStructure gSceneBVH : register(t5);
|
||||
Texture2D<float4> gEmissiveTex : register(t11);
|
||||
Texture2D<float4> gSpecularTex : register(t12);
|
||||
StructuredBuffer<MeshMetadata> gMeshMetadata : register(t13);
|
||||
Texture2D<float4> gIesTextures[8] : register(t14);
|
||||
RWTexture2D<float4> gOutputTex : register(u0);
|
||||
|
||||
static const uint GL_RAYTRACING_LIGHT_TYPE_POINT = 0;
|
||||
@@ -3143,6 +3161,60 @@ float Doom3ProjectionTexture2D(float2 centeredCoord)
|
||||
|
||||
return Doom3QuadraticCentered(centeredCoord.x) * Doom3QuadraticCentered(centeredCoord.y);
|
||||
}
|
||||
|
||||
int WrapIESHorizontalCoord(int x)
|
||||
{
|
||||
x = x % 512;
|
||||
return (x < 0) ? (x + 512) : x;
|
||||
}
|
||||
|
||||
float SampleIESTexture(Light Lgt, float3 lightToSurface)
|
||||
{
|
||||
if (Lgt.iesTextureIndex == 0u || Lgt.iesStrength <= 0.0)
|
||||
return 1.0;
|
||||
|
||||
float3 dir = Doom3SafeNormalizeOr(lightToSurface, Doom3SafeNormalizeOr(Lgt.normal, float3(0.0, 0.0, 1.0)));
|
||||
float3 axisW = Doom3SafeNormalizeOr(Lgt.normal, float3(0.0, 0.0, 1.0));
|
||||
float3 axisU = Doom3SafeNormalizeOr(Lgt.axisU, float3(1.0, 0.0, 0.0));
|
||||
float3 axisV = Doom3SafeNormalizeOr(Lgt.axisV, float3(0.0, 1.0, 0.0));
|
||||
|
||||
float localX = dot(dir, axisU);
|
||||
float localY = dot(dir, axisV);
|
||||
float localZ = dot(dir, axisW);
|
||||
|
||||
float horizontal = atan2(localY, localX) * (0.15915494309189535) + 0.5;
|
||||
float vertical = acos(clamp(localZ, -1.0, 1.0)) * (0.3183098861837907);
|
||||
|
||||
uint texIndex = min(Lgt.iesTextureIndex - 1u, 7u);
|
||||
float u = frac(horizontal) * 512.0 - 0.5;
|
||||
float v = saturate(vertical) * 256.0 - 0.5;
|
||||
int x0 = (int)floor(u);
|
||||
int y0 = (int)floor(v);
|
||||
float tx = frac(u);
|
||||
float ty = frac(v);
|
||||
int x1 = x0 + 1;
|
||||
int y1 = y0 + 1;
|
||||
|
||||
x0 = WrapIESHorizontalCoord(x0);
|
||||
x1 = WrapIESHorizontalCoord(x1);
|
||||
y0 = clamp(y0, 0, 255);
|
||||
y1 = clamp(y1, 0, 255);
|
||||
|
||||
float p00 = gIesTextures[texIndex].Load(int3(x0, y0, 0)).r;
|
||||
float p10 = gIesTextures[texIndex].Load(int3(x1, y0, 0)).r;
|
||||
float p01 = gIesTextures[texIndex].Load(int3(x0, y1, 0)).r;
|
||||
float p11 = gIesTextures[texIndex].Load(int3(x1, y1, 0)).r;
|
||||
float profile = lerp(lerp(p00, p10, tx), lerp(p01, p11, tx), ty);
|
||||
return lerp(1.0, profile, saturate(Lgt.iesStrength));
|
||||
}
|
||||
|
||||
float ApplyIESProfile(float attenuation, Light Lgt, float3 lightToSurface)
|
||||
{
|
||||
if (attenuation <= 0.0 || Lgt.iesTextureIndex == 0u || Lgt.iesStrength <= 0.0)
|
||||
return attenuation;
|
||||
|
||||
return attenuation * SampleIESTexture(Lgt, lightToSurface);
|
||||
}
|
||||
)"
|
||||
R"(
|
||||
float Doom3ProjectedDepthFalloff(float depth, float nearClip, float farClip)
|
||||
@@ -3192,6 +3264,15 @@ float ComputeSpotLightAttenuation(float3 worldPos, Light Lgt)
|
||||
|
||||
float depth = dot(lightToSurface, spotDir);
|
||||
|
||||
if (Lgt.iesTextureIndex != 0u && Lgt.iesStrength > 0.0)
|
||||
{
|
||||
if (depth <= 1e-4 || depth >= farClip)
|
||||
return 0.0;
|
||||
|
||||
float t = saturate(depth / max(farClip, 1e-4));
|
||||
return 1.0 - smoothstep(0.985, 1.0, t);
|
||||
}
|
||||
|
||||
if (depth <= nearClip || depth >= farClip)
|
||||
return 0.0;
|
||||
|
||||
@@ -4023,7 +4104,7 @@ float3 PathTraceDirectPointLight(uint2 pixel, float3 worldPos, float3 N, float3
|
||||
float3 tangent, bitangent;
|
||||
BuildOrthonormalBasis(centerDir, tangent, bitangent);
|
||||
|
||||
float atten = ComputePointLightAttenuation(worldPos, Lgt);
|
||||
float atten = ApplyIESProfile(ComputePointLightAttenuation(worldPos, Lgt), Lgt, worldPos - Lgt.position);
|
||||
if (atten <= 0.0)
|
||||
return 0.0;
|
||||
|
||||
@@ -4081,7 +4162,7 @@ float3 PathTraceDirectSpotLight(float3 worldPos, float3 N, float3 V, float3 base
|
||||
return 0.0;
|
||||
|
||||
float3 L = toLight / dist;
|
||||
float atten = ComputeSpotLightAttenuation(worldPos, Lgt);
|
||||
float atten = ApplyIESProfile(ComputeSpotLightAttenuation(worldPos, Lgt), Lgt, worldPos - Lgt.position);
|
||||
|
||||
float diffuseNoL = ComputeDiffuseLightingTerm(N, L);
|
||||
|
||||
@@ -5264,7 +5345,7 @@ void RayGen()
|
||||
reflectionRng);
|
||||
|
||||
float3 albedo = baseAlbedo * cavity;
|
||||
float3 finalColor = (albedo * (lightingAccum + float3(0.08, 0.08, 0.08))) + specularAccum + reflectedSpecular;
|
||||
float3 finalColor = (albedo * (lightingAccum)) + specularAccum + reflectedSpecular;
|
||||
|
||||
if (gMaxBounces > 1u)
|
||||
{
|
||||
@@ -6073,16 +6154,72 @@ static void glRaytracingLightingUpdateLights(void)
|
||||
if (g_glRaytracingLighting.cpuLights.empty())
|
||||
return;
|
||||
|
||||
const size_t bytes = g_glRaytracingLighting.cpuLights.size() * sizeof(glRaytracingLight_t);
|
||||
std::vector<glRaytracingLight_t>& uploadLights = g_glRaytracingLighting.uploadLights;
|
||||
uploadLights = g_glRaytracingLighting.cpuLights;
|
||||
|
||||
for (size_t i = 0; i < uploadLights.size(); ++i)
|
||||
{
|
||||
glRaytracingLight_t& light = uploadLights[i];
|
||||
const uint32_t textureId = light.iesTextureId;
|
||||
if (textureId == 0 || light.iesStrength <= 0.0f)
|
||||
{
|
||||
light.iesTextureId = 0;
|
||||
light.iesStrength = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t slot = GL_RAYTRACING_MAX_IES_TEXTURES;
|
||||
for (uint32_t j = 0; j < GL_RAYTRACING_MAX_IES_TEXTURES; ++j)
|
||||
{
|
||||
if (g_glRaytracingLighting.iesTextureIds[j] == textureId)
|
||||
{
|
||||
slot = j;
|
||||
break;
|
||||
}
|
||||
if (g_glRaytracingLighting.iesTextureIds[j] == 0 && slot == GL_RAYTRACING_MAX_IES_TEXTURES)
|
||||
{
|
||||
slot = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == GL_RAYTRACING_MAX_IES_TEXTURES)
|
||||
{
|
||||
light.iesTextureId = 0;
|
||||
light.iesStrength = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_glRaytracingLighting.iesTextureIds[slot] == 0)
|
||||
{
|
||||
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
UINT width = 0;
|
||||
UINT height = 0;
|
||||
ID3D12Resource* resource = QD3D12_GetTextureResource((GLuint)textureId, &format, &width, &height, g_glRaytracingCmd.cmdList.Get());
|
||||
if (!resource || width == 0 || height == 0)
|
||||
{
|
||||
light.iesTextureId = 0;
|
||||
light.iesStrength = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
g_glRaytracingLighting.iesTextureIds[slot] = textureId;
|
||||
g_glRaytracingLighting.iesTextures[slot] = resource;
|
||||
g_glRaytracingLighting.iesFormats[slot] = format;
|
||||
}
|
||||
|
||||
light.iesTextureId = slot + 1;
|
||||
}
|
||||
|
||||
const size_t bytes = uploadLights.size() * sizeof(glRaytracingLight_t);
|
||||
if (g_glRaytracingLighting.lightBufferMapped)
|
||||
{
|
||||
memcpy(g_glRaytracingLighting.lightBufferMapped, g_glRaytracingLighting.cpuLights.data(), bytes);
|
||||
memcpy(g_glRaytracingLighting.lightBufferMapped, uploadLights.data(), bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
glRaytracingMapCopy(
|
||||
g_glRaytracingLighting.lightBuffer.resource.Get(),
|
||||
g_glRaytracingLighting.cpuLights.data(),
|
||||
uploadLights.data(),
|
||||
bytes);
|
||||
}
|
||||
|
||||
@@ -6622,6 +6759,21 @@ static void glRaytracingLightingCreatePerPassDescriptors(
|
||||
g_glRaytracingCmd.device->CreateShaderResourceView(specularResource, &specularSrv,
|
||||
glRaytracingOffsetCpu(base, g_glRaytracingLighting.descriptorStride, GLR_DESC_SPECULAR_SRV));
|
||||
|
||||
for (uint32_t i = 0; i < GL_RAYTRACING_MAX_IES_TEXTURES; ++i)
|
||||
{
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC iesSrv = {};
|
||||
iesSrv.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
iesSrv.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||
iesSrv.Format = g_glRaytracingLighting.iesTextures[i]
|
||||
? g_glRaytracingLighting.iesFormats[i]
|
||||
: DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
iesSrv.Texture2D.MipLevels = 1;
|
||||
g_glRaytracingCmd.device->CreateShaderResourceView(
|
||||
g_glRaytracingLighting.iesTextures[i],
|
||||
&iesSrv,
|
||||
glRaytracingOffsetCpu(base, g_glRaytracingLighting.descriptorStride, GLR_DESC_IES_TEXTURES_SRV + i));
|
||||
}
|
||||
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC rayOutputUav = {};
|
||||
rayOutputUav.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
|
||||
rayOutputUav.Format = GL_RAYTRACING_DENOISE_FORMAT;
|
||||
|
||||
Reference in New Issue
Block a user