Example #1
0
        // 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;
                }
            }
        }
Example #2
0
        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.AddRenderPass <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       = builder.ReadTexture(shadowTexture);
                passData.outputShadowArrayBuffer = builder.ReadWriteTexture(screenSpaceShadowArray);

                builder.SetRenderFunc(
                    (WriteScreenSpaceShadowPassData data, RenderGraphContext ctx) =>
                {
                    // 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
                    ctx.cmd.SetComputeIntParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingShadowSlot, data.shadowSlot / 4);
                    ctx.cmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask, data.shadowChannelMask);
                    ctx.cmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask0, data.shadowChannelMask0);
                    ctx.cmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask1, data.shadowChannelMask1);
                    ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.shadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.inputShadowBuffer);

                    // Bind the output texture
                    ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.shadowKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, data.outputShadowArrayBuffer);

                    //Do our copy
                    ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.shadowKernel, numTilesX, numTilesY, data.viewCount);
                });
            }
        }
Example #3
0
        void RenderRayTracedDirectionalScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVetorsBuffer, TextureHandle rayCountTexture, TextureHandle screenSpaceShadowArray)
        {
            TextureHandle directionalShadow;
            TextureHandle velocityBuffer;
            TextureHandle distanceBuffer;
            RTShadowDirectionalTraceParameters rtsdtParams = PrepareRTShadowDirectionalTraceParameters(hdCamera, m_CurrentSunLightAdditionalLightData);

            using (var builder = renderGraph.AddRenderPass <RTSDirectionalTracePassData>("Directional RT Shadow", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingDirectionalLightShadow)))
            {
                passData.parameters = rtsdtParams;

                // Input Buffer
                passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read);
                passData.normalBuffer       = builder.ReadTexture(normalBuffer);
                passData.directionBuffer    = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Direction Buffer"
                });

                // Debug buffers
                passData.rayCountTexture = builder.ReadTexture(builder.WriteTexture(rayCountTexture));

                // Output Buffers
                passData.velocityBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R8_SNorm, enableRandomWrite = true, clearBuffer = true, name = "Velocity Buffer"
                })));
                passData.distanceBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, clearBuffer = true, name = "Distance Buffer"
                })));
                passData.outputShadowBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, clearBuffer = true, name = "RT Directional Shadow"
                })));

                builder.SetRenderFunc(
                    (RTSDirectionalTracePassData data, RenderGraphContext context) =>
                {
                    RTShadowDirectionalTraceResources resources = new RTShadowDirectionalTraceResources();
                    resources.depthStencilBuffer = data.depthStencilBuffer;
                    resources.normalBuffer       = data.normalBuffer;
                    resources.directionBuffer    = data.directionBuffer;
                    resources.rayCountTexture    = data.rayCountTexture;
                    resources.velocityBuffer     = data.velocityBuffer;
                    resources.distanceBuffer     = data.distanceBuffer;
                    resources.outputShadowBuffer = data.outputShadowBuffer;
                    ExecuteSSSDirectionalTrace(context.cmd, data.parameters, resources);
                });
                directionalShadow = passData.outputShadowBuffer;
                velocityBuffer    = passData.velocityBuffer;
                distanceBuffer    = passData.distanceBuffer;
            }

            // If required, denoise the shadow
            if (m_CurrentSunLightAdditionalLightData.filterTracedShadow && rtsdtParams.softShadow)
            {
                directionalShadow = DenoiseDirectionalScreenSpaceShadow(renderGraph, hdCamera,
                                                                        depthBuffer, normalBuffer, motionVetorsBuffer,
                                                                        directionalShadow, velocityBuffer, distanceBuffer);
            }

            int dirShadowIndex = m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex & (int)LightDefinitions.s_ScreenSpaceShadowIndexMask;
            ScreenSpaceShadowType shadowType = m_CurrentSunLightAdditionalLightData.colorShadow? ScreenSpaceShadowType.Color: ScreenSpaceShadowType.GrayScale;

            // Write the result texture to the screen space shadow buffer
            WriteScreenSpaceShadow(renderGraph, hdCamera, directionalShadow, screenSpaceShadowArray, dirShadowIndex, shadowType);
        }
