mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-19 12:14:35 +02:00
Added citybuilder and cloud pass.
This commit is contained in:
@@ -1582,7 +1582,8 @@ static int glRaytracingUploadMeshBuffers(glRaytracingMeshRecord_t* mesh);
|
||||
|
||||
static int glRaytracingBuildDirtyMeshesInternal(void)
|
||||
{
|
||||
std::vector<glRaytracingMeshRecord_t*> dirtyMeshes;
|
||||
static thread_local std::vector<glRaytracingMeshRecord_t*> dirtyMeshes;
|
||||
dirtyMeshes.clear();
|
||||
dirtyMeshes.reserve(g_glRaytracingScene.meshes.size());
|
||||
|
||||
for (size_t i = 0; i < g_glRaytracingScene.meshes.size(); ++i)
|
||||
@@ -1608,7 +1609,8 @@ static int glRaytracingBuildDirtyMeshesInternal(void)
|
||||
int newBlasIndex;
|
||||
};
|
||||
|
||||
std::vector<glRaytracingMeshBuildInfo_t> builds;
|
||||
static thread_local std::vector<glRaytracingMeshBuildInfo_t> builds;
|
||||
builds.clear();
|
||||
builds.resize(dirtyMeshes.size());
|
||||
|
||||
for (size_t i = 0; i < dirtyMeshes.size(); ++i)
|
||||
@@ -2570,6 +2572,11 @@ struct glRaytracingLightingConstants_t
|
||||
uint32_t secondaryCorrectionBudget;
|
||||
float secondaryLightCompensation;
|
||||
uint32_t historyReset;
|
||||
|
||||
uint32_t externalDenoiser;
|
||||
float giAmount;
|
||||
float worldGrimeAmount;
|
||||
uint32_t pad2;
|
||||
};
|
||||
|
||||
struct glRaytracingMeshMetadata_t
|
||||
@@ -2853,6 +2860,10 @@ cbuffer LightingCB : register(b0)
|
||||
uint gSecondaryCorrectionBudget;
|
||||
float gSecondaryLightCompensation;
|
||||
uint gHistoryReset;
|
||||
uint gExternalDenoiser;
|
||||
float gGiAmount;
|
||||
float gWorldGrimeAmount;
|
||||
uint gPadding2;
|
||||
};
|
||||
|
||||
StructuredBuffer<Light> gLights : register(t0);
|
||||
@@ -3338,6 +3349,53 @@ float Hash12(float2 p)
|
||||
return frac((p3.x + p3.y) * p3.z);
|
||||
}
|
||||
|
||||
float Hash13(float3 p)
|
||||
{
|
||||
p = frac(p * 0.1031);
|
||||
p += dot(p, p.yzx + 33.33);
|
||||
return frac((p.x + p.y) * p.z);
|
||||
}
|
||||
|
||||
float ValueNoise3D(float3 p)
|
||||
{
|
||||
float3 i = floor(p);
|
||||
float3 f = frac(p);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
float n000 = Hash13(i + float3(0, 0, 0));
|
||||
float n100 = Hash13(i + float3(1, 0, 0));
|
||||
float n010 = Hash13(i + float3(0, 1, 0));
|
||||
float n110 = Hash13(i + float3(1, 1, 0));
|
||||
float n001 = Hash13(i + float3(0, 0, 1));
|
||||
float n101 = Hash13(i + float3(1, 0, 1));
|
||||
float n011 = Hash13(i + float3(0, 1, 1));
|
||||
float n111 = Hash13(i + float3(1, 1, 1));
|
||||
|
||||
float nx00 = lerp(n000, n100, f.x);
|
||||
float nx10 = lerp(n010, n110, f.x);
|
||||
float nx01 = lerp(n001, n101, f.x);
|
||||
float nx11 = lerp(n011, n111, f.x);
|
||||
float nxy0 = lerp(nx00, nx10, f.y);
|
||||
float nxy1 = lerp(nx01, nx11, f.y);
|
||||
return lerp(nxy0, nxy1, f.z);
|
||||
}
|
||||
|
||||
void ApplyWorldGrime(float3 worldPos, float cavity, float ao, bool isSkeletal, inout float3 baseAlbedo, inout float3 specularAlbedo)
|
||||
{
|
||||
if (isSkeletal || gWorldGrimeAmount <= 0.0001)
|
||||
return;
|
||||
|
||||
float crevice = saturate((1.0 - cavity) * 1.35 + (1.0 - ao) * 0.55);
|
||||
float largeNoise = ValueNoise3D(worldPos * 0.025);
|
||||
float fineNoise = ValueNoise3D(worldPos * 0.11 + float3(17.0, 41.0, 9.0));
|
||||
float grimeMask = saturate(crevice * (0.65 + 0.55 * largeNoise) + fineNoise * 0.18);
|
||||
float amount = saturate(grimeMask * gWorldGrimeAmount);
|
||||
|
||||
float3 dirtTint = float3(0.36, 0.31, 0.24);
|
||||
baseAlbedo = lerp(baseAlbedo, baseAlbedo * dirtTint, amount);
|
||||
specularAlbedo *= lerp(1.0, 0.55, amount);
|
||||
}
|
||||
|
||||
float2 Hammersley2D(uint i, uint N, float rand)
|
||||
{
|
||||
float e1 = frac((float)i / (float)N + rand);
|
||||
@@ -4346,6 +4404,24 @@ uint InitSpatialRng(uint2 pixel, float3 worldPos, uint salt)
|
||||
return PcgHash(seed) | 1u;
|
||||
}
|
||||
|
||||
uint InitSurfaceStableRng(uint2 pixel, float3 worldPos, float3 normal, uint sampleIndex, uint frameIndex)
|
||||
{
|
||||
if (gExternalDenoiser == 0u)
|
||||
return InitRng(pixel, frameIndex, sampleIndex);
|
||||
|
||||
uint3 cell = (uint3)floor(abs(worldPos) * 16.0 + 0.5);
|
||||
uint3 ncell = (uint3)floor(saturate(normal * 0.5 + 0.5) * 255.0 + 0.5);
|
||||
uint seed =
|
||||
cell.x * 73856093u ^
|
||||
cell.y * 19349663u ^
|
||||
cell.z * 83492791u ^
|
||||
ncell.x * 1597334677u ^
|
||||
ncell.y * 3812015801u ^
|
||||
ncell.z * 2798796415u ^
|
||||
sampleIndex * 0x9E3779B9u;
|
||||
return PcgHash(seed) | 1u;
|
||||
}
|
||||
|
||||
float Rand(inout uint rng)
|
||||
{
|
||||
rng = PcgHash(rng);
|
||||
@@ -5587,7 +5663,8 @@ float2 GetStratifiedBounceXi(uint2 pixel, float3 worldPos, float3 pathNormal, ui
|
||||
{
|
||||
uint spp = max(gSamplesPerPixel, 1u);
|
||||
uint sequenceLength = max(spp * 64u, 64u);
|
||||
uint sequenceIndex = (sampleIndex + (gFrameIndex & 63u) * spp) % sequenceLength;
|
||||
uint rngFrameIndex = (gEnableDenoiser != 0u && gExternalDenoiser == 0u) ? gFrameIndex : 0u;
|
||||
uint sequenceIndex = (sampleIndex + (rngFrameIndex & 63u) * spp) % sequenceLength;
|
||||
|
||||
float rand = Hash12(
|
||||
(float2)pixel +
|
||||
@@ -6212,21 +6289,24 @@ void RayGen()
|
||||
|
||||
// All four of these are deterministic for this pixel. Compute them once,
|
||||
// then reuse them for every stochastic GI sample.
|
||||
float cavity = ComputeCavity(pixel, worldPos, N);
|
||||
const bool externalCharacterPixel = (gExternalDenoiser != 0u) && isSkeletal;
|
||||
float cavity = externalCharacterPixel ? 1.0 : ComputeCavity(pixel, worldPos, N);
|
||||
if (isSkeletal)
|
||||
cavity = lerp(cavity, 1.0, 0.65);
|
||||
float ao = ComputeAmbientOcclusion(worldPos, N, pixel, isSkeletal);
|
||||
float ao = externalCharacterPixel ? 1.0 : ComputeAmbientOcclusion(worldPos, N, pixel, isSkeletal);
|
||||
float skyVis = 0; //ComputeSkyVisibility(worldPos, N, pixel);
|
||||
float ambientSkyVis = 0; //TraceStraightUpToSky(worldPos, N);
|
||||
float microShadow = lerp(0.75, 1.0, cavity);
|
||||
ApplyWorldGrime(worldPos, cavity, ao, isSkeletal, baseAlbedo, specularAlbedo);
|
||||
|
||||
float3 reactiveFinalGather = 0.0;
|
||||
uint rngFrameIndex = (gEnableDenoiser != 0u && gExternalDenoiser == 0u) ? gFrameIndex : 0u;
|
||||
if (gMaxBounces > 1u)
|
||||
{
|
||||
// Evaluate this deterministic screen-space irradiance reuse once per
|
||||
// pixel, not once per SPP. That makes the GI more responsive without
|
||||
// multiplying the light-list work inside the stochastic sample loop.
|
||||
uint gatherRng = InitRng(pixel, gFrameIndex, 1337u);
|
||||
uint gatherRng = InitSurfaceStableRng(pixel, worldPos, N, 1337u, rngFrameIndex);
|
||||
reactiveFinalGather = EstimateReactiveScreenSpaceFinalGather(
|
||||
pixel,
|
||||
worldPos,
|
||||
@@ -6257,17 +6337,17 @@ void RayGen()
|
||||
// Only the indirect bounce path uses per-SPP randomness now. Direct lights,
|
||||
// AO, sky visibility, cavity, and final gather are deterministic and should
|
||||
// not be re-traced spp times.
|
||||
if (gMaxBounces > 1u)
|
||||
if (gMaxBounces > 1u && !externalCharacterPixel)
|
||||
{
|
||||
float3 indirectAccum = 0.0;
|
||||
|
||||
[loop]
|
||||
for (uint s = 0; s < spp; ++s)
|
||||
{
|
||||
// Frame-vary the GI path now that a temporal accumulator is present.
|
||||
// This lets the stochastic light subset, sky sample, and diffuse path
|
||||
// converge instead of staying locked to one noisy sample pattern.
|
||||
uint rng = InitRng(pixel, gFrameIndex, s);
|
||||
// Frame-vary only when the internal temporal accumulator is active.
|
||||
// External denoisers get a surface-stable raw GI pattern so texture
|
||||
// detail does not boil under reconstruction.
|
||||
uint rng = InitSurfaceStableRng(pixel, worldPos, N, s, rngFrameIndex);
|
||||
indirectAccum += EstimatePathTracedIndirectBounce(
|
||||
pixel,
|
||||
worldPos,
|
||||
@@ -6279,7 +6359,7 @@ void RayGen()
|
||||
}
|
||||
|
||||
float3 indirectLighting = indirectAccum / (float)spp;
|
||||
lightingAccum += ApplyPrimaryDiffusePost(indirectLighting, ao, microShadow, isSkeletal);
|
||||
lightingAccum += ApplyPrimaryDiffusePost(indirectLighting, ao, microShadow, isSkeletal) * gGiAmount;
|
||||
}
|
||||
|
||||
uint reflectionRng = InitRng(pixel, 0u, 0x5EECu);
|
||||
@@ -6301,11 +6381,10 @@ void RayGen()
|
||||
{
|
||||
// reactiveFinalGather is incoming indirect radiance. Apply the primary
|
||||
// diffuse albedo here, matching the regular lighting path.
|
||||
finalColor += baseAlbedo * reactiveFinalGather;
|
||||
finalColor += baseAlbedo * reactiveFinalGather * gGiAmount;
|
||||
}
|
||||
|
||||
float outputAo = isSkeletal ? lerp(ao, 1.0, 0.55) : ao;
|
||||
finalColor *= clamp(outputAo + 0.3, 0.0, 1.0);
|
||||
finalColor += subsurfaceAccum;
|
||||
|
||||
// Volumetric light scattering is radiance in the camera ray, not surface
|
||||
@@ -6321,7 +6400,7 @@ void RayGen()
|
||||
// the eventual swap-chain/backbuffer is LDR.
|
||||
finalColor += emissiveSurface + emissiveBloom;
|
||||
|
||||
gOutputTex[pixel] = float4(PreparePathTraceOutputColor(finalColor), primaryHitDistance);
|
||||
gOutputTex[pixel] = float4(PreparePathTraceOutputColor(finalColor) * outputAo, primaryHitDistance);
|
||||
}
|
||||
)";
|
||||
|
||||
@@ -6354,6 +6433,10 @@ cbuffer LightingCB : register(b0)
|
||||
uint gSecondaryCorrectionBudget;
|
||||
float gSecondaryLightCompensation;
|
||||
uint gHistoryReset;
|
||||
uint gExternalDenoiser;
|
||||
float gGiAmount;
|
||||
float gWorldGrimeAmount;
|
||||
uint gPadding2;
|
||||
};
|
||||
|
||||
Texture2D<float4> gAlbedoTex : register(t1);
|
||||
@@ -6640,6 +6723,10 @@ cbuffer LightingCB : register(b0)
|
||||
uint gSecondaryCorrectionBudget;
|
||||
float gSecondaryLightCompensation;
|
||||
uint gHistoryReset;
|
||||
uint gExternalDenoiser;
|
||||
float gGiAmount;
|
||||
float gWorldGrimeAmount;
|
||||
uint gPadding2;
|
||||
};
|
||||
|
||||
Texture2D<float4> gAlbedoTex : register(t1);
|
||||
@@ -8059,6 +8146,7 @@ static bool glRaytracingLightingExecuteInternal(
|
||||
g_glRaytracingLighting.constants.screenSize[2] = 1.0f / (float)pass->width;
|
||||
g_glRaytracingLighting.constants.screenSize[3] = 1.0f / (float)pass->height;
|
||||
g_glRaytracingLighting.constants.frameIndex = g_glRaytracingLighting.frameCounter;
|
||||
g_glRaytracingLighting.constants.externalDenoiser = g_glRaytracingLighting.externalDenoiser ? 1u : 0u;
|
||||
g_glRaytracingLighting.constants.lightCount =
|
||||
(uint32_t)glRaytracingClamp<size_t>(g_glRaytracingLighting.cpuLights.size(), 0, GL_RAYTRACING_MAX_LIGHTS);
|
||||
|
||||
@@ -8424,6 +8512,9 @@ bool glRaytracingLightingInit(void)
|
||||
g_glRaytracingLighting.constants.secondaryCorrectionBudget = 0;
|
||||
g_glRaytracingLighting.constants.secondaryLightCompensation = 0.62f;
|
||||
g_glRaytracingLighting.constants.historyReset = 1u;
|
||||
g_glRaytracingLighting.constants.externalDenoiser = 0u;
|
||||
g_glRaytracingLighting.constants.giAmount = 1.0f;
|
||||
g_glRaytracingLighting.constants.worldGrimeAmount = 0.35f;
|
||||
glRaytracingLightingResetDenoiseHistory();
|
||||
|
||||
glRaytracingLightingUpdateConstants();
|
||||
@@ -8653,6 +8744,30 @@ void glRaytracingLightingSetPathTracingOptions(uint32_t samplesPerPixel, uint32_
|
||||
glRaytracingLightingUpdateConstants();
|
||||
}
|
||||
|
||||
void glRaytracingLightingSetGIAmount(float amount)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
||||
|
||||
amount = glRaytracingClamp<float>(amount, 0.0f, 8.0f);
|
||||
if (g_glRaytracingLighting.constants.giAmount != amount)
|
||||
glRaytracingLightingResetDenoiseHistory();
|
||||
|
||||
g_glRaytracingLighting.constants.giAmount = amount;
|
||||
glRaytracingLightingUpdateConstants();
|
||||
}
|
||||
|
||||
void glRaytracingLightingSetWorldGrime(float amount)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
||||
|
||||
amount = glRaytracingClamp<float>(amount, 0.0f, 4.0f);
|
||||
if (g_glRaytracingLighting.constants.worldGrimeAmount != amount)
|
||||
glRaytracingLightingResetDenoiseHistory();
|
||||
|
||||
g_glRaytracingLighting.constants.worldGrimeAmount = amount;
|
||||
glRaytracingLightingUpdateConstants();
|
||||
}
|
||||
|
||||
void glRaytracingLightingSetSecondaryLightBudget(int budget, float compensation)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
||||
@@ -8717,6 +8832,8 @@ void glRaytracingLightingSetExternalDenoiser(int enabled)
|
||||
glRaytracingLightingResetDenoiseHistory();
|
||||
|
||||
g_glRaytracingLighting.externalDenoiser = newValue;
|
||||
g_glRaytracingLighting.constants.externalDenoiser = newValue ? 1u : 0u;
|
||||
glRaytracingLightingUpdateConstants();
|
||||
}
|
||||
|
||||
void glRaytracingLightingUseExternalDenoiser(int enabled)
|
||||
|
||||
Reference in New Issue
Block a user