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)
|
||||
|
||||
@@ -542,7 +542,7 @@ static const UINT QD3D12_UploadBufferSize = 128 * 1024 * 1024;
|
||||
static const UINT QD3D12_RequestedGBufferSampleCount = 1;
|
||||
static constexpr UINT QD3D12_PostSrvCount = 16;
|
||||
static constexpr UINT QD3D12_PostRootConstants = QD3D12_PostSrvCount;
|
||||
static constexpr UINT QD3D12_PostConstantDwords = 28;
|
||||
static constexpr UINT QD3D12_PostConstantDwords = 48;
|
||||
static constexpr UINT QD3D12_ToneMapTileDim = 64;
|
||||
static constexpr UINT QD3D12_MaxScreenSpaceDecals = 64;
|
||||
static constexpr UINT QD3D12_MaxScreenSpaceParticleLights = GL_RAYTRACING_MAX_LIGHTS;
|
||||
@@ -1798,6 +1798,7 @@ struct GLState
|
||||
ComPtr<ID3D12PipelineState> postScreenParticlePSO;
|
||||
ComPtr<ID3D12PipelineState> postScreenParticleAdditivePSO;
|
||||
ComPtr<ID3D12PipelineState> postScreenParticleEmissivePSO;
|
||||
ComPtr<ID3D12PipelineState> postSkyCloudsPSO;
|
||||
|
||||
ComPtr<ID3DBlob> vsMainBlob;
|
||||
ComPtr<ID3DBlob> hsMainBlob;
|
||||
@@ -1822,6 +1823,7 @@ struct GLState
|
||||
ComPtr<ID3DBlob> postPsScreenDecalBlob;
|
||||
ComPtr<ID3DBlob> postVsScreenParticleBlob;
|
||||
ComPtr<ID3DBlob> postPsScreenParticleBlob;
|
||||
ComPtr<ID3DBlob> postPsSkyCloudsBlob;
|
||||
|
||||
TextureResource whiteTexture;
|
||||
|
||||
@@ -4778,6 +4780,11 @@ cbuffer PostCB : register(b0)
|
||||
float4 gPostFogColor;
|
||||
float4 gPostFogCameraWorldPos;
|
||||
float4 gPostParticleParams;
|
||||
float4 gSkyCloudColorOpacity;
|
||||
float4 gSkyCloudForwardZMax;
|
||||
float4 gSkyCloudRightTanX;
|
||||
float4 gSkyCloudUpTanY;
|
||||
float4 gSkyCloudParams;
|
||||
};
|
||||
|
||||
#define gPostSharpness gPostParams0.x
|
||||
@@ -4799,6 +4806,20 @@ cbuffer PostCB : register(b0)
|
||||
#define gScreenParticleEmissiveScale gPostParticleParams.x
|
||||
#define gScreenParticleOutputMode gPostParticleParams.y
|
||||
#define gScreenParticleDepthScale gPostParticleParams.zw
|
||||
#define gSkyCloudColor gSkyCloudColorOpacity.rgb
|
||||
#define gSkyCloudOpacity gSkyCloudColorOpacity.a
|
||||
#define gSkyCloudViewOrigin gPostFogCameraWorldPos.xyz
|
||||
#define gSkyCloudZMin gPostFogCameraWorldPos.w
|
||||
#define gSkyCloudForward gSkyCloudForwardZMax.xyz
|
||||
#define gSkyCloudZMax gSkyCloudForwardZMax.w
|
||||
#define gSkyCloudRight gSkyCloudRightTanX.xyz
|
||||
#define gSkyCloudTanX gSkyCloudRightTanX.w
|
||||
#define gSkyCloudUp gSkyCloudUpTanY.xyz
|
||||
#define gSkyCloudTanY gSkyCloudUpTanY.w
|
||||
#define gSkyCloudScale gSkyCloudParams.x
|
||||
#define gSkyCloudCoverage gSkyCloudParams.y
|
||||
#define gSkyCloudDensity gSkyCloudParams.z
|
||||
#define gSkyCloudSeed gSkyCloudParams.w
|
||||
#define QD3D12_TONEMAP_TILE_DIM 64u
|
||||
|
||||
static const uint GL_RAYTRACING_LIGHT_TYPE_POINT = 0u;
|
||||
@@ -5134,12 +5155,124 @@ float4 PSCopy(VSOut i) : SV_Target0
|
||||
{
|
||||
return QD3D12_ApplyPostFog(gTex0.Sample(gSamp0, i.uv), i.uv);
|
||||
}
|
||||
|
||||
float QD3D12_SkyCloudFade(float t)
|
||||
{
|
||||
t = saturate(t);
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
float QD3D12_SkyCloudHash(int3 p)
|
||||
{
|
||||
uint h = (uint)p.x * 374761393u + (uint)p.y * 668265263u + (uint)p.z * 2147483647u;
|
||||
h = (h ^ (h >> 13)) * 1274126177u;
|
||||
h ^= h >> 16;
|
||||
return (float)(h & 0xffffu) * (1.0 / 65535.0);
|
||||
}
|
||||
|
||||
float QD3D12_SkyCloudNoise(float3 p)
|
||||
{
|
||||
int3 ip = int3(floor(p));
|
||||
float3 f = float3(
|
||||
QD3D12_SkyCloudFade(p.x - (float)ip.x),
|
||||
QD3D12_SkyCloudFade(p.y - (float)ip.y),
|
||||
QD3D12_SkyCloudFade(p.z - (float)ip.z));
|
||||
|
||||
float x00 = lerp(QD3D12_SkyCloudHash(ip + int3(0, 0, 0)), QD3D12_SkyCloudHash(ip + int3(1, 0, 0)), f.x);
|
||||
float x10 = lerp(QD3D12_SkyCloudHash(ip + int3(0, 1, 0)), QD3D12_SkyCloudHash(ip + int3(1, 1, 0)), f.x);
|
||||
float x01 = lerp(QD3D12_SkyCloudHash(ip + int3(0, 0, 1)), QD3D12_SkyCloudHash(ip + int3(1, 0, 1)), f.x);
|
||||
float x11 = lerp(QD3D12_SkyCloudHash(ip + int3(0, 1, 1)), QD3D12_SkyCloudHash(ip + int3(1, 1, 1)), f.x);
|
||||
|
||||
return lerp(lerp(x00, x10, f.y), lerp(x01, x11, f.y), f.z);
|
||||
}
|
||||
|
||||
float QD3D12_SkyCloudFBm(float3 p)
|
||||
{
|
||||
float sum = 0.0;
|
||||
float amp = 0.56;
|
||||
float norm = 0.0;
|
||||
|
||||
[unroll]
|
||||
for (int octave = 0; octave < 5; ++octave)
|
||||
{
|
||||
sum += QD3D12_SkyCloudNoise(p) * amp;
|
||||
norm += amp;
|
||||
p *= 2.06;
|
||||
amp *= 0.52;
|
||||
}
|
||||
|
||||
return sum / max(norm, 1.0e-4);
|
||||
}
|
||||
|
||||
float QD3D12_SkyCloudBillow(float3 p)
|
||||
{
|
||||
return 1.0 - abs(QD3D12_SkyCloudFBm(p) * 2.0 - 1.0);
|
||||
}
|
||||
)HLSL"
|
||||
R"HLSL(
|
||||
float4 PSSkyClouds(VSOut i) : SV_Target0
|
||||
{
|
||||
float2 ndc = float2(i.uv.x * 2.0 - 1.0, 1.0 - i.uv.y * 2.0);
|
||||
float3 ray = normalize(gSkyCloudForward + gSkyCloudRight * (ndc.x * gSkyCloudTanX) + gSkyCloudUp * (ndc.y * gSkyCloudTanY));
|
||||
float horizonMask = smoothstep(-0.015, 0.18, ray.z);
|
||||
if (horizonMask <= 0.0001)
|
||||
discard;
|
||||
|
||||
float zMin = gSkyCloudZMin;
|
||||
float zMax = max(gSkyCloudZMax, zMin + 64.0);
|
||||
float slabDepth = zMax - zMin;
|
||||
float cloudZ = zMin + slabDepth * 0.55;
|
||||
float rayZ = max(ray.z, 0.10);
|
||||
float baseT = (cloudZ - gSkyCloudViewOrigin.z) / rayZ;
|
||||
if (baseT <= 0.0)
|
||||
discard;
|
||||
|
||||
float2 baseWorld = (gSkyCloudViewOrigin + ray * baseT).xy;
|
||||
float alpha = 0.0;
|
||||
float shade = 0.0;
|
||||
float scale = max(gSkyCloudScale, 0.00001);
|
||||
float seed = gSkyCloudSeed;
|
||||
float3 seedVec = float3(11.7 + seed * 0.00011, 3.4 - seed * 0.00007, 9.1);
|
||||
|
||||
[unroll]
|
||||
for (int layer = 0; layer < 7; ++layer)
|
||||
{
|
||||
float l = ((float)layer + 0.5) * (1.0 / 7.0);
|
||||
float heightFade = smoothstep(0.02, 0.34, l) * (1.0 - smoothstep(0.70, 1.0, l));
|
||||
float2 layerDrift = float2(0.62, -0.28) * (seed * 0.00003 + l * 310.0);
|
||||
float2 parallax = ray.xy * ((l - 0.5) * slabDepth * 0.16);
|
||||
float2 cloudXY = (baseWorld + parallax + layerDrift) * scale;
|
||||
float3 p = float3(cloudXY, seed * 0.00009 + l * 2.7);
|
||||
|
||||
float broad = QD3D12_SkyCloudFBm(p * 0.48 + seedVec);
|
||||
float warpA = QD3D12_SkyCloudFBm(p * 0.82 + broad * 0.85 + seedVec.yzx);
|
||||
float billowA = smoothstep(0.18, 0.96, QD3D12_SkyCloudBillow(p * 1.35 + warpA * 1.20));
|
||||
float billowB = smoothstep(0.42, 0.96, QD3D12_SkyCloudBillow(p * 2.05 + seedVec.zxy));
|
||||
|
||||
float anvil = smoothstep(0.20, 0.76, broad);
|
||||
float shape = anvil * (billowA * 0.88 + billowB * 0.12);
|
||||
shape = smoothstep(saturate(gSkyCloudCoverage) * 0.66, 0.94, shape);
|
||||
|
||||
float density = shape * heightFade * max(gSkyCloudDensity, 0.0);
|
||||
alpha += (1.0 - alpha) * density * 0.36;
|
||||
shade += density * (0.66 + l * 0.22 + broad * 0.12);
|
||||
}
|
||||
|
||||
alpha = saturate(alpha * saturate(gSkyCloudOpacity) * horizonMask);
|
||||
if (alpha <= 0.001)
|
||||
discard;
|
||||
|
||||
float skyLum = dot(saturate(gSkyCloudColor), float3(0.299, 0.587, 0.114));
|
||||
float3 brightCloud = lerp(saturate(gSkyCloudColor * 1.28), float3(1.0, 0.985, 0.94), 0.76);
|
||||
brightCloud *= 0.92 + saturate(shade) * 0.16 + saturate(skyLum) * 0.16;
|
||||
return float4(saturate(brightCloud), alpha);
|
||||
}
|
||||
)HLSL"
|
||||
R"HLSL(
|
||||
float4 PSSharpen(VSOut i) : SV_Target0
|
||||
{
|
||||
float4 center = gTex0.Sample(gSamp0, i.uv);
|
||||
float amount = saturate(gPostSharpness);
|
||||
float amount = saturate(gPostSharpness) * 2.35;
|
||||
if (amount <= 0.0001)
|
||||
return center;
|
||||
|
||||
@@ -5151,11 +5284,23 @@ float4 PSSharpen(VSOut i) : SV_Target0
|
||||
float3 s = gTex0.Sample(gSamp0, saturate(i.uv + float2(0.0, texel.y))).rgb;
|
||||
float3 e = gTex0.Sample(gSamp0, saturate(i.uv + float2( texel.x, 0.0))).rgb;
|
||||
float3 w = gTex0.Sample(gSamp0, saturate(i.uv + float2(-texel.x, 0.0))).rgb;
|
||||
float3 blur = (n + s + e + w) * 0.25;
|
||||
float3 ne = gTex0.Sample(gSamp0, saturate(i.uv + float2( texel.x, -texel.y))).rgb;
|
||||
float3 nw = gTex0.Sample(gSamp0, saturate(i.uv + float2(-texel.x, -texel.y))).rgb;
|
||||
float3 se = gTex0.Sample(gSamp0, saturate(i.uv + float2( texel.x, texel.y))).rgb;
|
||||
float3 sw = gTex0.Sample(gSamp0, saturate(i.uv + float2(-texel.x, texel.y))).rgb;
|
||||
float3 blur = (n + s + e + w) * 0.18 + (ne + nw + se + sw) * 0.07;
|
||||
|
||||
float3 albedoC = gScreenDecalNormal.Sample(gSamp0, i.uv).rgb;
|
||||
float3 albedoN = gScreenDecalNormal.Sample(gSamp0, saturate(i.uv + float2(0.0, -texel.y))).rgb;
|
||||
float3 albedoS = gScreenDecalNormal.Sample(gSamp0, saturate(i.uv + float2(0.0, texel.y))).rgb;
|
||||
float3 albedoE = gScreenDecalNormal.Sample(gSamp0, saturate(i.uv + float2( texel.x, 0.0))).rgb;
|
||||
float3 albedoW = gScreenDecalNormal.Sample(gSamp0, saturate(i.uv + float2(-texel.x, 0.0))).rgb;
|
||||
float3 albedoBlur = (albedoN + albedoS + albedoE + albedoW) * 0.25;
|
||||
float3 albedoDetail = clamp(albedoC - albedoBlur, -0.18, 0.18);
|
||||
|
||||
// Sharpen strictly after temporal reconstruction. Keep it conservative so
|
||||
// the TAA resolve is not undone by ringing on high-contrast UI/geometry edges.
|
||||
float3 sharp = center.rgb + (center.rgb - blur) * amount;
|
||||
float3 sharp = center.rgb + (center.rgb - blur) * amount + albedoDetail * (amount * 0.38);
|
||||
return QD3D12_ApplyPostFog(float4(saturate(sharp), center.a), i.uv);
|
||||
}
|
||||
|
||||
@@ -5226,7 +5371,7 @@ float4 PSToneMapFinalMax(VSOut i) : SV_Target0
|
||||
R"HLSL(
|
||||
float3 QD3D12_PostSharpenHDR(float2 uv, float3 center)
|
||||
{
|
||||
float amount = saturate(gPostSharpness);
|
||||
float amount = saturate(gPostSharpness) * 2.35;
|
||||
if (amount <= 0.0001)
|
||||
return center;
|
||||
|
||||
@@ -5238,11 +5383,23 @@ float3 QD3D12_PostSharpenHDR(float2 uv, float3 center)
|
||||
float3 s = max(gTex0.Sample(gSamp0, saturate(uv + float2(0.0, texel.y))).rgb, 0.0);
|
||||
float3 e = max(gTex0.Sample(gSamp0, saturate(uv + float2( texel.x, 0.0))).rgb, 0.0);
|
||||
float3 w = max(gTex0.Sample(gSamp0, saturate(uv + float2(-texel.x, 0.0))).rgb, 0.0);
|
||||
float3 blur = (n + s + e + w) * 0.25;
|
||||
float3 ne = max(gTex0.Sample(gSamp0, saturate(uv + float2( texel.x, -texel.y))).rgb, 0.0);
|
||||
float3 nw = max(gTex0.Sample(gSamp0, saturate(uv + float2(-texel.x, -texel.y))).rgb, 0.0);
|
||||
float3 se = max(gTex0.Sample(gSamp0, saturate(uv + float2( texel.x, texel.y))).rgb, 0.0);
|
||||
float3 sw = max(gTex0.Sample(gSamp0, saturate(uv + float2(-texel.x, texel.y))).rgb, 0.0);
|
||||
float3 blur = (n + s + e + w) * 0.18 + (ne + nw + se + sw) * 0.07;
|
||||
|
||||
float3 albedoC = max(gScreenDecalNormal.Sample(gSamp0, uv).rgb, 0.0);
|
||||
float3 albedoN = max(gScreenDecalNormal.Sample(gSamp0, saturate(uv + float2(0.0, -texel.y))).rgb, 0.0);
|
||||
float3 albedoS = max(gScreenDecalNormal.Sample(gSamp0, saturate(uv + float2(0.0, texel.y))).rgb, 0.0);
|
||||
float3 albedoE = max(gScreenDecalNormal.Sample(gSamp0, saturate(uv + float2( texel.x, 0.0))).rgb, 0.0);
|
||||
float3 albedoW = max(gScreenDecalNormal.Sample(gSamp0, saturate(uv + float2(-texel.x, 0.0))).rgb, 0.0);
|
||||
float3 albedoBlur = (albedoN + albedoS + albedoE + albedoW) * 0.25;
|
||||
float3 albedoDetail = clamp(albedoC - albedoBlur, -0.18, 0.18);
|
||||
|
||||
// Sharpen before tone mapping so highlights keep their shoulder instead of
|
||||
// ringing after they have already been compressed to display range.
|
||||
return min(max(center + (center - blur) * amount, 0.0), 65504.0);
|
||||
return min(max(center + (center - blur) * amount + albedoDetail * (amount * 0.38), 0.0), 65504.0);
|
||||
}
|
||||
|
||||
float3 QD3D12_ExtendedReinhard(float3 hdr, float whitePoint)
|
||||
@@ -8531,7 +8688,8 @@ static void QD3D12_SetPostConstants(
|
||||
float screenParticleEmissiveScale = 0.0f,
|
||||
float screenParticleOutputMode = 0.0f,
|
||||
float screenParticleDepthScaleX = 1.0f,
|
||||
float screenParticleDepthScaleY = 1.0f)
|
||||
float screenParticleDepthScaleY = 1.0f,
|
||||
const glSkyClouds_t* skyClouds = nullptr)
|
||||
{
|
||||
if (!cl)
|
||||
return;
|
||||
@@ -8574,12 +8732,48 @@ static void QD3D12_SetPostConstants(
|
||||
constants[25] = screenParticleOutputMode;
|
||||
constants[26] = screenParticleDepthScaleX;
|
||||
constants[27] = screenParticleDepthScaleY;
|
||||
if (skyClouds)
|
||||
{
|
||||
constants[20] = skyClouds->viewOrigin[0];
|
||||
constants[21] = skyClouds->viewOrigin[1];
|
||||
constants[22] = skyClouds->viewOrigin[2];
|
||||
constants[23] = skyClouds->zMin;
|
||||
constants[28] = skyClouds->skyColor[0];
|
||||
constants[29] = skyClouds->skyColor[1];
|
||||
constants[30] = skyClouds->skyColor[2];
|
||||
constants[31] = skyClouds->opacity;
|
||||
constants[32] = skyClouds->viewForward[0];
|
||||
constants[33] = skyClouds->viewForward[1];
|
||||
constants[34] = skyClouds->viewForward[2];
|
||||
constants[35] = skyClouds->zMax;
|
||||
constants[36] = skyClouds->viewRight[0];
|
||||
constants[37] = skyClouds->viewRight[1];
|
||||
constants[38] = skyClouds->viewRight[2];
|
||||
constants[39] = skyClouds->tanHalfFovX;
|
||||
constants[40] = skyClouds->viewUp[0];
|
||||
constants[41] = skyClouds->viewUp[1];
|
||||
constants[42] = skyClouds->viewUp[2];
|
||||
constants[43] = skyClouds->tanHalfFovY;
|
||||
constants[44] = skyClouds->noiseScale;
|
||||
constants[45] = skyClouds->coverage;
|
||||
constants[46] = skyClouds->density;
|
||||
constants[47] = skyClouds->seedOffset;
|
||||
}
|
||||
cl->SetGraphicsRoot32BitConstants(QD3D12_PostRootConstants, QD3D12_PostConstantDwords, constants, 0);
|
||||
}
|
||||
|
||||
static void QD3D12_BindPostFogResources(ID3D12GraphicsCommandList* cl, QD3D12Window& w, bool applySceneFog)
|
||||
{
|
||||
if (!cl || !applySceneFog || !g_gl.sceneFogValidThisFrame)
|
||||
if (!cl)
|
||||
return;
|
||||
|
||||
if (w.sceneColorBuffers[w.frameIndex] && w.sceneColorSrvIndex[w.frameIndex] != UINT_MAX)
|
||||
{
|
||||
QD3D12_TransitionResource(cl, w.sceneColorBuffers[w.frameIndex].Get(), w.sceneColorState[w.frameIndex], D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
cl->SetGraphicsRootDescriptorTable(11, w.sceneColorSrvGpu[w.frameIndex]);
|
||||
}
|
||||
|
||||
if (!applySceneFog || !g_gl.sceneFogValidThisFrame)
|
||||
return;
|
||||
if (!w.positionBuffers[w.frameIndex] || !w.depthBuffer)
|
||||
return;
|
||||
@@ -8895,6 +9089,11 @@ static bool QD3D12_ToneMapFullscreenPass(
|
||||
cl->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
cl->SetGraphicsRootDescriptorTable(0, hdrInputSrv);
|
||||
cl->SetGraphicsRootDescriptorTable(7, w.toneMapSceneMaxSrvGpu[frame]);
|
||||
if (w.sceneColorBuffers[frame] && w.sceneColorSrvIndex[frame] != UINT_MAX)
|
||||
{
|
||||
QD3D12_TransitionResource(cl, w.sceneColorBuffers[frame].Get(), w.sceneColorState[frame], D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
cl->SetGraphicsRootDescriptorTable(11, w.sceneColorSrvGpu[frame]);
|
||||
}
|
||||
QD3D12_BindPostFogResources(cl, w, applySceneFog);
|
||||
cl->DrawInstanced(3, 1, 0, 0);
|
||||
return true;
|
||||
@@ -9019,6 +9218,52 @@ void APIENTRY glDrawScreenSpaceDecalsQD3D12(void)
|
||||
}
|
||||
}
|
||||
|
||||
void APIENTRY glDrawSkyCloudsQD3D12(const glSkyClouds_t* clouds)
|
||||
{
|
||||
if (!clouds || clouds->opacity <= 0.0f || clouds->density <= 0.0f)
|
||||
return;
|
||||
|
||||
QD3D12Window* window = g_currentWindow;
|
||||
if (!window || !g_gl.device || !g_gl.cmdList || !g_gl.postSkyCloudsPSO)
|
||||
return;
|
||||
if (!window->sceneColorBuffers[window->frameIndex])
|
||||
return;
|
||||
|
||||
QD3D12_EnsureFrameOpen();
|
||||
QD3D12_FlushQueuedBatches();
|
||||
|
||||
const UINT frame = window->frameIndex;
|
||||
ID3D12GraphicsCommandList* cl = g_gl.cmdList.Get();
|
||||
QD3D12_TransitionResource(cl, window->sceneColorBuffers[frame].Get(), window->sceneColorState[frame], D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
D3D12_VIEWPORT viewport{};
|
||||
viewport.TopLeftX = 0.0f;
|
||||
viewport.TopLeftY = 0.0f;
|
||||
viewport.Width = (float)window->renderWidth;
|
||||
viewport.Height = (float)window->renderHeight;
|
||||
viewport.MinDepth = 0.0f;
|
||||
viewport.MaxDepth = 1.0f;
|
||||
|
||||
D3D12_RECT scissor{};
|
||||
scissor.left = 0;
|
||||
scissor.top = 0;
|
||||
scissor.right = (LONG)window->renderWidth;
|
||||
scissor.bottom = (LONG)window->renderHeight;
|
||||
|
||||
ID3D12DescriptorHeap* heaps[] = { g_gl.srvHeap.Get() };
|
||||
cl->SetDescriptorHeaps(_countof(heaps), heaps);
|
||||
cl->SetGraphicsRootSignature(g_gl.postRootSig.Get());
|
||||
QD3D12_SetPostConstants(cl, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, false, 0.0f, 0.0f, false, 16.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, clouds);
|
||||
cl->SetPipelineState(g_gl.postSkyCloudsPSO.Get());
|
||||
cl->SetGraphicsRootDescriptorTable(0, g_gl.whiteTexture.srvGpu);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE sceneColorRtv = QD3D12_RtvAt(*window, QD3D12_RTV_SCENE_RENDER, frame);
|
||||
cl->OMSetRenderTargets(1, &sceneColorRtv, FALSE, nullptr);
|
||||
cl->RSSetViewports(1, &viewport);
|
||||
cl->RSSetScissorRects(1, &scissor);
|
||||
cl->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
cl->DrawInstanced(3, 1, 0, 0);
|
||||
}
|
||||
|
||||
static void QD3D12_DrawScreenSpaceParticleBatch(const QD3D12ScreenSpaceParticleBatch& batch, ID3D12Resource* tlas, bool emissiveOnly, bool nativeOutput)
|
||||
{
|
||||
const glScreenSpaceParticleVertex_t* verts = batch.vertices.empty() ? nullptr : batch.vertices.data();
|
||||
@@ -9538,7 +9783,6 @@ static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w)
|
||||
sl::Resource depth = { sl::ResourceType::eTex2d, w.depthBuffer.Get(), nullptr, nullptr, uint32_t(w.depthState) };
|
||||
sl::Resource mvec = { sl::ResourceType::eTex2d, w.velocityBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(w.velocityBufferState[w.frameIndex]) };
|
||||
sl::Resource diffuseAlbedo = { sl::ResourceType::eTex2d, w.sceneColorBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(w.sceneColorState[w.frameIndex]) };
|
||||
sl::Resource specularMvec = { sl::ResourceType::eTex2d, w.velocityBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(w.velocityBufferState[w.frameIndex]) };
|
||||
sl::Resource specularAlbedo = { sl::ResourceType::eTex2d, w.specularBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(w.specularBufferState[w.frameIndex]) };
|
||||
sl::Resource normalRoughness = { sl::ResourceType::eTex2d, w.normalBuffers[w.frameIndex].Get(), nullptr, nullptr, uint32_t(w.normalBufferState[w.frameIndex]) };
|
||||
|
||||
@@ -9549,7 +9793,6 @@ static void QD3D12_RunUpscalerOrBlit(QD3D12Window& w)
|
||||
sl::ResourceTag{ &depth, sl::kBufferTypeDepth, sl::ResourceLifecycle::eValidUntilPresent, &renderExtent },
|
||||
sl::ResourceTag{ &mvec, sl::kBufferTypeMotionVectors, sl::ResourceLifecycle::eOnlyValidNow, &renderExtent },
|
||||
sl::ResourceTag{ &diffuseAlbedo, sl::kBufferTypeAlbedo, sl::ResourceLifecycle::eOnlyValidNow, &renderExtent },
|
||||
sl::ResourceTag{ &specularMvec, sl::kBufferTypeSpecularMotionVectors, sl::ResourceLifecycle::eOnlyValidNow, &renderExtent },
|
||||
sl::ResourceTag{ &specularAlbedo, sl::kBufferTypeSpecularAlbedo, sl::ResourceLifecycle::eOnlyValidNow, &renderExtent },
|
||||
sl::ResourceTag{ &normalRoughness, sl::kBufferTypeNormalRoughness, sl::ResourceLifecycle::eOnlyValidNow, &renderExtent }
|
||||
};
|
||||
@@ -10784,6 +11027,7 @@ static void QD3D12_CompileShaders()
|
||||
g_gl.postPsScreenDecalBlob = CompileShaderSourceVariant(kQD3D12PostHLSL, "PSScreenDecals", "ps_6_0");
|
||||
g_gl.postVsScreenParticleBlob = CompileShaderSourceVariant(kQD3D12PostHLSL, "VSParticle", "vs_6_0");
|
||||
g_gl.postPsScreenParticleBlob = CompileShaderSourceVariant(kQD3D12PostHLSL, "PSScreenParticles", "ps_6_5", L"QD3D12_SCREEN_PARTICLE_RAYQUERY=1");
|
||||
g_gl.postPsSkyCloudsBlob = CompileShaderSourceVariant(kQD3D12PostHLSL, "PSSkyClouds", "ps_6_0");
|
||||
}
|
||||
|
||||
static const D3D12_INPUT_ELEMENT_DESC kGLVertexInputLayout[] =
|
||||
@@ -11015,6 +11259,16 @@ static void QD3D12_CreatePSOs()
|
||||
d.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ONE;
|
||||
QD3D12_CHECK(g_gl.device->CreateGraphicsPipelineState(&d, IID_PPV_ARGS(&g_gl.postScreenDecalStainPSO)));
|
||||
|
||||
d.PS = { g_gl.postPsSkyCloudsBlob->GetBufferPointer(), g_gl.postPsSkyCloudsBlob->GetBufferSize() };
|
||||
d.BlendState.RenderTarget[0].BlendEnable = TRUE;
|
||||
d.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
|
||||
d.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
d.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
|
||||
d.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
|
||||
d.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
d.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
QD3D12_CHECK(g_gl.device->CreateGraphicsPipelineState(&d, IID_PPV_ARGS(&g_gl.postSkyCloudsPSO)));
|
||||
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC particleDesc = d;
|
||||
particleDesc.VS = { g_gl.postVsScreenParticleBlob->GetBufferPointer(), g_gl.postVsScreenParticleBlob->GetBufferSize() };
|
||||
particleDesc.PS = { g_gl.postPsScreenParticleBlob->GetBufferPointer(), g_gl.postPsScreenParticleBlob->GetBufferSize() };
|
||||
@@ -17881,6 +18135,7 @@ PROC WINAPI qd3d12_wglGetProcAddress(LPCSTR name) {
|
||||
{ "glDrawScreenSpaceDecalsQD3D12",(PROC)glDrawScreenSpaceDecalsQD3D12 },
|
||||
{ "glSetScreenSpaceParticleLightsQD3D12",(PROC)glSetScreenSpaceParticleLightsQD3D12 },
|
||||
{ "glDrawScreenSpaceParticlesQD3D12",(PROC)glDrawScreenSpaceParticlesQD3D12 },
|
||||
{ "glDrawSkyCloudsQD3D12", (PROC)glDrawSkyCloudsQD3D12 },
|
||||
{ "QD3D12_SetUpscalerBackend", (PROC)QD3D12_SetUpscalerBackend },
|
||||
{ "QD3D12_SetUpscalerQuality", (PROC)QD3D12_SetUpscalerQuality },
|
||||
{ "QD3D12_SetUpscalerSharpness", (PROC)QD3D12_SetUpscalerSharpness },
|
||||
|
||||
@@ -1794,6 +1794,24 @@ typedef struct glScreenSpaceParticleVertex_s
|
||||
float pad0;
|
||||
} glScreenSpaceParticleVertex_t;
|
||||
|
||||
typedef struct glSkyClouds_s
|
||||
{
|
||||
float skyColor[3];
|
||||
float opacity;
|
||||
float viewOrigin[3];
|
||||
float zMin;
|
||||
float viewForward[3];
|
||||
float zMax;
|
||||
float viewRight[3];
|
||||
float tanHalfFovX;
|
||||
float viewUp[3];
|
||||
float tanHalfFovY;
|
||||
float noiseScale;
|
||||
float coverage;
|
||||
float density;
|
||||
float seedOffset;
|
||||
} glSkyClouds_t;
|
||||
|
||||
int glRaytracingInit(void);
|
||||
void glRaytracingShutdown(void);
|
||||
void glRaytracingClear(void);
|
||||
@@ -1893,6 +1911,7 @@ void glSetScreenSpaceDecalsQD3D12(const glScreenSpaceDecal
|
||||
void glDrawScreenSpaceDecalsQD3D12(void);
|
||||
void glSetScreenSpaceParticleLightsQD3D12(const glRaytracingLight_t* lights, uint32_t lightCount);
|
||||
void glDrawScreenSpaceParticlesQD3D12(const glScreenSpaceParticleVertex_t* verts, uint32_t vertexCount, uint32_t textureId, uint32_t blendMode, float softDepth, float emissiveScale);
|
||||
void glDrawSkyCloudsQD3D12(const glSkyClouds_t* clouds);
|
||||
|
||||
ID3D12Device* QD3D12_GetDevice(void);
|
||||
ID3D12CommandQueue* QD3D12_GetQueue(void);
|
||||
@@ -2313,6 +2332,8 @@ void glUpdateTopLevelAceelStructure(
|
||||
void glRaytracingLightingSetExternalDenoiser(int enable);
|
||||
void glRaytracingLightingUseExternalDenoiser(int enable);
|
||||
void glRaytracingLightingSetPathTracingOptions(uint32_t samplesPerPixel, uint32_t maxBounces, int enableDenoiser, float denoiseStrength);
|
||||
void glRaytracingLightingSetGIAmount(float amount);
|
||||
void glRaytracingLightingSetWorldGrime(float amount);
|
||||
void glRaytracingLightingSetSecondaryLightBudget(int budget, float compensation);
|
||||
void QD3D12_SetPathTracingQuality(uint32_t samplesPerPixel, uint32_t maxBounces);
|
||||
void QD3D12_SetPathTracingFallbackSamples(uint32_t samplesPerPixel);
|
||||
|
||||
Reference in New Issue
Block a user