Example #4
0
        WriteScreenSpaceShadowParameters PrepareWriteScreenSpaceShadowParameters(HDCamera hdCamera, int shadowSlot, ScreenSpaceShadowType shadowType)
        {
            WriteScreenSpaceShadowParameters wsssParams = new WriteScreenSpaceShadowParameters();

            // Set the camera parameters
            wsssParams.texWidth  = hdCamera.actualWidth;
            wsssParams.texHeight = hdCamera.actualHeight;
            wsssParams.viewCount = hdCamera.viewCount;

            // Evaluation parameters
            GetShadowChannelMask(shadowSlot, shadowType, ref wsssParams.shadowChannelMask);
            // If the light is an area, we also need to grab the individual channels
            if (shadowType == ScreenSpaceShadowType.Area)
            {
                GetShadowChannelMask(shadowSlot, ScreenSpaceShadowType.GrayScale, ref wsssParams.shadowChannelMask0);
                GetShadowChannelMask(shadowSlot + 1, ScreenSpaceShadowType.GrayScale, ref wsssParams.shadowChannelMask1);
            }
            wsssParams.shadowSlot = shadowSlot;

            // Kernel
            switch (shadowType)
            {
            case ScreenSpaceShadowType.GrayScale:
            {
                wsssParams.shadowKernel = m_OutputShadowTextureKernel;
            }
            break;

            case ScreenSpaceShadowType.Area:
            {
                wsssParams.shadowKernel = m_OutputSpecularShadowTextureKernel;
            }
            break;

            case ScreenSpaceShadowType.Color:
            {
                wsssParams.shadowKernel = m_OutputColorShadowTextureKernel;
            }
            break;
            }

            // Other parameters
            wsssParams.screenSpaceShadowCS = m_ScreenSpaceShadowsCS;

            return(wsssParams);
        }
        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.AddRenderPass <WriteScreenSpaceShadowPassData>("Write Screen Space Shadows", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingWriteShadow)))
            {
                passData.parameters              = PrepareWriteScreenSpaceShadowParameters(hdCamera, shadowIndex, shadowType);
                passData.inputShadowBuffer       = builder.ReadTexture(shadowTexture);
                passData.outputShadowArrayBuffer = builder.WriteTexture(builder.ReadTexture(screenSpaceShadowArray));

                builder.SetRenderFunc(
                    (WriteScreenSpaceShadowPassData data, RenderGraphContext context) =>
                {
                    WriteScreenSpaceShadowResources resources = new WriteScreenSpaceShadowResources();
                    resources.inputShadowBuffer       = data.inputShadowBuffer;
                    resources.outputShadowArrayBuffer = data.outputShadowArrayBuffer;
                    ExecuteWriteScreenSpaceShadow(context.cmd, data.parameters, resources);
                });
            }
        }
