浏览代码

Reduce the reliance on macros for sampling the V-Buffer

/Yibing-Project-2
Evgenii Golubev 7 年前
当前提交
24634f16
共有 6 个文件被更改,包括 74 次插入60 次删除
  1. 100
      ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl
  2. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs
  3. 18
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  4. 8
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs
  5. 3
      ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  6. 2
      ScriptableRenderPipeline/HDRenderPipeline/Sky/AtmosphericScattering/AtmosphericScattering.hlsl

100
ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl


#define VOLUMETRIC_LIGHTING_ENABLED
#ifdef PRESET_ULTRA
// E.g. for 1080p: (1920/4)x(1080/4)x(256) = 33,177,600 voxels
#define VBUFFER_TILE_SIZE 4
#define VBUFFER_SLICE_COUNT 256
#else
// E.g. for 1080p: (1920/8)x(1080/8)x(128) = 4,147,200 voxels
#define VBUFFER_TILE_SIZE 8
#define VBUFFER_SLICE_COUNT 128
#endif // PRESET_ULTRA
// Interpolation in the log space is non-linear.
// Therefore, given 'logEncodedDepth', we compute a new depth value
// which allows us to perform HW interpolation which is linear in the view space.
float ComputeLerpPositionForLogEncoding(float linearDepth, float logEncodedDepth,
float4 VBufferScaleAndSliceCount,
float4 VBufferDepthEncodingParams)
{
float z = linearDepth;
float d = logEncodedDepth;
#include "Random.hlsl"
float numSlices = VBufferScaleAndSliceCount.z;
float rcpNumSlices = VBufferScaleAndSliceCount.w;
// Samples the linearly interpolated V-Buffer.
float s0 = floor(d * numSlices - 0.5);
float s1 = ceil(d * numSlices - 0.5);
float d0 = saturate(s0 * rcpNumSlices + (0.5 * rcpNumSlices));
float d1 = saturate(s1 * rcpNumSlices + (0.5 * rcpNumSlices));
float z0 = DecodeLogarithmicDepth(d0, VBufferDepthEncodingParams);
float z1 = DecodeLogarithmicDepth(d1, VBufferDepthEncodingParams);
// Compute the linear interpolation weight.
float t = saturate((z - z0) / (z1 - z0));
return d0 + t * rcpNumSlices;
}
// Performs trilinear reconstruction of the V-Buffer.
float2 VBufferScale,
float4 VBufferScaleAndSliceCount,
int k = VBUFFER_SLICE_COUNT;
float z = linearDepth;
float d = EncodeLogarithmicDepth(z, VBufferDepthEncodingParams);
float numSlices = VBufferScaleAndSliceCount.z;
float rcpNumSlices = VBufferScaleAndSliceCount.w;
float2 uv = positionNDC * VBufferScale;
float2 uv = positionNDC * VBufferScaleAndSliceCount.xy;
// The distance between slices is log-encoded.
float z = linearDepth;
float d = EncodeLogarithmicDepth(z, VBufferDepthEncodingParams);
// Unity doesn't support samplers clamping to border, so we have to do it ourselves.
// TODO: add the proper sampler support.

