Remove disabling temporal reprojection from Volumetric Fog
This commit is contained in:
@@ -146,7 +146,6 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridPixelSize = 16;
|
_cache.GridPixelSize = 16;
|
||||||
_cache.GridSizeZ = 64;
|
_cache.GridSizeZ = 64;
|
||||||
_cache.FogJitter = false;
|
_cache.FogJitter = false;
|
||||||
_cache.TemporalReprojection = false;
|
|
||||||
_cache.MissedHistorySamplesCount = 1;
|
_cache.MissedHistorySamplesCount = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -155,7 +154,6 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridPixelSize = 16;
|
_cache.GridPixelSize = 16;
|
||||||
_cache.GridSizeZ = 64;
|
_cache.GridSizeZ = 64;
|
||||||
_cache.FogJitter = true;
|
_cache.FogJitter = true;
|
||||||
_cache.TemporalReprojection = true;
|
|
||||||
_cache.MissedHistorySamplesCount = 4;
|
_cache.MissedHistorySamplesCount = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -164,7 +162,6 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridPixelSize = 16;
|
_cache.GridPixelSize = 16;
|
||||||
_cache.GridSizeZ = 128;
|
_cache.GridSizeZ = 128;
|
||||||
_cache.FogJitter = true;
|
_cache.FogJitter = true;
|
||||||
_cache.TemporalReprojection = true;
|
|
||||||
_cache.MissedHistorySamplesCount = 4;
|
_cache.MissedHistorySamplesCount = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -173,7 +170,6 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
_cache.GridPixelSize = 8;
|
_cache.GridPixelSize = 8;
|
||||||
_cache.GridSizeZ = 256;
|
_cache.GridSizeZ = 256;
|
||||||
_cache.FogJitter = true;
|
_cache.FogJitter = true;
|
||||||
_cache.TemporalReprojection = true;
|
|
||||||
_cache.MissedHistorySamplesCount = 8;
|
_cache.MissedHistorySamplesCount = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -214,7 +210,7 @@ bool VolumetricFogPass::Init(RenderContext& renderContext, GPUContext* context,
|
|||||||
{
|
{
|
||||||
_cache.Data.FrameJitterOffsets[i] = defaultOffset;
|
_cache.Data.FrameJitterOffsets[i] = defaultOffset;
|
||||||
}
|
}
|
||||||
if (_cache.FogJitter && _cache.TemporalReprojection)
|
if (_cache.FogJitter)
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < _cache.MissedHistorySamplesCount; i++)
|
for (int32 i = 0; i < _cache.MissedHistorySamplesCount; i++)
|
||||||
{
|
{
|
||||||
@@ -320,7 +316,7 @@ void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUConte
|
|||||||
InitCircleBuffer();
|
InitCircleBuffer();
|
||||||
|
|
||||||
// Call rendering to the volume
|
// Call rendering to the volume
|
||||||
const int32 psIndex = (_cache.TemporalReprojection ? 1 : 0) + 2;
|
const int32 psIndex = 1;
|
||||||
context->SetState(_psInjectLight.Get(psIndex));
|
context->SetState(_psInjectLight.Get(psIndex));
|
||||||
const int32 instanceCount = volumeZBoundsMax - volumeZBoundsMin;
|
const int32 instanceCount = volumeZBoundsMax - volumeZBoundsMin;
|
||||||
const int32 indexCount = _ibCircleRasterize->GetElementsCount();
|
const int32 indexCount = _ibCircleRasterize->GetElementsCount();
|
||||||
@@ -379,7 +375,7 @@ void VolumetricFogPass::RenderRadialLight(RenderContext& renderContext, GPUConte
|
|||||||
InitCircleBuffer();
|
InitCircleBuffer();
|
||||||
|
|
||||||
// Call rendering to the volume
|
// Call rendering to the volume
|
||||||
const int32 psIndex = (cache.TemporalReprojection ? 1 : 0) + (withShadow ? 2 : 0);
|
const int32 psIndex = withShadow ? 1 : 0;
|
||||||
context->SetState(_psInjectLight.Get(psIndex));
|
context->SetState(_psInjectLight.Get(psIndex));
|
||||||
const int32 instanceCount = volumeZBoundsMax - volumeZBoundsMin;
|
const int32 instanceCount = volumeZBoundsMax - volumeZBoundsMin;
|
||||||
const int32 indexCount = _ibCircleRasterize->GetElementsCount();
|
const int32 indexCount = _ibCircleRasterize->GetElementsCount();
|
||||||
@@ -479,12 +475,6 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
|||||||
context->UpdateCB(cb0, &_cache.Data);
|
context->UpdateCB(cb0, &_cache.Data);
|
||||||
context->BindCB(0, cb0);
|
context->BindCB(0, cb0);
|
||||||
|
|
||||||
// Peek flags
|
|
||||||
const bool temporalHistoryIsValid = cache.TemporalReprojection
|
|
||||||
&& renderContext.Buffers->VolumetricFogHistory
|
|
||||||
&& !renderContext.Task->IsCameraCut
|
|
||||||
&& Float3::NearEqual(renderContext.Buffers->VolumetricFogHistory->Size3(), cache.GridSize);
|
|
||||||
|
|
||||||
// Allocate buffers
|
// Allocate buffers
|
||||||
const GPUTextureDescription volumeDesc = GPUTextureDescription::New3D(cache.GridSize, PixelFormat::R16G16B16A16_Float, GPUTextureFlags::RenderTarget | GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess);
|
const GPUTextureDescription volumeDesc = GPUTextureDescription::New3D(cache.GridSize, PixelFormat::R16G16B16A16_Float, GPUTextureFlags::RenderTarget | GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess);
|
||||||
const GPUTextureDescription volumeDescRGB = GPUTextureDescription::New3D(cache.GridSize, PixelFormat::R11G11B10_Float, GPUTextureFlags::RenderTarget | GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess);
|
const GPUTextureDescription volumeDescRGB = GPUTextureDescription::New3D(cache.GridSize, PixelFormat::R11G11B10_Float, GPUTextureFlags::RenderTarget | GPUTextureFlags::ShaderResource | GPUTextureFlags::UnorderedAccess);
|
||||||
@@ -646,6 +636,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
|||||||
{
|
{
|
||||||
PROFILE_GPU("Light Scattering");
|
PROFILE_GPU("Light Scattering");
|
||||||
|
|
||||||
|
const bool temporalHistoryIsValid = renderContext.Buffers->VolumetricFogHistory && !renderContext.Task->IsCameraCut && Float3::NearEqual(renderContext.Buffers->VolumetricFogHistory->Size3(), cache.GridSize);
|
||||||
const auto lightScatteringHistory = temporalHistoryIsValid ? renderContext.Buffers->VolumetricFogHistory : nullptr;
|
const auto lightScatteringHistory = temporalHistoryIsValid ? renderContext.Buffers->VolumetricFogHistory : nullptr;
|
||||||
|
|
||||||
context->BindUA(0, lightScattering->ViewVolume());
|
context->BindUA(0, lightScattering->ViewVolume());
|
||||||
@@ -656,7 +647,7 @@ void VolumetricFogPass::Render(RenderContext& renderContext)
|
|||||||
context->BindSR(4, dirLightShadowMap);
|
context->BindSR(4, dirLightShadowMap);
|
||||||
context->BindSR(5, skyLightImage);
|
context->BindSR(5, skyLightImage);
|
||||||
|
|
||||||
const int32 csIndex = cache.TemporalReprojection ? 1 : 0;
|
const int32 csIndex = 0;
|
||||||
context->Dispatch(_csLightScattering.Get(csIndex), groupCountX, groupCountY, groupCountZ);
|
context->Dispatch(_csLightScattering.Get(csIndex), groupCountX, groupCountY, groupCountZ);
|
||||||
|
|
||||||
context->ResetSR();
|
context->ResetSR();
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ private:
|
|||||||
// Shader stuff
|
// Shader stuff
|
||||||
AssetReference<Shader> _shader;
|
AssetReference<Shader> _shader;
|
||||||
GPUShaderProgramCS* _csInitialize = nullptr;
|
GPUShaderProgramCS* _csInitialize = nullptr;
|
||||||
ComputeShaderPermutation<2> _csLightScattering;
|
ComputeShaderPermutation<1> _csLightScattering;
|
||||||
GPUShaderProgramCS* _csFinalIntegration = nullptr;
|
GPUShaderProgramCS* _csFinalIntegration = nullptr;
|
||||||
GPUPipelineStatePermutationsPs<4> _psInjectLight;
|
GPUPipelineStatePermutationsPs<2> _psInjectLight;
|
||||||
|
|
||||||
GPUBuffer* _vbCircleRasterize = nullptr;
|
GPUBuffer* _vbCircleRasterize = nullptr;
|
||||||
GPUBuffer* _ibCircleRasterize = nullptr;
|
GPUBuffer* _ibCircleRasterize = nullptr;
|
||||||
@@ -108,11 +108,6 @@ private:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool FogJitter;
|
bool FogJitter;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether to use temporal reprojection on volumetric fog.
|
|
||||||
/// </summary>
|
|
||||||
bool TemporalReprojection;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How much the history value should be weighted each frame. This is a tradeoff between visible jittering and responsiveness.
|
/// How much the history value should be weighted each frame. This is a tradeoff between visible jittering and responsiveness.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -185,10 +185,8 @@ float ComputeVolumeShadowing(float3 worldPosition, bool isSpotLight)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
META_PS(true, FEATURE_LEVEL_SM5)
|
META_PS(true, FEATURE_LEVEL_SM5)
|
||||||
META_PERMUTATION_2(USE_TEMPORAL_REPROJECTION=0, USE_SHADOW=0)
|
META_PERMUTATION_1(USE_SHADOW=0)
|
||||||
META_PERMUTATION_2(USE_TEMPORAL_REPROJECTION=1, USE_SHADOW=0)
|
META_PERMUTATION_1(USE_SHADOW=1)
|
||||||
META_PERMUTATION_2(USE_TEMPORAL_REPROJECTION=0, USE_SHADOW=1)
|
|
||||||
META_PERMUTATION_2(USE_TEMPORAL_REPROJECTION=1, USE_SHADOW=1)
|
|
||||||
float4 PS_InjectLight(Quad_GS2PS input) : SV_Target0
|
float4 PS_InjectLight(Quad_GS2PS input) : SV_Target0
|
||||||
{
|
{
|
||||||
uint3 gridCoordinate = uint3(input.Vertex.Position.xy, input.LayerIndex);
|
uint3 gridCoordinate = uint3(input.Vertex.Position.xy, input.LayerIndex);
|
||||||
@@ -197,18 +195,12 @@ float4 PS_InjectLight(Quad_GS2PS input) : SV_Target0
|
|||||||
if (!all(gridCoordinate < GridSizeInt))
|
if (!all(gridCoordinate < GridSizeInt))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if USE_TEMPORAL_REPROJECTION
|
|
||||||
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
||||||
float historyAlpha = HistoryWeight;
|
float historyAlpha = HistoryWeight;
|
||||||
FLATTEN
|
FLATTEN
|
||||||
if (any(historyUV < 0) || any(historyUV > 1))
|
if (any(historyUV < 0) || any(historyUV > 1))
|
||||||
{
|
|
||||||
historyAlpha = 0;
|
historyAlpha = 0;
|
||||||
}
|
|
||||||
uint samplesCount = historyAlpha < 0.001f ? MissedHistorySamplesCount : 1;
|
uint samplesCount = historyAlpha < 0.001f ? MissedHistorySamplesCount : 1;
|
||||||
#else
|
|
||||||
uint samplesCount = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float NoL = 0;
|
float NoL = 0;
|
||||||
float distanceAttenuation = 1;
|
float distanceAttenuation = 1;
|
||||||
@@ -298,28 +290,19 @@ TextureCube SkyLightImage : register(t5);
|
|||||||
#define THREADGROUP_SIZE 4
|
#define THREADGROUP_SIZE 4
|
||||||
|
|
||||||
META_CS(true, FEATURE_LEVEL_SM5)
|
META_CS(true, FEATURE_LEVEL_SM5)
|
||||||
META_PERMUTATION_1(USE_TEMPORAL_REPROJECTION=0)
|
|
||||||
META_PERMUTATION_1(USE_TEMPORAL_REPROJECTION=1)
|
|
||||||
[numthreads(THREADGROUP_SIZE, THREADGROUP_SIZE, THREADGROUP_SIZE)]
|
[numthreads(THREADGROUP_SIZE, THREADGROUP_SIZE, THREADGROUP_SIZE)]
|
||||||
void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_DispatchThreadID, uint3 GroupThreadId : SV_GroupThreadID)
|
void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_DispatchThreadID, uint3 GroupThreadId : SV_GroupThreadID)
|
||||||
{
|
{
|
||||||
uint3 gridCoordinate = DispatchThreadId;
|
uint3 gridCoordinate = DispatchThreadId;
|
||||||
float3 lightScattering = 0;
|
float3 lightScattering = 0;
|
||||||
uint samplesCount = 1;
|
uint samplesCount = 1;
|
||||||
|
|
||||||
#if USE_TEMPORAL_REPROJECTION
|
|
||||||
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
float3 historyUV = GetVolumeUV(GetCellPositionWS(gridCoordinate, 0.5f), PrevWorldToClip);
|
||||||
float historyAlpha = HistoryWeight;
|
float historyAlpha = HistoryWeight;
|
||||||
|
|
||||||
// Discard history if it lays outside the current view
|
|
||||||
FLATTEN
|
FLATTEN
|
||||||
if (any(historyUV < 0) || any(historyUV > 1))
|
if (any(historyUV < 0) || any(historyUV > 1))
|
||||||
{
|
|
||||||
historyAlpha = 0;
|
historyAlpha = 0;
|
||||||
}
|
|
||||||
|
|
||||||
samplesCount = historyAlpha < 0.001f && all(gridCoordinate < GridSizeInt) ? MissedHistorySamplesCount : 1;
|
samplesCount = historyAlpha < 0.001f && all(gridCoordinate < GridSizeInt) ? MissedHistorySamplesCount : 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
for (uint sampleIndex = 0; sampleIndex < samplesCount; sampleIndex++)
|
for (uint sampleIndex = 0; sampleIndex < samplesCount; sampleIndex++)
|
||||||
{
|
{
|
||||||
@@ -363,15 +346,13 @@ void CS_LightScattering(uint3 GroupId : SV_GroupID, uint3 DispatchThreadId : SV_
|
|||||||
float extinction = materialScatteringAndAbsorption.w + Luminance(materialScatteringAndAbsorption.xyz);
|
float extinction = materialScatteringAndAbsorption.w + Luminance(materialScatteringAndAbsorption.xyz);
|
||||||
float3 materialEmissive = VBufferB[gridCoordinate].xyz;
|
float3 materialEmissive = VBufferB[gridCoordinate].xyz;
|
||||||
float4 scatteringAndExtinction = float4(lightScattering * materialScatteringAndAbsorption.xyz + materialEmissive, extinction);
|
float4 scatteringAndExtinction = float4(lightScattering * materialScatteringAndAbsorption.xyz + materialEmissive, extinction);
|
||||||
|
|
||||||
#if USE_TEMPORAL_REPROJECTION
|
|
||||||
BRANCH
|
BRANCH
|
||||||
if (historyAlpha > 0)
|
if (historyAlpha > 0)
|
||||||
{
|
{
|
||||||
float4 historyScatteringAndExtinction = LightScatteringHistory.SampleLevel(SamplerLinearClamp, historyUV, 0);
|
float4 historyScatteringAndExtinction = LightScatteringHistory.SampleLevel(SamplerLinearClamp, historyUV, 0);
|
||||||
scatteringAndExtinction = lerp(scatteringAndExtinction, historyScatteringAndExtinction, historyAlpha);
|
scatteringAndExtinction = lerp(scatteringAndExtinction, historyScatteringAndExtinction, historyAlpha);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (all(gridCoordinate < GridSizeInt))
|
if (all(gridCoordinate < GridSizeInt))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user