You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

546 lines
28 KiB

using System;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
namespace UnityEngine.Rendering.HighDefinition
{
public partial class HDRenderPipeline
{
// String values (ray tracing gen shaders)
const string m_RayGenAreaShadowSingleName = "RayGenAreaShadowSingle";
const string m_RayGenDirectionalShadowSingleName = "RayGenDirectionalShadowSingle";
const string m_RayGenDirectionalColorShadowSingleName = "RayGenDirectionalColorShadowSingle";
const string m_RayGenShadowSegmentSingleName = "RayGenShadowSegmentSingle";
const string m_RayGenSemiTransparentShadowSegmentSingleName = "RayGenSemiTransparentShadowSegmentSingle";
// Shaders
RayTracingShader m_ScreenSpaceShadowsRT;
ComputeShader m_ScreenSpaceShadowsCS;
ComputeShader m_ScreenSpaceShadowsFilterCS;
// Kernels
// Shared shadow kernels
int m_ClearShadowTexture;
int m_OutputShadowTextureKernel;
int m_OutputColorShadowTextureKernel;
int m_OutputSpecularShadowTextureKernel;
// Directional shadow kernels
int m_RaytracingDirectionalShadowSample;
// Punctual shadow kernels
int m_RaytracingPointShadowSample;
int m_RaytracingSpotShadowSample;
int m_RaytracingProjectorPyramidShadowSample;
int m_RaytracingProjectorBoxShadowSample;
// Area shadow kernels
int m_AreaRaytracingShadowPrepassKernel;
int m_AreaRaytracingShadowNewSampleKernel;
int m_AreaShadowApplyTAAKernel;
int m_AreaUpdateAnalyticHistoryKernel;
int m_AreaUpdateShadowHistoryKernel;
int m_AreaEstimateNoiseKernel;
int m_AreaFirstDenoiseKernel;
int m_AreaSecondDenoiseKernel;
int m_AreaShadowNoDenoiseKernel;
int m_WriteShadowTextureDebugKernel;
// Temporary variables that allow us to read and write the right channels from the history buffer
Vector4 m_ShadowChannelMask0 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 m_ShadowChannelMask1 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
Vector4 m_ShadowChannelMask2 = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
// Screen space shadow material
static Material s_ScreenSpaceShadowsMat;
// This buffer holds the unfiltered, accumulated, shadow values, it is accessed with the same index as the one used at runtime (aka screen space shadow slot)
static RTHandle ShadowHistoryBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem)
{
HDRenderPipeline hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline;
HDRenderPipelineAsset hdPipelineAsset = hdrp.m_Asset;
int numShadowSlices = Math.Max((int)Math.Ceiling(hdPipelineAsset.currentPlatformRenderPipelineSettings.hdShadowInitParams.maxScreenSpaceShadowSlots / 4.0f), 1);
return rtHandleSystem.Alloc(Vector2.one, slices: numShadowSlices * TextureXR.slices, dimension: TextureDimension.Tex2DArray, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat,
enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: string.Format("{0}_ScreenSpaceShadowHistoryBuffer{1}", viewName, frameIndex));
}
// This value holds additional values that are required for the filtering process.
// For directional, punctual and spot light it holds the sample accumulation count and for the area light it holds the analytic value.
// It is accessed with the same index used at runtime (aka screen space shadow slot)
static RTHandle ShadowHistoryValidityBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem)
{
HDRenderPipeline hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline;
HDRenderPipelineAsset hdPipelineAsset = hdrp.m_Asset;
int numShadowSlices = Math.Max((int)Math.Ceiling(hdPipelineAsset.currentPlatformRenderPipelineSettings.hdShadowInitParams.maxScreenSpaceShadowSlots / 4.0f), 1);
return rtHandleSystem.Alloc(Vector2.one, slices: numShadowSlices * TextureXR.slices, dimension: TextureDimension.Tex2DArray, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat,
enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: string.Format("{0}_ShadowHistoryValidityBuffer{1}", viewName, frameIndex));
}
static RTHandle ShadowHistoryDistanceBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem)
{
HDRenderPipeline hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline;
HDRenderPipelineAsset hdPipelineAsset = hdrp.m_Asset;
int numShadowSlices = Math.Max((int)Math.Ceiling(hdPipelineAsset.currentPlatformRenderPipelineSettings.hdShadowInitParams.maxScreenSpaceShadowSlots / 4.0f), 1);
return rtHandleSystem.Alloc(Vector2.one, slices: numShadowSlices * TextureXR.slices, dimension: TextureDimension.Tex2DArray, filterMode: FilterMode.Point, colorFormat: GraphicsFormat.R16G16B16A16_SFloat,
enableRandomWrite: true, useDynamicScale: true, useMipMap: false, name: string.Format("{0}_ShadowHistoryDistanceBuffer{1}", viewName, frameIndex));
}
RTHandle RequestShadowHistoryBuffer(HDCamera hdCamera)
{
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadowHistory)
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadowHistory, ShadowHistoryBufferAllocatorFunction, 1);
}
RTHandle RequestShadowHistoryValidityBuffer(HDCamera hdCamera)
{
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadowHistoryValidity)
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadowHistoryValidity, ShadowHistoryValidityBufferAllocatorFunction, 1);
}
RTHandle RequestShadowHistoryDistanceBuffer(HDCamera hdCamera)
{
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedShadowDistanceValidity)
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedShadowDistanceValidity, ShadowHistoryDistanceBufferAllocatorFunction, 1);
}
// The three types of shadows that we currently support
enum ScreenSpaceShadowType
{
GrayScale,
Area,
Color
}
// This functions returns a mask that tells us for a given slot and based on the light type, which channels should hold the shadow information.
static void GetShadowChannelMask(int shadowSlot, ScreenSpaceShadowType shadowType, ref Vector4 outputMask)
{
int outputChannel = shadowSlot % 4;
if (shadowType == ScreenSpaceShadowType.GrayScale)
{
switch (outputChannel)
{
case 0:
{
outputMask.Set(1.0f, 0.0f, 0.0f, 0.0f);
break;
}
case 1:
{
outputMask.Set(0.0f, 1.0f, 0.0f, 0.0f);
break;
}
case 2:
{
outputMask.Set(0.0f, 0.0f, 1.0f, 0.0f);
break;
}
case 3:
{
outputMask.Set(0.0f, 0.0f, 0.0f, 1.0f);
break;
}
}
}
else if (shadowType == ScreenSpaceShadowType.Area)
{
switch (outputChannel)
{
case 0:
{
outputMask.Set(1.0f, 1.0f, 0.0f, 0.0f);
break;
}
case 1:
{
outputMask.Set(0.0f, 1.0f, 1.0f, 0.0f);
break;
}
case 2:
{
outputMask.Set(0.0f, 0.0f, 1.0f, 1.0f);
break;
}
default:
Debug.Assert(false);
break;
}
}
else if (shadowType == ScreenSpaceShadowType.Color)
{
switch (outputChannel)
{
case 0:
{
outputMask.Set(1.0f, 1.0f, 1.0f, 0.0f);
break;
}
default:
Debug.Assert(false);
break;
}
}
}
void InitializeScreenSpaceShadows()
{
if (!m_Asset.currentPlatformRenderPipelineSettings.hdShadowInitParams.supportScreenSpaceShadows)
return;
// Fetch the shaders
if (m_RayTracingSupported)
{
m_ScreenSpaceShadowsCS = rayTracingResources.shadowRayTracingCS;
m_ScreenSpaceShadowsFilterCS = rayTracingResources.shadowFilterCS;
m_ScreenSpaceShadowsRT = rayTracingResources.shadowRayTracingRT;
// Directional shadow kernels
m_ClearShadowTexture = m_ScreenSpaceShadowsCS.FindKernel("ClearShadowTexture");
m_OutputShadowTextureKernel = m_ScreenSpaceShadowsCS.FindKernel("OutputShadowTexture");
m_OutputColorShadowTextureKernel = m_ScreenSpaceShadowsCS.FindKernel("OutputColorShadowTexture");
m_OutputSpecularShadowTextureKernel = m_ScreenSpaceShadowsCS.FindKernel("OutputSpecularShadowTexture");
m_RaytracingDirectionalShadowSample = m_ScreenSpaceShadowsCS.FindKernel("RaytracingDirectionalShadowSample");
m_RaytracingPointShadowSample = m_ScreenSpaceShadowsCS.FindKernel("RaytracingPointShadowSample");
m_RaytracingSpotShadowSample = m_ScreenSpaceShadowsCS.FindKernel("RaytracingSpotShadowSample");
m_RaytracingProjectorPyramidShadowSample = m_ScreenSpaceShadowsCS.FindKernel("RaytracingProjectorPyramidShadowSample");
m_RaytracingProjectorBoxShadowSample = m_ScreenSpaceShadowsCS.FindKernel("RaytracingProjectorBoxShadowSample");
// Area shadow kernels
m_AreaRaytracingShadowPrepassKernel = m_ScreenSpaceShadowsCS.FindKernel("RaytracingAreaShadowPrepass");
m_AreaRaytracingShadowNewSampleKernel = m_ScreenSpaceShadowsCS.FindKernel("RaytracingAreaShadowNewSample");
m_AreaShadowApplyTAAKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaShadowApplyTAA");
m_AreaUpdateAnalyticHistoryKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaAnalyticHistoryCopy");
m_AreaUpdateShadowHistoryKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaShadowHistoryCopy");
m_AreaEstimateNoiseKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaShadowEstimateNoise");
m_AreaFirstDenoiseKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaShadowDenoiseFirstPass");
m_AreaSecondDenoiseKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaShadowDenoiseSecondPass");
m_AreaShadowNoDenoiseKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("AreaShadowNoDenoise");
// Debug kernel
m_WriteShadowTextureDebugKernel = m_ScreenSpaceShadowsFilterCS.FindKernel("WriteShadowTextureDebug");
}
// Directional shadow material
s_ScreenSpaceShadowsMat = CoreUtils.CreateEngineMaterial(screenSpaceShadowsShader);
switch (m_Asset.currentPlatformRenderPipelineSettings.hdShadowInitParams.punctualShadowFilteringQuality)
{
case HDShadowFilteringQuality.Low:
s_ScreenSpaceShadowsMat.EnableKeyword("PUNCTUAL_SHADOW_LOW");
break;
case HDShadowFilteringQuality.Medium:
s_ScreenSpaceShadowsMat.EnableKeyword("PUNCTUAL_SHADOW_MEDIUM");
break;
case HDShadowFilteringQuality.High:
s_ScreenSpaceShadowsMat.EnableKeyword("PUNCTUAL_SHADOW_HIGH");
break;
default:
s_ScreenSpaceShadowsMat.EnableKeyword("PUNCTUAL_SHADOW_MEDIUM");
break;
}
switch (m_Asset.currentPlatformRenderPipelineSettings.hdShadowInitParams.directionalShadowFilteringQuality)
{
case HDShadowFilteringQuality.Low:
s_ScreenSpaceShadowsMat.EnableKeyword("DIRECTIONAL_SHADOW_LOW");
break;
case HDShadowFilteringQuality.Medium:
s_ScreenSpaceShadowsMat.EnableKeyword("DIRECTIONAL_SHADOW_MEDIUM");
break;
case HDShadowFilteringQuality.High:
s_ScreenSpaceShadowsMat.EnableKeyword("DIRECTIONAL_SHADOW_HIGH");
break;
default:
s_ScreenSpaceShadowsMat.EnableKeyword("DIRECTIONAL_SHADOW_MEDIUM");
break;
}
switch (m_Asset.currentPlatformRenderPipelineSettings.hdShadowInitParams.areaShadowFilteringQuality)
{
case HDAreaShadowFilteringQuality.Medium:
s_ScreenSpaceShadowsMat.EnableKeyword("AREA_SHADOW_MEDIUM");
break;
case HDAreaShadowFilteringQuality.High:
s_ScreenSpaceShadowsMat.EnableKeyword("AREA_SHADOW_HIGH");
break;
default:
s_ScreenSpaceShadowsMat.EnableKeyword("AREA_SHADOW_MEDIUM");
break;
}
}
void ReleaseScreenSpaceShadows()
{
CoreUtils.Destroy(s_ScreenSpaceShadowsMat);
}
internal TextureHandle CreateScreenSpaceShadowTextureArray(RenderGraph renderGraph)
{
int numShadowTextures = Math.Max((int)Math.Ceiling(m_Asset.currentPlatformRenderPipelineSettings.hdShadowInitParams.maxScreenSpaceShadowSlots / 4.0f), 1);
GraphicsFormat graphicsFormat = (GraphicsFormat)m_Asset.currentPlatformRenderPipelineSettings.hdShadowInitParams.screenSpaceShadowBufferFormat;
return renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
{
format = graphicsFormat,
slices = numShadowTextures * TextureXR.slices,
dimension = TextureDimension.Tex2DArray,
filterMode = FilterMode.Point,
enableRandomWrite = true,
useMipMap = false,
name = "ScreenSpaceShadowArrayBuffer"
});
}
class ScreenSpaceShadowDebugPassData
{
// Camera parameters
public int texWidth;
public int texHeight;
public int viewCount;
// Evaluation parameters
public int targetShadow;
// Kernel
public int debugKernel;
// Other parameters
public ComputeShader shadowFilter;
public TextureHandle screenSpaceShadowArray;
public TextureHandle outputBuffer;
}
TextureHandle EvaluateShadowDebugView(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle screenSpaceShadowArray)
{
// If this is the right debug mode and the index we are asking for is in the range
if (!rayTracingSupported || (m_ScreenSpaceShadowChannelSlot <= m_CurrentDebugDisplaySettings.data.screenSpaceShadowIndex))
return m_RenderGraph.defaultResources.blackTextureXR;
using (var builder = renderGraph.AddUnsafePass<ScreenSpaceShadowDebugPassData>("Screen Space Shadows Debug", out var passData, ProfilingSampler.Get(HDProfileId.ScreenSpaceShadowsDebug)))
{
passData.texWidth = hdCamera.actualWidth;
passData.texHeight = hdCamera.actualHeight;
passData.viewCount = hdCamera.viewCount;
// Evaluation params
passData.targetShadow = (int)m_CurrentDebugDisplaySettings.data.screenSpaceShadowIndex;
// Kernel to be used
passData.debugKernel = m_WriteShadowTextureDebugKernel;
// TODO: move the debug kernel outside of the ray tracing resources
passData.shadowFilter = rayTracingResources.shadowFilterCS;
passData.screenSpaceShadowArray = screenSpaceShadowArray;
builder.UseTexture(passData.screenSpaceShadowArray, AccessFlags.Read);
passData.outputBuffer = renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "EvaluateShadowDebug" });
builder.UseTexture(passData.outputBuffer, AccessFlags.Write);
builder.SetRenderFunc(
(ScreenSpaceShadowDebugPassData data, UnsafeGraphContext ctx) =>
{
var natCmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd);
// Evaluate the dispatch parameters
int shadowTileSize = 8;
int numTilesX = (data.texWidth + (shadowTileSize - 1)) / shadowTileSize;
int numTilesY = (data.texHeight + (shadowTileSize - 1)) / shadowTileSize;
// If the screen space shadows we are asked to deliver is available output it to the intermediate texture
natCmd.SetComputeIntParam(data.shadowFilter, HDShaderIDs._DenoisingHistorySlot, data.targetShadow);
natCmd.SetComputeTextureParam(data.shadowFilter, data.debugKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, data.screenSpaceShadowArray);
natCmd.SetComputeTextureParam(data.shadowFilter, data.debugKernel, HDShaderIDs._DenoiseOutputTextureRW, data.outputBuffer);
natCmd.DispatchCompute(data.shadowFilter, data.debugKernel, numTilesX, numTilesY, data.viewCount);
});
return passData.outputBuffer;
}
}
class WriteScreenSpaceShadowPassData
{
// Camera parameters
public int texWidth;
public int texHeight;
public int viewCount;
// Evaluation parameters
public Vector4 shadowChannelMask;
public Vector4 shadowChannelMask0;
public Vector4 shadowChannelMask1;
public int shadowSlot;
// Kernel
public int shadowKernel;
// Other parameters
public ComputeShader screenSpaceShadowCS;
public TextureHandle inputShadowBuffer;
public TextureHandle outputShadowArrayBuffer;
}
void WriteScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle shadowTexture, TextureHandle screenSpaceShadowArray, int shadowIndex, ScreenSpaceShadowType shadowType)
{
// Write the result texture to the screen space shadow buffer
using (var builder = renderGraph.AddUnsafePass<WriteScreenSpaceShadowPassData>("Write Screen Space Shadows", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingWriteShadow)))
{
passData.texWidth = hdCamera.actualWidth;
passData.texHeight = hdCamera.actualHeight;
passData.viewCount = hdCamera.viewCount;
// Evaluation parameters
GetShadowChannelMask(shadowIndex, shadowType, ref passData.shadowChannelMask);
// If the light is an area, we also need to grab the individual channels
if (shadowType == ScreenSpaceShadowType.Area)
{
GetShadowChannelMask(shadowIndex, ScreenSpaceShadowType.GrayScale, ref passData.shadowChannelMask0);
GetShadowChannelMask(shadowIndex + 1, ScreenSpaceShadowType.GrayScale, ref passData.shadowChannelMask1);
}
passData.shadowSlot = shadowIndex;
// Kernel
switch (shadowType)
{
case ScreenSpaceShadowType.GrayScale:
{
passData.shadowKernel = m_OutputShadowTextureKernel;
}
break;
case ScreenSpaceShadowType.Area:
{
passData.shadowKernel = m_OutputSpecularShadowTextureKernel;
}
break;
case ScreenSpaceShadowType.Color:
{
passData.shadowKernel = m_OutputColorShadowTextureKernel;
}
break;
}
// Other parameters
passData.screenSpaceShadowCS = m_ScreenSpaceShadowsCS;
passData.inputShadowBuffer = shadowTexture;
builder.UseTexture(passData.inputShadowBuffer, AccessFlags.Read);
passData.outputShadowArrayBuffer = screenSpaceShadowArray;
builder.UseTexture(passData.outputShadowArrayBuffer, AccessFlags.ReadWrite);
builder.SetRenderFunc(
(WriteScreenSpaceShadowPassData data, UnsafeGraphContext ctx) =>
{
var natCmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd);
// Evaluate the dispatch parameters
int shadowTileSize = 8;
int numTilesX = (data.texWidth + (shadowTileSize - 1)) / shadowTileSize;
int numTilesY = (data.texHeight + (shadowTileSize - 1)) / shadowTileSize;
// Bind the input data
natCmd.SetComputeIntParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingShadowSlot, data.shadowSlot / 4);
natCmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask, data.shadowChannelMask);
natCmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask0, data.shadowChannelMask0);
natCmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask1, data.shadowChannelMask1);
natCmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.shadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.inputShadowBuffer);
// Bind the output texture
natCmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.shadowKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, data.outputShadowArrayBuffer);
//Do our copy
natCmd.DispatchCompute(data.screenSpaceShadowCS, data.shadowKernel, numTilesX, numTilesY, data.viewCount);
});
}
}
bool RenderLightScreenSpaceShadows(RenderGraph renderGraph, HDCamera hdCamera,
PrepassOutput prepassOutput, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, TextureHandle historyValidityBuffer,
TextureHandle rayCountTexture, TextureHandle screenSpaceShadowArray)
{
// Loop through all the potential screen space light shadows
for (int lightIdx = 0; lightIdx < m_ScreenSpaceShadowIndex; ++lightIdx)
{
// This matches the directional light
if (!m_CurrentScreenSpaceShadowData[lightIdx].valid) continue;
// Fetch the light data and additional light data
LightData currentLight = m_GpuLightsBuilder.lights[m_CurrentScreenSpaceShadowData[lightIdx].lightDataIndex];
HDAdditionalLightData currentAdditionalLightData = m_CurrentScreenSpaceShadowData[lightIdx].additionalLightData;
// Trigger the right algorithm based on the light type
switch (currentLight.lightType)
{
case GPULightType.Rectangle:
{
RenderAreaScreenSpaceShadow(renderGraph, hdCamera, currentLight, currentAdditionalLightData, m_CurrentScreenSpaceShadowData[lightIdx].lightDataIndex,
prepassOutput, depthBuffer, normalBuffer, motionVectorsBuffer, rayCountTexture, screenSpaceShadowArray);
}
break;
case GPULightType.Point:
case GPULightType.Spot:
case GPULightType.ProjectorPyramid:
case GPULightType.ProjectorBox:
{
RenderPunctualScreenSpaceShadow(renderGraph, hdCamera, currentLight, currentAdditionalLightData, m_CurrentScreenSpaceShadowData[lightIdx].lightDataIndex,
prepassOutput, depthBuffer, normalBuffer, motionVectorsBuffer, historyValidityBuffer, rayCountTexture, screenSpaceShadowArray);
}
break;
}
}
return true;
}
bool RequestedScreenSpaceShadows()
{
// We have screen space shadows that needs to be evaluated if we have one of these:
// - A screen space directional shadow
// - A ray traced directional shadow
bool screenSpaceShadowDirectionalRequired = m_CurrentSunLightAdditionalLightData != null && (m_CurrentSunShadowMapFlags & HDProcessedVisibleLightsBuilder.ShadowMapFlags.WillRenderScreenSpaceShadow) != 0;
// - A ray traced spot or point shadow
// - A ray traced area light shadow
bool pointOrAreaLightShadowRequired = false;
for (int lightIdx = 0; lightIdx < m_ScreenSpaceShadowIndex; ++lightIdx)
{
// This matches the directional light
if (!m_CurrentScreenSpaceShadowData[lightIdx].valid) continue;
pointOrAreaLightShadowRequired = true;
break;
}
return screenSpaceShadowDirectionalRequired || pointOrAreaLightShadowRequired;
}
TextureHandle RenderScreenSpaceShadows(RenderGraph renderGraph, HDCamera hdCamera,
PrepassOutput prepassOutput, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVectorsBuffer, TextureHandle historyValidityBuffer, TextureHandle rayCountTexture)
{
// If screen space shadows are not supported for this camera, we are done
bool validConditions = hdCamera.frameSettings.IsEnabled(FrameSettingsField.ScreenSpaceShadows) && RequestedScreenSpaceShadows();
if (!validConditions)
{
// We push the debug texture anyway if we are not evaluating any screen space shadows.
PushFullScreenDebugTexture(m_RenderGraph, m_RenderGraph.defaultResources.whiteTextureXR, FullScreenDebugMode.ScreenSpaceShadows);
return m_RenderGraph.defaultResources.blackTextureArrayXR;
}
using (new RenderGraphProfilingScope(renderGraph, ProfilingSampler.Get(HDProfileId.ScreenSpaceShadows)))
{
// Request the output texture
TextureHandle screenSpaceShadowTexture = CreateScreenSpaceShadowTextureArray(renderGraph);
// First of all we handle the directional light
RenderDirectionalLightScreenSpaceShadow(renderGraph, hdCamera, depthBuffer, normalBuffer, motionVectorsBuffer, historyValidityBuffer, rayCountTexture, screenSpaceShadowTexture);
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && GetRayTracingState())
{
// We handle the other light sources
RenderLightScreenSpaceShadows(renderGraph, hdCamera, prepassOutput, depthBuffer, normalBuffer, motionVectorsBuffer, historyValidityBuffer, rayCountTexture, screenSpaceShadowTexture);
}
// We render the debug view, if the texture is not used, it is not evaluated anyway
TextureHandle screenSpaceShadowDebug = EvaluateShadowDebugView(renderGraph, hdCamera, screenSpaceShadowTexture);
PushFullScreenDebugTexture(m_RenderGraph, screenSpaceShadowDebug, FullScreenDebugMode.ScreenSpaceShadows);
return screenSpaceShadowTexture;
}
}
}
}