internal void InitializeForRendering(RenderGraph renderGraph) { blackTexture = renderGraph.ImportTexture(m_BlackTexture2D); whiteTexture = renderGraph.ImportTexture(m_WhiteTexture2D); clearTextureXR = renderGraph.ImportTexture(TextureXR.GetClearTexture()); magentaTextureXR = renderGraph.ImportTexture(TextureXR.GetMagentaTexture()); blackTextureXR = renderGraph.ImportTexture(TextureXR.GetBlackTexture()); blackTextureArrayXR = renderGraph.ImportTexture(TextureXR.GetBlackTextureArray()); blackUIntTextureXR = renderGraph.ImportTexture(TextureXR.GetBlackUIntTexture()); blackTexture3DXR = renderGraph.ImportTexture(TextureXR.GetBlackTexture3D()); whiteTextureXR = renderGraph.ImportTexture(TextureXR.GetWhiteTexture()); }
public override void BindBufferAsTextures(CommandBuffer cmd) { for (int i = 0; i < m_BufferCount; ++i) { cmd.SetGlobalTexture(m_TextureShaderIDs[i], m_RTs[i]); } // Bind alias for gbuffer usage to simplify shader code (not need to check which gbuffer is the shadowmask or lightlayers) if (m_ShadowMaskIndex >= 0) { cmd.SetGlobalTexture(HDShaderIDs._ShadowMaskTexture, m_RTs[m_ShadowMaskIndex]); } if (m_LightLayers >= 0) { cmd.SetGlobalTexture(HDShaderIDs._LightLayersTexture, m_RTs[m_LightLayers]); } else { cmd.SetGlobalTexture(HDShaderIDs._LightLayersTexture, TextureXR.GetWhiteTexture()); // This is never use but need to be bind as the read is inside a if } }
public void Render(RenderGraph renderGraph, HDCamera hdCamera, BlueNoise blueNoise, TextureHandle colorBuffer, TextureHandle afterPostProcessTexture, TextureHandle depthBuffer, TextureHandle finalRT, bool flipY) { var dynResHandler = DynamicResolutionHandler.instance; bool isSceneView = hdCamera.camera.cameraType == CameraType.SceneView; // TODO: Implement TextureHandle alphaTexture = new TextureHandle(); //// Save the alpha and apply it back into the final pass if working in fp16 //if (m_KeepAlpha) //{ // using (new ProfilingSample(cmd, "Alpha Copy", CustomSamplerId.AlphaCopy.GetSampler())) // { // DoCopyAlpha(cmd, hdCamera, colorBuffer); // } //} var source = colorBuffer; //if (m_PostProcessEnabled) //{ // Guard bands (also known as "horrible hack") to avoid bleeding previous RTHandle // content into smaller viewports with some effects like Bloom that rely on bilinear // filtering and can't use clamp sampler and the likes // Note: some platforms can't clear a partial render target so we directly draw black triangles //{ // int w = hdCamera.actualWidth; // int h = hdCamera.actualHeight; // cmd.SetRenderTarget(source, 0, CubemapFace.Unknown, -1); // if (w < source.rt.width || h < source.rt.height) // { // cmd.SetViewport(new Rect(w, 0, k_RTGuardBandSize, h)); // cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1); // cmd.SetViewport(new Rect(0, h, w + k_RTGuardBandSize, k_RTGuardBandSize)); // cmd.DrawProcedural(Matrix4x4.identity, m_ClearBlackMaterial, 0, MeshTopology.Triangles, 3, 1); // } //} // // Optional NaN killer before post-processing kicks in // bool stopNaNs = hdCamera.stopNaNs && m_StopNaNFS; //#if UNITY_EDITOR // if (isSceneView) // stopNaNs = HDRenderPipelinePreferences.sceneViewStopNaNs; //#endif // if (stopNaNs) // { // using (new ProfilingSample(cmd, "Stop NaNs", CustomSamplerId.StopNaNs.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoStopNaNs(cmd, hdCamera, source, destination); // PoolSource(ref source, destination); // } // } //} //// Dynamic exposure - will be applied in the next frame //// Not considered as a post-process so it's not affected by its enabled state //if (!IsExposureFixed() && m_ExposureControlFS) //{ // using (new ProfilingSample(cmd, "Dynamic Exposure", CustomSamplerId.Exposure.GetSampler())) // { // DoDynamicExposure(cmd, hdCamera, source); // } //} //if (m_PostProcessEnabled) //{ // // Temporal anti-aliasing goes first // bool taaEnabled = false; // if (m_AntialiasingFS) // { // taaEnabled = hdCamera.antialiasing == AntialiasingMode.TemporalAntialiasing; // if (taaEnabled) // { // using (new ProfilingSample(cmd, "Temporal Anti-aliasing", CustomSamplerId.TemporalAntialiasing.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoTemporalAntialiasing(cmd, hdCamera, source, destination, depthBuffer); // PoolSource(ref source, destination); // } // } // else if (hdCamera.antialiasing == AntialiasingMode.SubpixelMorphologicalAntiAliasing) // { // using (new ProfilingSample(cmd, "SMAA", CustomSamplerId.SMAA.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoSMAA(cmd, hdCamera, source, destination, depthBuffer); // PoolSource(ref source, destination); // } // } // } // if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.CustomPostProcess)) // { // using (new ProfilingSample(cmd, "Custom Post Processes Before PP", CustomSamplerId.CustomPostProcessBeforePP.GetSampler())) // { // foreach (var typeString in HDRenderPipeline.currentAsset.beforePostProcessCustomPostProcesses) // RenderCustomPostProcess(cmd, hdCamera, ref source, colorBuffer, Type.GetType(typeString)); // } // } // // Depth of Field is done right after TAA as it's easier to just re-project the CoC // // map rather than having to deal with all the implications of doing it before TAA // if (m_DepthOfField.IsActive() && !isSceneView && m_DepthOfFieldFS) // { // using (new ProfilingSample(cmd, "Depth of Field", CustomSamplerId.DepthOfField.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoDepthOfField(cmd, hdCamera, source, destination, taaEnabled); // PoolSource(ref source, destination); // } // } // // Motion blur after depth of field for aesthetic reasons (better to see motion // // blurred bokeh rather than out of focus motion blur) // if (m_MotionBlur.IsActive() && m_AnimatedMaterialsEnabled && !m_ResetHistory && m_MotionBlurFS) // { // using (new ProfilingSample(cmd, "Motion Blur", CustomSamplerId.MotionBlur.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoMotionBlur(cmd, hdCamera, source, destination); // PoolSource(ref source, destination); // } // } // // Panini projection is done as a fullscreen pass after all depth-based effects are // // done and before bloom kicks in // // This is one effect that would benefit from an overscan mode or supersampling in // // HDRP to reduce the amount of resolution lost at the center of the screen // if (m_PaniniProjection.IsActive() && !isSceneView && m_PaniniProjectionFS) // { // using (new ProfilingSample(cmd, "Panini Projection", CustomSamplerId.PaniniProjection.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoPaniniProjection(cmd, hdCamera, source, destination); // PoolSource(ref source, destination); // } // } // // Combined post-processing stack - always runs if postfx is enabled // using (new ProfilingSample(cmd, "Uber", CustomSamplerId.UberPost.GetSampler())) // { // // Feature flags are passed to all effects and it's their responsibility to check // // if they are used or not so they can set default values if needed // var cs = m_Resources.shaders.uberPostCS; // var featureFlags = GetUberFeatureFlags(isSceneView); // int kernel = GetUberKernel(cs, featureFlags); // // Generate the bloom texture // bool bloomActive = m_Bloom.IsActive() && m_BloomFS; // if (bloomActive) // { // using (new ProfilingSample(cmd, "Bloom", CustomSamplerId.Bloom.GetSampler())) // { // DoBloom(cmd, hdCamera, source, cs, kernel); // } // } // else // { // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._BloomTexture, TextureXR.GetBlackTexture()); // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._BloomDirtTexture, Texture2D.blackTexture); // cmd.SetComputeVectorParam(cs, HDShaderIDs._BloomParams, Vector4.zero); // } // // Build the color grading lut // using (new ProfilingSample(cmd, "Color Grading LUT Builder", CustomSamplerId.ColorGradingLUTBuilder.GetSampler())) // { // DoColorGrading(cmd, cs, kernel); // } // // Setup the rest of the effects // DoLensDistortion(cmd, cs, kernel, featureFlags); // DoChromaticAberration(cmd, cs, kernel, featureFlags); // DoVignette(cmd, cs, kernel, featureFlags); // // Run // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // bool outputColorLog = m_HDInstance.m_CurrentDebugDisplaySettings.data.fullScreenDebugMode == FullScreenDebugMode.ColorLog; // cmd.SetComputeVectorParam(cs, "_DebugFlags", new Vector4(outputColorLog ? 1 : 0, 0, 0, 0)); // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source); // cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination); // cmd.DispatchCompute(cs, kernel, (hdCamera.actualWidth + 7) / 8, (hdCamera.actualHeight + 7) / 8, hdCamera.viewCount); // m_HDInstance.PushFullScreenDebugTexture(hdCamera, cmd, destination, FullScreenDebugMode.ColorLog); // // Cleanup // if (bloomActive) m_Pool.Recycle(m_BloomTexture); // m_BloomTexture = null; // PoolSource(ref source, destination); // } // if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.CustomPostProcess)) // { // using (new ProfilingSample(cmd, "Custom Post Processes After PP", CustomSamplerId.CustomPostProcessAfterPP.GetSampler())) // { // foreach (var typeString in HDRenderPipeline.currentAsset.afterPostProcessCustomPostProcesses) // RenderCustomPostProcess(cmd, hdCamera, ref source, colorBuffer, Type.GetType(typeString)); // } // } //} //if (dynResHandler.DynamicResolutionEnabled() && // Dynamic resolution is on. // hdCamera.antialiasing == AntialiasingMode.FastApproximateAntialiasing && // m_AntialiasingFS) //{ // using (new ProfilingSample(cmd, "FXAA", CustomSamplerId.FXAA.GetSampler())) // { // var destination = m_Pool.Get(Vector2.one, k_ColorFormat); // DoFXAA(cmd, hdCamera, source, destination); // PoolSource(ref source, destination); // } //} using (var builder = renderGraph.AddRenderPass <FinalPassData>("Final Pass", out var passData, ProfilingSampler.Get(HDProfileId.FinalPost))) { passData.parameters = PrepareFinalPass(hdCamera, blueNoise, flipY); passData.source = builder.ReadTexture(source); passData.afterPostProcessTexture = builder.ReadTexture(afterPostProcessTexture); passData.alphaTexture = builder.ReadTexture(m_KeepAlpha ? alphaTexture : renderGraph.ImportTexture(TextureXR.GetWhiteTexture())); passData.destination = builder.WriteTexture(finalRT); builder.SetRenderFunc( (FinalPassData data, RenderGraphContext ctx) => { DoFinalPass(data.parameters, ctx.resources.GetTexture(data.source), ctx.resources.GetTexture(data.afterPostProcessTexture), ctx.resources.GetTexture(data.destination), ctx.resources.GetTexture(data.alphaTexture), ctx.cmd); }); } }
public void RenderRaytracingDeferredLighting(CommandBuffer cmd, HDCamera hdCamera, HDRaytracingEnvironment rtEnvironment, RTHandle directionBuffer, bool rayBinning, LayerMask layerMask, float maxRayLength, RTHandle outputBuffer, bool disableSpecularLighting = false, bool halfResolution = false) { ComputeShader rayBinningCS = m_Asset.renderPipelineRayTracingResources.rayBinningCS; RayTracingShader gBufferRaytracingRT = m_Asset.renderPipelineRayTracingResources.gBufferRaytracingRT; ComputeShader deferredRaytracingCS = m_Asset.renderPipelineRayTracingResources.deferredRaytracingCS; // Texture dimensions int texWidth = hdCamera.actualWidth; int texHeight = hdCamera.actualHeight; if (halfResolution) { texWidth /= 2; texHeight /= 2; } // Evaluate the dispatch parameters int rayTileSize = 16; int numTilesRayBinX = (texWidth + (rayTileSize - 1)) / rayTileSize; int numTilesRayBinY = (texHeight + (rayTileSize - 1)) / rayTileSize; int bufferSizeX = numTilesRayBinX * rayTileSize; int bufferSizeY = numTilesRayBinY * rayTileSize; int currentKernel = 0; if (rayBinning) { // We need to go through the ray binning pass (if required) currentKernel = rayBinningCS.FindKernel(halfResolution? "RayBinningHalf" : "RayBinning"); if (bufferSizeX * bufferSizeY > m_RayBinResult.count) { if (m_RayBinResult != null) { CoreUtils.SafeRelease(m_RayBinResult); CoreUtils.SafeRelease(m_RayBinSizeResult); m_RayBinResult = null; m_RayBinSizeResult = null; } if (bufferSizeX * bufferSizeY > 0) { m_RayBinResult = new ComputeBuffer(bufferSizeX * bufferSizeY, sizeof(uint)); m_RayBinSizeResult = new ComputeBuffer(numTilesRayBinX * numTilesRayBinY, sizeof(uint)); } } cmd.SetComputeTextureParam(rayBinningCS, currentKernel, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer); cmd.SetComputeBufferParam(rayBinningCS, currentKernel, HDShaderIDs._RayBinResult, m_RayBinResult); cmd.SetComputeBufferParam(rayBinningCS, currentKernel, HDShaderIDs._RayBinSizeResult, m_RayBinSizeResult); cmd.SetComputeIntParam(rayBinningCS, HDShaderIDs._RayBinTileCountX, numTilesRayBinX); cmd.DispatchCompute(rayBinningCS, currentKernel, numTilesRayBinX, numTilesRayBinY, 1); } // Define the shader pass to use for the reflection pass cmd.SetRayTracingShaderPass(gBufferRaytracingRT, "GBufferDXR"); if (rayBinning) { cmd.SetGlobalBuffer(HDShaderIDs._RayBinResult, m_RayBinResult); cmd.SetGlobalBuffer(HDShaderIDs._RayBinSizeResult, m_RayBinSizeResult); cmd.SetRayTracingIntParam(gBufferRaytracingRT, HDShaderIDs._RayBinTileCountX, numTilesRayBinX); } // Grab the acceleration structures and the light cluster to use RayTracingAccelerationStructure accelerationStructure = m_RayTracingManager.RequestAccelerationStructure(layerMask); HDRaytracingLightCluster lightCluster = m_RayTracingManager.RequestLightCluster(layerMask); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(gBufferRaytracingRT, HDShaderIDs._RaytracingAccelerationStructureName, accelerationStructure); // Bind the textures required for the ray launching cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._NormalBufferTexture, m_SharedRTManager.GetNormalBuffer()); cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer); // Compute the pixel spread value float pixelSpreadAngle = hdCamera.camera.fieldOfView * (Mathf.PI / 180.0f) / Mathf.Min(hdCamera.actualWidth, hdCamera.actualHeight); cmd.SetGlobalFloat(HDShaderIDs._RaytracingPixelSpreadAngle, pixelSpreadAngle); // Additional ray launch values cmd.SetRayTracingFloatParams(gBufferRaytracingRT, HDShaderIDs._RaytracingRayBias, rtEnvironment.rayBias); cmd.SetRayTracingFloatParams(gBufferRaytracingRT, HDShaderIDs._RaytracingRayMaxLength, maxRayLength); // Bind the output textures cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[0], m_RaytracingGBufferManager.GetBuffer(0)); cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[1], m_RaytracingGBufferManager.GetBuffer(1)); cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[2], m_RaytracingGBufferManager.GetBuffer(2)); cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[3], m_RaytracingGBufferManager.GetBuffer(3)); // cmd.SetRaytracingTextureParam(gBufferRaytracingRT, rayGenGBuffer, HDShaderIDs._GBufferTextureRW[4], m_LocalGBufferManager.GetBuffer(4)); // cmd.SetRaytracingTextureParam(gBufferRaytracingRT, rayGenGBuffer, HDShaderIDs._GBufferTextureRW[5], m_LocalGBufferManager.GetBuffer(5)); cmd.SetRayTracingTextureParam(gBufferRaytracingRT, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer); // Compute the actual resolution that is needed base on the quality uint widthResolution = (uint)hdCamera.actualWidth; uint heightResolution = (uint)hdCamera.actualHeight; if (disableSpecularLighting) { cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, 0); } if (rayBinning) { cmd.DispatchRays(gBufferRaytracingRT, m_RayGenGBufferBinned, (uint)bufferSizeX, (uint)bufferSizeY, 1); } else { cmd.SetRayTracingIntParams(gBufferRaytracingRT, "_RaytracingHalfResolution", halfResolution? 1 : 0); cmd.DispatchRays(gBufferRaytracingRT, m_RayGenGBuffer, widthResolution, heightResolution, 1); } // Now let's do the deferred shading pass on the samples currentKernel = deferredRaytracingCS.FindKernel(halfResolution ? "RaytracingDeferredHalf" : "RaytracingDeferred"); LightCluster lightClusterSettings = VolumeManager.instance.stack.GetComponent <LightCluster>(); cmd.SetComputeBufferParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingLightCluster, lightCluster.GetCluster()); cmd.SetComputeBufferParam(deferredRaytracingCS, currentKernel, HDShaderIDs._LightDatasRT, lightCluster.GetLightDatas()); cmd.SetComputeVectorParam(deferredRaytracingCS, HDShaderIDs._MinClusterPos, lightCluster.GetMinClusterPos()); cmd.SetComputeVectorParam(deferredRaytracingCS, HDShaderIDs._MaxClusterPos, lightCluster.GetMaxClusterPos()); cmd.SetComputeIntParam(deferredRaytracingCS, HDShaderIDs._LightPerCellCount, lightClusterSettings.maxNumLightsPercell.value); cmd.SetComputeIntParam(deferredRaytracingCS, HDShaderIDs._PunctualLightCountRT, lightCluster.GetPunctualLightCount()); cmd.SetComputeIntParam(deferredRaytracingCS, HDShaderIDs._AreaLightCountRT, lightCluster.GetAreaLightCount()); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._DepthTexture, m_SharedRTManager.GetDepthStencilBuffer()); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDistanceBuffer, m_RaytracingDistanceBuffer); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[0], m_RaytracingGBufferManager.GetBuffer(0)); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[1], m_RaytracingGBufferManager.GetBuffer(1)); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[2], m_RaytracingGBufferManager.GetBuffer(2)); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[3], m_RaytracingGBufferManager.GetBuffer(3)); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._LightLayersTexture, TextureXR.GetWhiteTexture()); cmd.SetComputeTextureParam(deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingLitBufferRW, outputBuffer); // Evaluate the dispatch parameters int areaTileSize = 8; int numTilesXHR = (texWidth + (areaTileSize - 1)) / areaTileSize; int numTilesYHR = (texHeight + (areaTileSize - 1)) / areaTileSize; // Compute the texture cmd.DispatchCompute(deferredRaytracingCS, currentKernel, numTilesXHR, numTilesYHR, 1); if (disableSpecularLighting) { cmd.SetGlobalInt(HDShaderIDs._EnableSpecularLighting, hdCamera.frameSettings.IsEnabled(FrameSettingsField.SpecularLighting) ? 1 : 0); } }