199 lines
11 KiB
C#
199 lines
11 KiB
C#
using System;
|
|
using UnityEngine.Experimental.Rendering;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
public partial class HDRenderPipeline
|
|
{
|
|
MaterialPropertyBlock directionalShadowPB = new MaterialPropertyBlock();
|
|
struct RTShadowDirectionalTraceParameters
|
|
{
|
|
// Camera parameters
|
|
public int texWidth;
|
|
public int texHeight;
|
|
public int viewCount;
|
|
|
|
// Evaluation parameters
|
|
public bool softShadow;
|
|
public int numShadowSamples;
|
|
public bool colorShadow;
|
|
public float maxShadowLength;
|
|
|
|
// Kernels
|
|
public int clearShadowKernel;
|
|
public int directionalShadowSample;
|
|
|
|
// Other parameters
|
|
public RayTracingShader screenSpaceShadowRT;
|
|
public ComputeShader screenSpaceShadowCS;
|
|
public RayTracingAccelerationStructure accelerationStructure;
|
|
public ShaderVariablesRaytracing shaderVariablesRayTracingCB;
|
|
public BlueNoise.DitheredTextureSet ditheredTextureSet;
|
|
}
|
|
|
|
RTShadowDirectionalTraceParameters PrepareRTShadowDirectionalTraceParameters(HDCamera hdCamera, HDAdditionalLightData additionalLightData)
|
|
{
|
|
RTShadowDirectionalTraceParameters rtsdtParams = new RTShadowDirectionalTraceParameters();
|
|
RayTracingSettings rayTracingSettings = hdCamera.volumeStack.GetComponent<RayTracingSettings>();
|
|
|
|
// Set the camera parameters
|
|
rtsdtParams.texWidth = hdCamera.actualWidth;
|
|
rtsdtParams.texHeight = hdCamera.actualHeight;
|
|
rtsdtParams.viewCount = hdCamera.viewCount;
|
|
|
|
// Evaluation parameters
|
|
rtsdtParams.softShadow = additionalLightData.angularDiameter > 0.0 ? true : false;
|
|
// If the surface is infinitively small, we force it to one sample.
|
|
rtsdtParams.numShadowSamples = rtsdtParams.softShadow ? additionalLightData.numRayTracingSamples : 1;
|
|
rtsdtParams.colorShadow = m_CurrentSunLightAdditionalLightData.colorShadow;
|
|
rtsdtParams.maxShadowLength = rayTracingSettings.directionalShadowRayLength.value;
|
|
|
|
// Kernels
|
|
rtsdtParams.clearShadowKernel = m_ClearShadowTexture;
|
|
rtsdtParams.directionalShadowSample = m_RaytracingDirectionalShadowSample;
|
|
|
|
// Grab the acceleration structure for the target camera
|
|
rtsdtParams.accelerationStructure = RequestAccelerationStructure();
|
|
rtsdtParams.screenSpaceShadowCS = m_ScreenSpaceShadowsCS;
|
|
rtsdtParams.screenSpaceShadowRT = m_ScreenSpaceShadowsRT;
|
|
rtsdtParams.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB;
|
|
BlueNoise blueNoise = GetBlueNoiseManager();
|
|
rtsdtParams.ditheredTextureSet = blueNoise.DitheredTextureSet8SPP();
|
|
|
|
return rtsdtParams;
|
|
}
|
|
|
|
struct RTShadowDirectionalTraceResources
|
|
{
|
|
// Input Buffers
|
|
public RTHandle depthStencilBuffer;
|
|
public RTHandle normalBuffer;
|
|
|
|
// Intermediate buffers
|
|
public RTHandle directionBuffer;
|
|
|
|
// Debug textures
|
|
public RTHandle rayCountTexture;
|
|
|
|
// Output buffers
|
|
public RTHandle velocityBuffer;
|
|
public RTHandle distanceBuffer;
|
|
public RTHandle outputShadowBuffer;
|
|
}
|
|
|
|
static void ExecuteSSSDirectionalTrace(CommandBuffer cmd, RTShadowDirectionalTraceParameters rtsdtParams, RTShadowDirectionalTraceResources rtsdtResources)
|
|
{
|
|
// Inject the ray-tracing sampling data
|
|
BlueNoise.BindDitheredTextureSet(cmd, rtsdtParams.ditheredTextureSet);
|
|
|
|
// Evaluate the dispatch parameters
|
|
int shadowTileSize = 8;
|
|
int numTilesX = (rtsdtParams.texWidth + (shadowTileSize - 1)) / shadowTileSize;
|
|
int numTilesY = (rtsdtParams.texHeight + (shadowTileSize - 1)) / shadowTileSize;
|
|
|
|
// Clear the integration texture
|
|
cmd.SetComputeTextureParam(rtsdtParams.screenSpaceShadowCS, rtsdtParams.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, rtsdtResources.outputShadowBuffer);
|
|
cmd.DispatchCompute(rtsdtParams.screenSpaceShadowCS, rtsdtParams.clearShadowKernel, numTilesX, numTilesY, rtsdtParams.viewCount);
|
|
|
|
cmd.SetComputeTextureParam(rtsdtParams.screenSpaceShadowCS, rtsdtParams.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, rtsdtResources.velocityBuffer);
|
|
cmd.DispatchCompute(rtsdtParams.screenSpaceShadowCS, rtsdtParams.clearShadowKernel, numTilesX, numTilesY, rtsdtParams.viewCount);
|
|
|
|
cmd.SetComputeTextureParam(rtsdtParams.screenSpaceShadowCS, rtsdtParams.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, rtsdtResources.distanceBuffer);
|
|
cmd.DispatchCompute(rtsdtParams.screenSpaceShadowCS, rtsdtParams.clearShadowKernel, numTilesX, numTilesY, rtsdtParams.viewCount);
|
|
|
|
// Grab and bind the acceleration structure for the target camera
|
|
cmd.SetRayTracingAccelerationStructure(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._RaytracingAccelerationStructureName, rtsdtParams.accelerationStructure);
|
|
|
|
// Make sure the right closest hit/any hit will be triggered by using the right multi compile
|
|
CoreUtils.SetKeyword(cmd, "TRANSPARENT_COLOR_SHADOW", rtsdtParams.colorShadow);
|
|
|
|
// Define which ray generation shaders we shall be using
|
|
string directionaLightShadowShader = rtsdtParams.colorShadow ? m_RayGenDirectionalColorShadowSingleName : m_RayGenDirectionalShadowSingleName;
|
|
|
|
// Loop through the samples of this frame
|
|
for (int sampleIdx = 0; sampleIdx < rtsdtParams.numShadowSamples; ++sampleIdx)
|
|
{
|
|
// Update global Constant Buffer
|
|
rtsdtParams.shaderVariablesRayTracingCB._RaytracingSampleIndex = sampleIdx;
|
|
rtsdtParams.shaderVariablesRayTracingCB._RaytracingNumSamples = rtsdtParams.numShadowSamples;
|
|
ConstantBuffer.PushGlobal(cmd, rtsdtParams.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing);
|
|
|
|
// Input Buffer
|
|
cmd.SetComputeTextureParam(rtsdtParams.screenSpaceShadowCS, rtsdtParams.directionalShadowSample, HDShaderIDs._DepthTexture, rtsdtResources.depthStencilBuffer);
|
|
cmd.SetComputeTextureParam(rtsdtParams.screenSpaceShadowCS, rtsdtParams.directionalShadowSample, HDShaderIDs._NormalBufferTexture, rtsdtResources.normalBuffer);
|
|
|
|
// Output buffer
|
|
cmd.SetComputeTextureParam(rtsdtParams.screenSpaceShadowCS, rtsdtParams.directionalShadowSample, HDShaderIDs._RaytracingDirectionBuffer, rtsdtResources.directionBuffer);
|
|
|
|
// Generate a new direction
|
|
cmd.DispatchCompute(rtsdtParams.screenSpaceShadowCS, rtsdtParams.directionalShadowSample, numTilesX, numTilesY, rtsdtParams.viewCount);
|
|
|
|
// Define the shader pass to use for the shadow pass
|
|
cmd.SetRayTracingShaderPass(rtsdtParams.screenSpaceShadowRT, "VisibilityDXR");
|
|
|
|
// Input Uniforms
|
|
cmd.SetRayTracingFloatParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._DirectionalMaxRayLength, rtsdtParams.maxShadowLength);
|
|
|
|
// Set ray count texture
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._RayCountTexture, rtsdtResources.rayCountTexture);
|
|
|
|
// Input buffers
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._DepthTexture, rtsdtResources.depthStencilBuffer);
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._NormalBufferTexture, rtsdtResources.normalBuffer);
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._RaytracingDirectionBuffer, rtsdtResources.directionBuffer);
|
|
|
|
// Output buffer
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, rtsdtParams.colorShadow ? HDShaderIDs._RaytracedColorShadowIntegration : HDShaderIDs._RaytracedShadowIntegration, rtsdtResources.outputShadowBuffer);
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._VelocityBuffer, rtsdtResources.velocityBuffer);
|
|
cmd.SetRayTracingTextureParam(rtsdtParams.screenSpaceShadowRT, HDShaderIDs._RaytracingDistanceBufferRW, rtsdtResources.distanceBuffer);
|
|
|
|
// Evaluate the visibility
|
|
cmd.DispatchRays(rtsdtParams.screenSpaceShadowRT, directionaLightShadowShader, (uint)rtsdtParams.texWidth, (uint)rtsdtParams.texHeight, (uint)rtsdtParams.viewCount);
|
|
}
|
|
|
|
// Now that we are done with the ray tracing bit, disable the multi compile that was potentially enabled
|
|
CoreUtils.SetKeyword(cmd, "TRANSPARENT_COLOR_SHADOW", false);
|
|
}
|
|
|
|
static float EvaluateHistoryValidityDirectionalShadow(HDCamera hdCamera, int dirShadowIndex, HDAdditionalLightData additionalLightData)
|
|
{
|
|
// We need to set the history as invalid if the directional light has rotated
|
|
float historyValidity = 1.0f;
|
|
if (additionalLightData.previousTransform.rotation != additionalLightData.transform.localToWorldMatrix.rotation
|
|
|| !hdCamera.ValidShadowHistory(additionalLightData, dirShadowIndex, GPULightType.Directional))
|
|
historyValidity = 0.0f;
|
|
|
|
#if UNITY_HDRP_DXR_TESTS_DEFINE
|
|
if (Application.isPlaying)
|
|
historyValidity = 0.0f;
|
|
else
|
|
#endif
|
|
// We need to check if something invalidated the history buffers
|
|
historyValidity *= EvaluateHistoryValidity(hdCamera);
|
|
|
|
return historyValidity;
|
|
}
|
|
|
|
struct SSShadowDirectionalParameters
|
|
{
|
|
public int depthSlice;
|
|
}
|
|
|
|
SSShadowDirectionalParameters PrepareSSShadowDirectionalParameters()
|
|
{
|
|
SSShadowDirectionalParameters sssdParams = new SSShadowDirectionalParameters();
|
|
sssdParams.depthSlice = m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex;
|
|
return sssdParams;
|
|
}
|
|
|
|
static void ExecuteSSShadowDirectional(CommandBuffer cmd, SSShadowDirectionalParameters sssdParams, MaterialPropertyBlock mpb, RTHandle normalBuffer, RTHandle textureArray)
|
|
{
|
|
// If it is screen space but not ray traced, then we can rely on the shadow map
|
|
// WARNING: This pattern only works because we can only have one directional and the directional shadow is evaluated first.
|
|
CoreUtils.SetRenderTarget(cmd, textureArray, depthSlice: sssdParams.depthSlice);
|
|
mpb.SetTexture(HDShaderIDs._NormalBufferTexture, normalBuffer);
|
|
HDUtils.DrawFullScreen(cmd, s_ScreenSpaceShadowsMat, textureArray, mpb);
|
|
}
|
|
}
|
|
}
|