void ResetVolumetricCloud() { CoreUtils.Destroy(m_VolumetricClouds); m_VolumetricClouds = null; m_CloudSettingsFromProfile = null; m_LastComputedVolumetricCloudHash = 0; }
void GetVolumetricCloudVolume(VolumeProfile profile, out VolumetricClouds volumetricClouds) { volumetricClouds = null; if (profile != null) { profile.TryGet <VolumetricClouds>(out volumetricClouds); } }
TextureHandle RenderVolumetricClouds_FullResolution(RenderGraph renderGraph, HDCamera hdCamera, TVolumetricCloudsCameraType cameraType, TextureHandle colorBuffer, TextureHandle depthPyramid, TextureHandle motionVectors, TextureHandle volumetricLighting, TextureHandle maxZMask) { using (var builder = renderGraph.AddRenderPass <VolumetricCloudsFullResolutionData>("Generating the rays for RTR", out var passData, ProfilingSampler.Get(HDProfileId.VolumetricClouds))) { builder.EnableAsyncCompute(false); VolumetricClouds settings = hdCamera.volumeStack.GetComponent <VolumetricClouds>(); passData.parameters = PrepareVolumetricCloudsParameters_FullResolution(hdCamera, hdCamera.actualWidth, hdCamera.actualHeight, hdCamera.viewCount, hdCamera.exposureControlFS, settings, cameraType); passData.colorBuffer = builder.ReadTexture(builder.WriteTexture(colorBuffer)); passData.depthPyramid = builder.ReadTexture(depthPyramid); passData.maxZMask = settings.localClouds.value ? renderGraph.defaultResources.blackTextureXR : builder.ReadTexture(maxZMask); passData.ambientProbeBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(m_CloudsProbeBuffer)); passData.volumetricLighting = builder.ReadTexture(volumetricLighting); passData.scatteringFallbackTexture = renderGraph.defaultResources.blackTexture3DXR; passData.intermediateLightingBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporary Clouds Lighting Buffer 0" }); passData.intermediateBufferDepth = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "Temporary Clouds Depth Buffer 0" }); passData.intermediateColorBufferCopy = passData.parameters.needExtraColorBufferCopy ? builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GetColorBufferFormat(), enableRandomWrite = true, name = "Temporary Color Buffer" }) : renderGraph.defaultResources.blackTextureXR; if (passData.parameters.needsTemporaryBuffer) { passData.intermediateBufferUpscale = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporary Clouds Upscaling Buffer" }); } else { passData.intermediateBufferUpscale = renderGraph.defaultResources.blackTexture; } builder.SetRenderFunc( (VolumetricCloudsFullResolutionData data, RenderGraphContext ctx) => { TraceVolumetricClouds_FullResolution(ctx.cmd, data.parameters, data.ambientProbeBuffer, data.colorBuffer, data.depthPyramid, data.volumetricLighting, data.scatteringFallbackTexture, data.maxZMask, data.intermediateLightingBuffer, data.intermediateBufferDepth, data.intermediateColorBufferCopy, data.intermediateBufferUpscale); }); // In the case of reflection probes, we don't expect any pass that will need the transmittance mask of the clouds so we return white. return(renderGraph.defaultResources.whiteTextureXR); } }
void UpdateCurrentStaticLightingVolumetricClouds() { // First, grab the cloud settings of the right type in the profile. CoreUtils.Destroy(m_VolumetricClouds); m_VolumetricClouds = null; m_LastComputedVolumetricCloudHash = 0; GetVolumetricCloudVolume(m_Profile, out m_VolumetricCloudSettingsFromProfile); if (m_VolumetricCloudSettingsFromProfile != null) { m_VolumetricClouds = (VolumetricClouds)ScriptableObject.CreateInstance(typeof(VolumetricClouds)); m_LastComputedVolumetricCloudHash = InitComponentFromProfile(m_VolumetricClouds, m_VolumetricCloudSettingsFromProfile, typeof(VolumetricClouds)); } }
internal void PreRenderVolumetricClouds_AmbientProbe(RenderGraph renderGraph, HDCamera hdCamera) { if (hdCamera.lightingSky.skyRenderer != null) { VolumetricClouds settings = hdCamera.volumeStack.GetComponent <VolumetricClouds>(); using (new RenderGraphProfilingScope(renderGraph, ProfilingSampler.Get(HDProfileId.VolumetricCloudsAmbientProbe))) { TextureHandle outputCubemap = renderGraph.CreateTexture(new TextureDesc(16, 16) { slices = TextureXR.slices, dimension = TextureDimension.Cube, colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true }); outputCubemap = m_SkyManager.RenderSkyToCubemap(renderGraph, hdCamera.lightingSky, hdCamera, includeSunInBaking: false, renderCloudLayers: false, outputCubemap); m_SkyManager.UpdateAmbientProbe(renderGraph, outputCubemap, outputForClouds: true, null, null, m_CloudsProbeBuffer, new Vector4(settings.ambientLightProbeDimmer.value, 0.0f, 0.0f, 0.0f), null); } } }
TextureHandle RenderVolumetricClouds_Accumulation(RenderGraph renderGraph, HDCamera hdCamera, TVolumetricCloudsCameraType cameraType, TextureHandle colorBuffer, TextureHandle depthPyramid, TextureHandle motionVectors, TextureHandle volumetricLighting, TextureHandle maxZMask) { using (var builder = renderGraph.AddRenderPass <VolumetricCloudsAccumulationData>("Volumetric Clouds", out var passData, ProfilingSampler.Get(HDProfileId.VolumetricClouds))) { builder.EnableAsyncCompute(false); VolumetricClouds settings = hdCamera.volumeStack.GetComponent <VolumetricClouds>(); passData.parameters = PrepareVolumetricCloudsParameters_Accumulation(hdCamera, settings, cameraType, EvaluateVolumetricCloudsHistoryValidity(hdCamera, settings.localClouds.value)); passData.colorBuffer = builder.ReadTexture(builder.WriteTexture(colorBuffer)); passData.depthPyramid = builder.ReadTexture(depthPyramid); passData.motionVectors = builder.ReadTexture(motionVectors); passData.maxZMask = settings.localClouds.value ? renderGraph.defaultResources.blackTextureXR : builder.ReadTexture(maxZMask); passData.ambientProbeBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(m_CloudsProbeBuffer)); passData.volumetricLighting = builder.ReadTexture(volumetricLighting); passData.scatteringFallbackTexture = renderGraph.defaultResources.blackTexture3DXR; passData.currentHistoryBuffer0 = renderGraph.ImportTexture(RequestCurrentVolumetricCloudsHistoryTexture0(hdCamera)); passData.previousHistoryBuffer0 = renderGraph.ImportTexture(RequestPreviousVolumetricCloudsHistoryTexture0(hdCamera)); passData.currentHistoryBuffer1 = renderGraph.ImportTexture(RequestCurrentVolumetricCloudsHistoryTexture1(hdCamera)); passData.previousHistoryBuffer1 = renderGraph.ImportTexture(RequestPreviousVolumetricCloudsHistoryTexture1(hdCamera)); passData.intermediateBuffer0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one * 0.5f, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporary Clouds Lighting Buffer 0" }); passData.intermediateBuffer1 = builder.CreateTransientTexture(new TextureDesc(Vector2.one * 0.5f, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporary Clouds Lighting Buffer 1 " }); passData.intermediateBufferDepth0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one * 0.5f, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "Temporary Clouds Depth Buffer 0" }); passData.intermediateBufferDepth1 = builder.CreateTransientTexture(new TextureDesc(Vector2.one * 0.5f, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "Temporary Clouds Depth Buffer 1" }); passData.intermediateColorBufferCopy = passData.parameters.needExtraColorBufferCopy ? builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GetColorBufferFormat(), enableRandomWrite = true, name = "Temporary Color Buffer" }) : renderGraph.defaultResources.blackTextureXR; if (passData.parameters.needsTemporaryBuffer) { passData.intermediateBufferUpscale = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Temporary Clouds Upscaling Buffer" }); } else { passData.intermediateBufferUpscale = renderGraph.defaultResources.blackTexture; } if (passData.parameters.commonData.cameraType == TVolumetricCloudsCameraType.PlanarReflection) { passData.intermediateBufferDepth2 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "Temporary Clouds Depth Buffer 2" }); } else { passData.intermediateBufferDepth2 = renderGraph.defaultResources.blackTexture; } builder.SetRenderFunc( (VolumetricCloudsAccumulationData data, RenderGraphContext ctx) => { TraceVolumetricClouds_Accumulation(ctx.cmd, data.parameters, data.ambientProbeBuffer, data.colorBuffer, data.depthPyramid, data.motionVectors, data.volumetricLighting, data.scatteringFallbackTexture, data.maxZMask, data.currentHistoryBuffer0, data.previousHistoryBuffer0, data.currentHistoryBuffer1, data.previousHistoryBuffer1, data.intermediateBuffer0, data.intermediateBuffer1, data.intermediateBufferDepth0, data.intermediateBufferDepth1, data.intermediateBufferDepth2, data.intermediateColorBufferCopy, data.intermediateBufferUpscale); }); // Push the texture to the debug menu PushFullScreenDebugTexture(m_RenderGraph, passData.currentHistoryBuffer0, FullScreenDebugMode.VolumetricClouds); // We return the volumetric clouds buffers rendered at half resolution. We should ideally return the full resolution transmittance, but // this should be enough for the initial case (which is the lens flares). The transmittance can be found in the alpha channel. return(passData.currentHistoryBuffer0); } }
VolumetricCloudsParameters_Accumulation PrepareVolumetricCloudsParameters_Accumulation(HDCamera hdCamera, VolumetricClouds settings, TVolumetricCloudsCameraType cameraType, bool historyValidity) { VolumetricCloudsParameters_Accumulation parameters = new VolumetricCloudsParameters_Accumulation(); // Compute the cloud model data CloudModelData cloudModelData = GetCloudModelData(settings); // Fill the common data FillVolumetricCloudsCommonData(hdCamera.exposureControlFS, settings, cameraType, in cloudModelData, ref parameters.commonData); // We need to make sure that the allocated size of the history buffers and the dispatch size are perfectly equal. // The ideal approach would be to have a function for that returns the converted size from a viewport and texture size. // but for now we do it like this. // Final resolution at which the effect should be exported parameters.finalWidth = hdCamera.actualWidth; parameters.finalHeight = hdCamera.actualHeight; // Intermediate resolution at which the effect is accumulated parameters.intermediateWidth = Mathf.RoundToInt(0.5f * hdCamera.actualWidth); parameters.intermediateHeight = Mathf.RoundToInt(0.5f * hdCamera.actualHeight); // Resolution at which the effect is traced parameters.traceWidth = Mathf.RoundToInt(0.25f * hdCamera.actualWidth); parameters.traceHeight = Mathf.RoundToInt(0.25f * hdCamera.actualHeight); parameters.viewCount = hdCamera.viewCount; parameters.previousViewportSize = hdCamera.historyRTHandleProperties.previousViewportSize; parameters.historyValidity = historyValidity; // MSAA support parameters.needsTemporaryBuffer = hdCamera.msaaEnabled; parameters.cloudCombinePass = m_CloudCombinePass; parameters.needExtraColorBufferCopy = (GetColorBufferFormat() == GraphicsFormat.B10G11R11_UFloatPack32 && // On PC and Metal, but not on console. (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)); // In case of MSAA, we no longer require the preliminary copy as there is no longer a need for RW of the color buffer. parameters.needExtraColorBufferCopy &= !parameters.needsTemporaryBuffer; // Compute shader and kernels parameters.convertObliqueDepthKernel = m_ConvertObliqueDepthKernel; parameters.depthDownscaleKernel = m_CloudDownscaleDepthKernel; parameters.renderKernel = m_CloudRenderKernel; parameters.reprojectKernel = settings.ghostingReduction.value ? m_ReprojectCloudsRejectionKernel : m_ReprojectCloudsKernel; parameters.upscaleAndCombineKernel = parameters.needExtraColorBufferCopy ? m_UpscaleAndCombineCloudsKernelColorCopy : m_UpscaleAndCombineCloudsKernelColorRW; // Update the constant buffer VolumetricCloudsCameraData cameraData; cameraData.cameraType = parameters.commonData.cameraType; cameraData.traceWidth = parameters.traceWidth; cameraData.traceHeight = parameters.traceHeight; cameraData.intermediateWidth = parameters.intermediateWidth; cameraData.intermediateHeight = parameters.intermediateHeight; cameraData.finalWidth = parameters.finalWidth; cameraData.finalHeight = parameters.finalHeight; cameraData.viewCount = parameters.viewCount; cameraData.enableExposureControl = parameters.commonData.enableExposureControl; cameraData.lowResolution = true; cameraData.enableIntegration = true; UpdateShaderVariableslClouds(ref parameters.commonData.cloudsCB, hdCamera, settings, cameraData, cloudModelData, false); // If this is a default camera, we want the improved blending, otherwise we don't (in the case of a planar) parameters.commonData.cloudsCB._ImprovedTransmittanceBlend = parameters.commonData.cameraType == TVolumetricCloudsCameraType.Default ? 1 : 0; parameters.commonData.cloudsCB._CubicTransmittance = parameters.commonData.cameraType == TVolumetricCloudsCameraType.Default && hdCamera.msaaEnabled ? 1 : 0; return(parameters); }
VolumetricCloudsParameters_FullResolution PrepareVolumetricCloudsParameters_FullResolution(HDCamera hdCamera, int width, int height, int viewCount, bool exposureControl, VolumetricClouds settings, TVolumetricCloudsCameraType cameraType) { VolumetricCloudsParameters_FullResolution parameters = new VolumetricCloudsParameters_FullResolution(); // Compute the cloud model data CloudModelData cloudModelData = GetCloudModelData(settings); // Fill the common data FillVolumetricCloudsCommonData(exposureControl, settings, cameraType, in cloudModelData, ref parameters.commonData); // If this is a baked reflection, we run everything at full res parameters.finalWidth = width; parameters.finalHeight = height; parameters.viewCount = viewCount; // MSAA support parameters.needsTemporaryBuffer = hdCamera.msaaEnabled; parameters.cloudCombinePass = m_CloudCombinePass; parameters.needExtraColorBufferCopy = (GetColorBufferFormat() == GraphicsFormat.B10G11R11_UFloatPack32 && // On PC and Metal, but not on console. (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)); // In case of MSAA, we no longer require the preliminary copy as there is no longer a need for RW of the color buffer. parameters.needExtraColorBufferCopy &= !parameters.needsTemporaryBuffer; // Compute shader and kernels parameters.renderKernel = m_CloudRenderKernel; parameters.combineKernel = parameters.needExtraColorBufferCopy ? m_CombineCloudsKernelColorCopy : m_CombineCloudsKernelColorRW; // Update the constant buffer VolumetricCloudsCameraData cameraData; cameraData.cameraType = parameters.commonData.cameraType; cameraData.traceWidth = parameters.finalWidth; cameraData.traceHeight = parameters.finalHeight; cameraData.intermediateWidth = parameters.finalWidth; cameraData.intermediateHeight = parameters.finalHeight; cameraData.finalWidth = parameters.finalWidth; cameraData.finalHeight = parameters.finalHeight; cameraData.viewCount = parameters.viewCount; cameraData.enableExposureControl = parameters.commonData.enableExposureControl; cameraData.lowResolution = false; cameraData.enableIntegration = true; UpdateShaderVariableslClouds(ref parameters.commonData.cloudsCB, hdCamera, settings, cameraData, cloudModelData, false); return(parameters); }
// Function that fills the buffer with the ambient probe values unsafe void SetPreconvolvedAmbientLightProbe(ref ShaderVariablesClouds cb, HDCamera hdCamera, VolumetricClouds settings) { SphericalHarmonicsL2 probeSH = SphericalHarmonicMath.UndoCosineRescaling(m_SkyManager.GetAmbientProbe(hdCamera)); probeSH = SphericalHarmonicMath.RescaleCoefficients(probeSH, settings.ambientLightProbeDimmer.value); ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(m_PhaseZHClouds, 0.0f); SphericalHarmonicsL2 finalSH = SphericalHarmonicMath.PremultiplyCoefficients(SphericalHarmonicMath.Convolve(probeSH, m_PhaseZHClouds)); SphericalHarmonicMath.PackCoefficients(m_PackedCoeffsClouds, finalSH); for (int i = 0; i < 7; i++) { for (int j = 0; j < 4; ++j) { cb._AmbientProbeCoeffs[i * 4 + j] = m_PackedCoeffsClouds[i][j]; } } }
VolumetricCloudsParameters_LowResolution PrepareVolumetricCloudsParameters_LowResolution(HDCamera hdCamera, int width, int height, int viewCount, bool exposureControl, VolumetricClouds settings, TVolumetricCloudsCameraType cameraType) { VolumetricCloudsParameters_LowResolution parameters = new VolumetricCloudsParameters_LowResolution(); // Compute the cloud model data CloudModelData cloudModelData = GetCloudModelData(settings); // Fill the common data FillVolumetricCloudsCommonData(exposureControl, settings, cameraType, in cloudModelData, ref parameters.commonData); // We need to make sure that the allocated size of the history buffers and the dispatch size are perfectly equal. // The ideal approach would be to have a function for that returns the converted size from a viewport and texture size. // but for now we do it like this. // Final resolution at which the effect should be exported parameters.finalWidth = width; parameters.finalHeight = height; // Intermediate resolution at which the effect is accumulated parameters.intermediateWidth = Mathf.RoundToInt(0.5f * width); parameters.intermediateHeight = Mathf.RoundToInt(0.5f * height); // Resolution at which the effect is traced parameters.traceWidth = Mathf.RoundToInt(0.25f * width); parameters.traceHeight = Mathf.RoundToInt(0.25f * height); parameters.viewCount = viewCount; // MSAA support parameters.needsTemporaryBuffer = hdCamera.msaaEnabled; parameters.cloudCombinePass = m_CloudCombinePass; parameters.needExtraColorBufferCopy = (GetColorBufferFormat() == GraphicsFormat.B10G11R11_UFloatPack32 && // On PC and Metal, but not on console. (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D11 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal || SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)); // In case of MSAA, we no longer require the preliminary copy as there is no longer a need for RW of the color buffer. parameters.needExtraColorBufferCopy &= !parameters.needsTemporaryBuffer; // Compute shader and kernels parameters.depthDownscaleKernel = m_CloudDownscaleDepthKernel; parameters.renderKernel = m_CloudRenderKernel; parameters.preUpscaleKernel = m_PreUpscaleCloudsKernel; parameters.upscaleAndCombineKernel = parameters.needExtraColorBufferCopy ? m_UpscaleAndCombineCloudsKernelColorCopy : m_UpscaleAndCombineCloudsKernelColorRW; // Update the constant buffer VolumetricCloudsCameraData cameraData; cameraData.cameraType = parameters.commonData.cameraType; cameraData.traceWidth = parameters.traceWidth; cameraData.traceHeight = parameters.traceHeight; cameraData.intermediateWidth = parameters.intermediateWidth; cameraData.intermediateHeight = parameters.intermediateHeight; cameraData.finalWidth = parameters.finalWidth; cameraData.finalHeight = parameters.finalHeight; cameraData.viewCount = parameters.viewCount; cameraData.enableExposureControl = parameters.commonData.enableExposureControl; cameraData.lowResolution = true; cameraData.enableIntegration = false; UpdateShaderVariableslClouds(ref parameters.commonData.cloudsCB, hdCamera, settings, cameraData, cloudModelData, false); return(parameters); }
void PrepareVolumetricCloudsSkyLowPassData(RenderGraph renderGraph, RenderGraphBuilder builder, HDCamera hdCamera, int width, int height, Matrix4x4[] pixelCoordToViewDir, CubemapFace cubemapFace, VolumetricClouds settings, VolumetricCloudsSkyLowPassData data) { // Compute the cloud model data CloudModelData cloudModelData = GetCloudModelData(settings); // Fill the common data FillVolumetricCloudsCommonData(false, settings, TVolumetricCloudsCameraType.Sky, in cloudModelData, ref data.commonData); // We need to make sure that the allocated size of the history buffers and the dispatch size are perfectly equal. // The ideal approach would be to have a function for that returns the converted size from a viewport and texture size. // but for now we do it like this. // Final resolution at which the effect should be exported data.finalWidth = width; data.finalHeight = height; // Intermediate resolution at which the effect is accumulated data.intermediateWidth = Mathf.RoundToInt(0.5f * width); data.intermediateHeight = Mathf.RoundToInt(0.5f * height); // Resolution at which the effect is traced data.traceWidth = Mathf.RoundToInt(0.25f * width); data.traceHeight = Mathf.RoundToInt(0.25f * height); // Sky data.cubemapFace = cubemapFace; data.cloudCombinePass = m_CloudCombinePass; // Kernels data.renderKernel = m_CloudRenderKernel; data.preUpscaleKernel = m_PreUpscaleCloudsSkyKernel; data.finalUpscaleKernel = m_UpscaleAndCombineCloudsSkyKernel; data.pixelCoordToViewDir = pixelCoordToViewDir; // Update the constant buffer VolumetricCloudsCameraData cameraData; cameraData.cameraType = data.commonData.cameraType; cameraData.traceWidth = data.traceWidth; cameraData.traceHeight = data.traceHeight; cameraData.intermediateWidth = data.intermediateWidth; cameraData.intermediateHeight = data.intermediateHeight; cameraData.finalWidth = data.finalWidth; cameraData.finalHeight = data.finalHeight; cameraData.viewCount = 1; cameraData.enableExposureControl = data.commonData.enableExposureControl; cameraData.lowResolution = true; cameraData.enableIntegration = false; UpdateShaderVariableslClouds(ref data.commonData.cloudsCB, hdCamera, settings, cameraData, cloudModelData, false); int skyResolution = (int)m_Asset.currentPlatformRenderPipelineSettings.lightLoopSettings.skyReflectionSize; data.intermediateLightingBuffer = builder.CreateTransientTexture(GetVolumetricCloudsIntermediateLightingBufferDesc()); data.intermediateDepthBuffer = builder.CreateTransientTexture(GetVolumetricCloudsIntermediateDepthBufferDesc()); data.output = builder.WriteTexture(renderGraph.CreateTexture(GetVolumetricCloudsIntermediateCubeTextureDesc())); data.maxZMask = builder.ReadTexture(renderGraph.defaultResources.blackTextureXR); data.ambientProbeBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(m_CloudsProbeBuffer)); }
internal TextureHandle RenderVolumetricClouds_Sky(RenderGraph renderGraph, HDCamera hdCamera, Matrix4x4[] pixelCoordToViewDir, VolumetricClouds settings, int width, int height, TextureHandle skyboxCubemap) { // If the current volume does not enable the feature, quit right away. if (!HasVolumetricClouds(hdCamera, in settings)) { return(skyboxCubemap); } if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.FullResolutionCloudsForSky)) { using (var builder = renderGraph.AddRenderPass <VolumetricCloudsSkyHighPassData>("FullResolutionCloudsForSky", out var passData, ProfilingSampler.Get(HDProfileId.VolumetricCloudsTrace))) { PrepareVolumetricCloudsSkyHighPassData(renderGraph, builder, hdCamera, width, height, pixelCoordToViewDir, CubemapFace.Unknown, settings, skyboxCubemap, passData); builder.SetRenderFunc( (VolumetricCloudsSkyHighPassData data, RenderGraphContext ctx) => { for (int faceIdx = 0; faceIdx < 6; ++faceIdx) { // Update the cubemap face and the inverse projection matrix data.cubemapFace = (CubemapFace)faceIdx; data.commonData.cloudsCB._CloudsPixelCoordToViewDirWS = data.pixelCoordToViewDir[faceIdx]; data.commonData.cloudsCB._ValidMaxZMask = 0; // Render the face straight to the output cubemap RenderVolumetricClouds_Sky_High(ctx.cmd, data, ctx.renderGraphPool.GetTempMaterialPropertyBlock()); } }); return(passData.output); } } else { TextureHandle intermediateCubemap; using (var builder = renderGraph.AddRenderPass <VolumetricCloudsSkyLowPassData>("LowResolutionCloudsForSky", out var passData, ProfilingSampler.Get(HDProfileId.VolumetricCloudsTrace))) { PrepareVolumetricCloudsSkyLowPassData(renderGraph, builder, hdCamera, width, height, pixelCoordToViewDir, CubemapFace.Unknown, settings, passData); builder.SetRenderFunc( (VolumetricCloudsSkyLowPassData data, RenderGraphContext ctx) => { for (int faceIdx = 0; faceIdx < 6; ++faceIdx) { // Update the cubemap face and the inverse projection matrix data.cubemapFace = (CubemapFace)faceIdx; data.commonData.cloudsCB._CloudsPixelCoordToViewDirWS = data.pixelCoordToViewDir[faceIdx]; data.commonData.cloudsCB._ValidMaxZMask = 0; // Render the face straight to the output cubemap TraceVolumetricClouds_Sky_Low(ctx.cmd, data, ctx.renderGraphPool.GetTempMaterialPropertyBlock()); } }); intermediateCubemap = passData.output; } using (var builder = renderGraph.AddRenderPass <VolumetricCloudsPreUpscalePassData>("VolumetricCloudsPreUpscale", out var passData, ProfilingSampler.Get(HDProfileId.VolumetricCloudsPreUpscale))) { int skyResolution = (int)m_Asset.currentPlatformRenderPipelineSettings.lightLoopSettings.skyReflectionSize; passData.cloudCombinePass = m_CloudCombinePass; passData.pixelCoordToViewDir = pixelCoordToViewDir; passData.input = builder.ReadTexture(intermediateCubemap); passData.output = builder.WriteTexture(renderGraph.CreateTexture(GetVolumetricCloudsIntermediateCubeTextureDesc())); builder.SetRenderFunc( (VolumetricCloudsPreUpscalePassData data, RenderGraphContext ctx) => { for (int faceIdx = 0; faceIdx < 6; ++faceIdx) { var mpb = ctx.renderGraphPool.GetTempMaterialPropertyBlock(); mpb.Clear(); mpb.SetTexture(HDShaderIDs._VolumetricCloudsTexture, data.input); mpb.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, data.pixelCoordToViewDir[faceIdx]); mpb.SetInt(HDShaderIDs._Mipmap, 2); CoreUtils.SetRenderTarget(ctx.cmd, data.output, ClearFlag.None, 1, (CubemapFace)faceIdx); CoreUtils.DrawFullScreen(ctx.cmd, data.cloudCombinePass, mpb, 4); } }); intermediateCubemap = passData.output; } using (var builder = renderGraph.AddRenderPass <VolumetricCloudsUpscalePassData>("VolumetricCloudsUpscaleAndCombine", out var passData, ProfilingSampler.Get(HDProfileId.VolumetricCloudsUpscaleAndCombine))) { passData.cloudCombinePass = m_CloudCombinePass; passData.pixelCoordToViewDir = pixelCoordToViewDir; passData.input = builder.ReadTexture(intermediateCubemap); if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) { passData.intermediateBuffer = builder.CreateTransientTexture(GetVolumetricCloudsIntermediateLightingBufferDesc()); passData.output = builder.ReadWriteTexture(skyboxCubemap); } else { passData.output = builder.WriteTexture(skyboxCubemap); } builder.SetRenderFunc( (VolumetricCloudsUpscalePassData data, RenderGraphContext ctx) => { for (int faceIdx = 0; faceIdx < 6; ++faceIdx) { var mpb = ctx.renderGraphPool.GetTempMaterialPropertyBlock(); if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) { // On Intel GPUs on OSX, due to the fact that we cannot always rely on pre-exposure the hardware blending fails and turns into Nans when // the values are close to the max fp16 value. We do the blending manually on metal to avoid that behavior. // Copy the target face of the cubemap into a temporary texture ctx.cmd.CopyTexture(data.output, faceIdx, 0, data.intermediateBuffer, 0, 0); mpb.Clear(); mpb.SetTexture(HDShaderIDs._CameraColorTexture, data.intermediateBuffer); mpb.SetTexture(HDShaderIDs._VolumetricCloudsTexture, data.input); mpb.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, data.pixelCoordToViewDir[faceIdx]); mpb.SetInt(HDShaderIDs._Mipmap, 1); CoreUtils.SetRenderTarget(ctx.cmd, data.output, ClearFlag.None, 0, (CubemapFace)faceIdx); CoreUtils.DrawFullScreen(ctx.cmd, data.cloudCombinePass, mpb, 5); } else { mpb.Clear(); mpb.SetTexture(HDShaderIDs._VolumetricCloudsTexture, data.input); mpb.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, data.pixelCoordToViewDir[faceIdx]); mpb.SetInt(HDShaderIDs._Mipmap, 1); CoreUtils.SetRenderTarget(ctx.cmd, data.output, ClearFlag.None, 0, (CubemapFace)faceIdx); CoreUtils.DrawFullScreen(ctx.cmd, data.cloudCombinePass, mpb, 6); } } }); return(passData.output); } } }
void PrepareVolumetricCloudsSkyHighPassData(RenderGraph renderGraph, RenderGraphBuilder builder, HDCamera hdCamera, int width, int height, Matrix4x4[] pixelCoordToViewDir, CubemapFace cubemapFace, VolumetricClouds settings, TextureHandle output, VolumetricCloudsSkyHighPassData data) { // Compute the cloud model data CloudModelData cloudModelData = GetCloudModelData(settings); // Fill the common data FillVolumetricCloudsCommonData(false, settings, TVolumetricCloudsCameraType.Sky, in cloudModelData, ref data.commonData); // If this is a baked reflection, we run everything at full res data.finalWidth = width; data.finalHeight = height; // Sky data.cubemapFace = cubemapFace; data.cloudCombinePass = m_CloudCombinePass; // Compute shader and kernels data.renderKernel = m_CloudRenderKernel; data.combineKernel = m_CombineCloudsSkyKernel; data.pixelCoordToViewDir = pixelCoordToViewDir; // Update the constant buffer VolumetricCloudsCameraData cameraData; cameraData.cameraType = data.commonData.cameraType; cameraData.traceWidth = data.finalWidth; cameraData.traceHeight = data.finalHeight; cameraData.intermediateWidth = data.finalWidth; cameraData.intermediateHeight = data.finalHeight; cameraData.finalWidth = data.finalWidth; cameraData.finalHeight = data.finalHeight; cameraData.viewCount = 1; cameraData.enableExposureControl = data.commonData.enableExposureControl; cameraData.lowResolution = false; cameraData.enableIntegration = false; UpdateShaderVariableslClouds(ref data.commonData.cloudsCB, hdCamera, settings, cameraData, cloudModelData, false); int skyResolution = (int)m_Asset.currentPlatformRenderPipelineSettings.lightLoopSettings.skyReflectionSize; data.intermediateLightingBuffer0 = builder.CreateTransientTexture(GetVolumetricCloudsIntermediateLightingBufferDesc()); data.intermediateDepthBuffer = builder.CreateTransientTexture(GetVolumetricCloudsIntermediateDepthBufferDesc()); if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal) { data.intermediateLightingBuffer1 = builder.CreateTransientTexture(GetVolumetricCloudsIntermediateLightingBufferDesc()); data.output = builder.ReadWriteTexture(output); } else { data.output = builder.WriteTexture(output); } data.maxZMask = builder.ReadTexture(renderGraph.defaultResources.blackTextureXR); data.ambientProbeBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(m_CloudsProbeBuffer)); }