Example #6
0
        WriteScreenSpaceShadowParameters PrepareWriteScreenSpaceShadowParameters(HDCamera hdCamera, int shadowSlot, ScreenSpaceShadowType shadowType)
        {
            WriteScreenSpaceShadowParameters wsssParams = new WriteScreenSpaceShadowParameters();

            // Set the camera parameters
            wsssParams.texWidth  = hdCamera.actualWidth;
            wsssParams.texHeight = hdCamera.actualHeight;
            wsssParams.viewCount = hdCamera.viewCount;

            // Evaluation parameters
            GetShadowChannelMask(shadowSlot, shadowType, ref wsssParams.shadowChannelMask);
            wsssParams.shadowSlot = shadowSlot;

            // Kernel
            wsssParams.shadowKernel = (shadowType == ScreenSpaceShadowType.Color ? m_OutputColorShadowTextureKernel : m_OutputShadowTextureKernel);

            // Other parameters
            wsssParams.screenSpaceShadowCS = m_ScreenSpaceShadowsCS;

            return(wsssParams);
        }
        void RenderRayTracedDirectionalScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera,
                                                         TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVetorsBuffer, TextureHandle historyValidityBuffer,
                                                         TextureHandle rayCountTexture, TextureHandle screenSpaceShadowArray)
        {
            TextureHandle directionalShadow;
            TextureHandle velocityBuffer;
            TextureHandle distanceBuffer;

            bool softShadows = m_CurrentSunLightAdditionalLightData.angularDiameter > 0.0 ? true : false;

            using (var builder = renderGraph.AddRenderPass <RTSDirectionalTracePassData>("Directional RT Shadow", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingDirectionalLightShadow)))
            {
                RayTracingSettings rayTracingSettings = hdCamera.volumeStack.GetComponent <RayTracingSettings>();

                // Set the camera parameters
                passData.texWidth  = hdCamera.actualWidth;
                passData.texHeight = hdCamera.actualHeight;
                passData.viewCount = hdCamera.viewCount;

                // Evaluation parameters
                passData.softShadow = softShadows;
                // If the surface is infinitively small, we force it to one sample.
                passData.numShadowSamples = passData.softShadow ? m_CurrentSunLightAdditionalLightData.numRayTracingSamples : 1;
                passData.colorShadow      = m_CurrentSunLightAdditionalLightData.colorShadow;
                passData.maxShadowLength  = rayTracingSettings.directionalShadowRayLength.value;

                // Kernels
                passData.clearShadowKernel       = m_ClearShadowTexture;
                passData.directionalShadowSample = m_RaytracingDirectionalShadowSample;

                // Grab the acceleration structure for the target camera
                passData.accelerationStructure       = RequestAccelerationStructure(hdCamera);
                passData.screenSpaceShadowCS         = m_ScreenSpaceShadowsCS;
                passData.screenSpaceShadowRT         = m_ScreenSpaceShadowsRT;
                passData.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB;
                passData.ditheredTextureSet          = GetBlueNoiseManager().DitheredTextureSet8SPP();

                // Input Buffer
                passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read);
                passData.normalBuffer       = builder.ReadTexture(normalBuffer);
                passData.directionBuffer    = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Direction Buffer"
                });

                // Debug buffers
                passData.rayCountTexture = builder.ReadWriteTexture(rayCountTexture);

                // Output Buffers
                passData.velocityBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R8_SNorm, enableRandomWrite = true, clearBuffer = true, name = "Velocity Buffer"
                }));
                passData.distanceBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, clearBuffer = true, name = "Distance Buffer"
                }));
                passData.outputShadowBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, clearBuffer = true, name = "RT Directional Shadow"
                }));

                builder.SetRenderFunc(
                    (RTSDirectionalTracePassData data, RenderGraphContext ctx) =>
                {
                    // Inject the ray-tracing sampling data
                    BlueNoise.BindDitheredTextureSet(ctx.cmd, data.ditheredTextureSet);

                    // Evaluate the dispatch parameters
                    int shadowTileSize = 8;
                    int numTilesX      = (data.texWidth + (shadowTileSize - 1)) / shadowTileSize;
                    int numTilesY      = (data.texHeight + (shadowTileSize - 1)) / shadowTileSize;

                    // Clear the integration texture
                    ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.outputShadowBuffer);
                    ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.clearShadowKernel, numTilesX, numTilesY, data.viewCount);

                    ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.velocityBuffer);
                    ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.clearShadowKernel, numTilesX, numTilesY, data.viewCount);

                    ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.distanceBuffer);
                    ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.clearShadowKernel, numTilesX, numTilesY, data.viewCount);

                    // Grab and bind the acceleration structure for the target camera
                    ctx.cmd.SetRayTracingAccelerationStructure(data.screenSpaceShadowRT, HDShaderIDs._RaytracingAccelerationStructureName, data.accelerationStructure);

                    // Make sure the right closest hit/any hit will be triggered by using the right multi compile
                    CoreUtils.SetKeyword(ctx.cmd, "TRANSPARENT_COLOR_SHADOW", data.colorShadow);

                    // Define which ray generation shaders we shall be using
                    string directionaLightShadowShader = data.colorShadow ? m_RayGenDirectionalColorShadowSingleName : m_RayGenDirectionalShadowSingleName;

                    // Loop through the samples of this frame
                    for (int sampleIdx = 0; sampleIdx < data.numShadowSamples; ++sampleIdx)
                    {
                        // Update global Constant Buffer
                        data.shaderVariablesRayTracingCB._RaytracingSampleIndex = sampleIdx;
                        data.shaderVariablesRayTracingCB._RaytracingNumSamples  = data.numShadowSamples;
                        ConstantBuffer.PushGlobal(ctx.cmd, data.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing);

                        // Input Buffer
                        ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.directionalShadowSample, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
                        ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.directionalShadowSample, HDShaderIDs._NormalBufferTexture, data.normalBuffer);

                        // Output buffer
                        ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.directionalShadowSample, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer);

                        // Generate a new direction
                        ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.directionalShadowSample, numTilesX, numTilesY, data.viewCount);

                        // Define the shader pass to use for the shadow pass
                        ctx.cmd.SetRayTracingShaderPass(data.screenSpaceShadowRT, "VisibilityDXR");

                        // Input Uniforms
                        ctx.cmd.SetRayTracingFloatParam(data.screenSpaceShadowRT, HDShaderIDs._DirectionalMaxRayLength, data.maxShadowLength);

                        // Set ray count texture
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._RayCountTexture, data.rayCountTexture);

                        // Input buffers
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer);

                        // Output buffer
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, data.colorShadow ? HDShaderIDs._RaytracedColorShadowIntegration : HDShaderIDs._RaytracedShadowIntegration, data.outputShadowBuffer);
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._VelocityBuffer, data.velocityBuffer);
                        ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._RaytracingDistanceBufferRW, data.distanceBuffer);

                        // Evaluate the visibility
                        ctx.cmd.DispatchRays(data.screenSpaceShadowRT, directionaLightShadowShader, (uint)data.texWidth, (uint)data.texHeight, (uint)data.viewCount);
                    }

                    // Now that we are done with the ray tracing bit, disable the multi compile that was potentially enabled
                    CoreUtils.SetKeyword(ctx.cmd, "TRANSPARENT_COLOR_SHADOW", false);
                });

                directionalShadow = passData.outputShadowBuffer;
                velocityBuffer    = passData.velocityBuffer;
                distanceBuffer    = passData.distanceBuffer;
            }

            // If required, denoise the shadow
            if (m_CurrentSunLightAdditionalLightData.filterTracedShadow && softShadows)
            {
                directionalShadow = DenoiseDirectionalScreenSpaceShadow(renderGraph, hdCamera,
                                                                        depthBuffer, normalBuffer, motionVetorsBuffer, historyValidityBuffer,
                                                                        directionalShadow, velocityBuffer, distanceBuffer);
            }

            int dirShadowIndex = m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex & (int)LightDefinitions.s_ScreenSpaceShadowIndexMask;
            ScreenSpaceShadowType shadowType = m_CurrentSunLightAdditionalLightData.colorShadow ? ScreenSpaceShadowType.Color : ScreenSpaceShadowType.GrayScale;

            // Write the result texture to the screen space shadow buffer
            WriteScreenSpaceShadow(renderGraph, hdCamera, directionalShadow, screenSpaceShadowArray, dirShadowIndex, shadowType);
        }