{
// The distance between slices is log-encoded.
float s0 = floor(d * k - 0.5);
float s1 = ceil(d * k - 0.5);
float d0 = saturate(s0 * rcp(k) + (0.5 * rcp(k)));
float d1 = saturate(s1 * rcp(k) + (0.5 * rcp(k)));
float z0 = DecodeLogarithmicDepth(d0, VBufferDepthEncodingParams);
float z1 = DecodeLogarithmicDepth(d1, VBufferDepthEncodingParams);
// Adjust the texture coordinate for HW trilinear sampling.
float w = ComputeLerpPositionForLogEncoding(z, d, VBufferScaleAndSliceCount, VBufferDepthEncodingParams);
// Compute the linear Z-interpolation weight.
float a = saturate((z - z0) / (z1 - z0));
float w = d0 + a * rcp(k);
// Adjust the texture coordinate and take a single HW trlinear sample.
return SAMPLE_TEXTURE3D_LOD(VBufferLighting, trilinearSampler, float3(uv, w), 0);
}
else

}
// Returns linearly interpolated {volumetric radiance, opacity}. The sampler clamps to edge.
// Returns interpolated {volumetric radiance, opacity}. The sampler clamps to edge.
float4 VBufferResolutionAndScale, float4 VBufferDepthEncodingParams)
float4 VBufferResolution,
float4 VBufferScaleAndSliceCount,
float4 VBufferDepthEncodingParams)
positionNDC, linearDepth, VBufferScale, VBufferDepthEncodingParams);
positionNDC, linearDepth,
VBufferScaleAndSliceCount, VBufferDepthEncodingParams);
int k = VBUFFER_SLICE_COUNT;
float z = linearDepth;
float d = EncodeLogarithmicDepth(z, VBufferDepthEncodingParams);
// The distance between slices is log-encoded.
float s0 = floor(d * k - 0.5);
float s1 = ceil(d * k - 0.5);
float d0 = saturate(s0 * rcp(k) + (0.5 * rcp(k)));
float d1 = saturate(s1 * rcp(k) + (0.5 * rcp(k)));
float z0 = DecodeLogarithmicDepth(d0, VBufferDepthEncodingParams);
float z1 = DecodeLogarithmicDepth(d1, VBufferDepthEncodingParams);
// Compute the linear Z-interpolation weight.
float a = saturate((z - z0) / (z1 - z0));
float w = d0 + a * rcp(k);
float2 xy = positionNDC * (VBufferResolutionAndScale.xy * VBufferResolutionAndScale.zw); // TODO: precompute
float2 xy = positionNDC * (VBufferResolution.xy * VBufferScaleAndSliceCount.xy);
// The distance between slices is log-encoded.
float z = linearDepth;
float d = EncodeLogarithmicDepth(z, VBufferDepthEncodingParams);
// Adjust the texture coordinate for HW trilinear sampling.
float w = ComputeLerpPositionForLogEncoding(z, d, VBufferScaleAndSliceCount, VBufferDepthEncodingParams);
float2 rcpRes = rcp(VBufferResolutionAndScale.xy); // TODO: precompute
float2 rcpRes = VBufferResolution.zw;
// TODO: reconstruction should be performed in the perceptual space (e.i., after tone mapping).
// But our VBuffer is linear. How to achieve that?
// See "A Fresh Look at Generalized Sampling", p. 51.
float4 L = (weights[0].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBufferLighting, trilinearSampler, float3((ic + float2(offsets[0].x, offsets[0].y)) * rcpRes, w), 0) // Top left
+ (weights[1].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBufferLighting, trilinearSampler, float3((ic + float2(offsets[1].x, offsets[0].y)) * rcpRes, w), 0) // Top right
+ (weights[0].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBufferLighting, trilinearSampler, float3((ic + float2(offsets[0].x, offsets[1].y)) * rcpRes, w), 0) // Bottom left

3
ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs


public static readonly int _GlobalFog_Extinction = Shader.PropertyToID("_GlobalFog_Extinction");
public static readonly int _GlobalFog_Scattering = Shader.PropertyToID("_GlobalFog_Scattering");
public static readonly int _VBufferResolutionAndScale = Shader.PropertyToID("_VBufferResolutionAndScale");
public static readonly int _VBufferResolution = Shader.PropertyToID("_VBufferResolution");
public static readonly int _VBufferScaleAndSliceCount = Shader.PropertyToID("_VBufferScaleAndSliceCount");
public static readonly int _VBufferDepthEncodingParams = Shader.PropertyToID("_VBufferDepthEncodingParams");
public static readonly int _VBufferCoordToViewDirWS = Shader.PropertyToID("_VBufferCoordToViewDirWS");
public static readonly int _VBufferDensity = Shader.PropertyToID("_VBufferDensity");

18
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute


#define GROUP_SIZE_1D 16
#define GROUP_SIZE_2D (GROUP_SIZE_1D * GROUP_SIZE_1D)
#ifdef PRESET_ULTRA
// E.g. for 1080p: (1920/4)x(1080/4)x(256) = 33,177,600 voxels
#define VBUFFER_TILE_SIZE 4
#define VBUFFER_SLICE_COUNT 256
#else
// E.g. for 1080p: (1920/8)x(1080/8)x(128) = 4,147,200 voxels
#define VBUFFER_TILE_SIZE 8
#define VBUFFER_SLICE_COUNT 128
#endif // PRESET_ULTRA
//--------------------------------------------------------------------------------------------------
// Included headers
//--------------------------------------------------------------------------------------------------

float reprojZ = mul(_PrevViewProjMatrix, float4(centerWS, 1)).w;
float4 reprojValue = SampleVBuffer(TEXTURE3D_PARAM(_VBufferLightingHistory, s_trilinear_clamp_sampler),
false, reprojPosNDC, reprojZ,
_VBufferResolutionAndScale.zw,
_VBufferScaleAndSliceCount,
_VBufferDepthEncodingParams);
// Compute the exponential moving average over 'n' frames:

tileCoord = WaveReadFirstLane(tileCoord);
}
[branch] if (voxelCoord.x >= (uint)_VBufferResolutionAndScale.x ||
voxelCoord.y >= (uint)_VBufferResolutionAndScale.y)
[branch] if (voxelCoord.x >= (uint)_VBufferResolution.x ||
voxelCoord.y >= (uint)_VBufferResolution.y)
{
return;
}

context.shadowContext = InitShadowContext();
uint featureFlags = 0xFFFFFFFF;
PositionInputs posInput = GetPositionInput(voxelCoord, rcp(_VBufferResolutionAndScale.xy), tileCoord);
PositionInputs posInput = GetPositionInput(voxelCoord, _VBufferResolution.zw, tileCoord);
FillVolumetricLightingBuffer(context, featureFlags, posInput, ray);
}

8
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs


int w = 0, h = 0, d = 0;
Vector2 scale = ComputeVBufferResolutionAndScale(camera.screenSize.x, camera.screenSize.y, ref w, ref h, ref d);
Vector4 resAndScale = new Vector4(w, h, scale.x, scale.y);
Vector4 depthParams = ComputeLogarithmicDepthEncodingParams(m_VBufferNearPlane, m_VBufferFarPlane);
cmd.SetGlobalVector( HDShaderIDs._VBufferResolutionAndScale, resAndScale);
cmd.SetGlobalVector( HDShaderIDs._VBufferDepthEncodingParams, depthParams);
cmd.SetGlobalVector( HDShaderIDs._VBufferResolution, new Vector4(w, h, 1.0f / w, 1.0f / h));
cmd.SetGlobalVector( HDShaderIDs._VBufferScaleAndSliceCount, new Vector4(scale.x, scale.y, d, 1.0f / d));
cmd.SetGlobalVector( HDShaderIDs._VBufferDepthEncodingParams, ComputeLogarithmicDepthEncodingParams(m_VBufferNearPlane, m_VBufferFarPlane));
cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, GetVBufferLightingIntegral());
}

3
ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


// Unfortunately, structures inside constant buffers are not supported by Unity.
float3 _GlobalFog_Scattering;
float _GlobalFog_Extinction;
float4 _VBufferResolution; // { w, h, 1/w, 1/h }
float4 _VBufferScaleAndSliceCount; // { fracVisW, fracVisH, count, 1/count }
float4 _VBufferResolutionAndScale; // { w, h, fracVisW, fracVisH }
CBUFFER_END
// ----------------------------------------------------------------------------

2
ScriptableRenderPipeline/HDRenderPipeline/Sky/AtmosphericScattering/AtmosphericScattering.hlsl


#ifdef VOLUMETRIC_LIGHTING_ENABLED
return SampleInScatteredRadianceAndTransmittance(TEXTURE3D_PARAM(_VBufferLighting, s_trilinear_clamp_sampler),
posInput.positionNDC, posInput.linearDepth,
_VBufferResolutionAndScale,
_VBufferResolution, _VBufferScaleAndSliceCount,
_VBufferDepthEncodingParams);
#endif

正在加载...
取消
保存