예제 #1
0
 void ResetVolumetricCloud()
 {
     CoreUtils.Destroy(m_VolumetricClouds);
     m_VolumetricClouds                = null;
     m_CloudSettingsFromProfile        = null;
     m_LastComputedVolumetricCloudHash = 0;
 }
예제 #2
0
 void GetVolumetricCloudVolume(VolumeProfile profile, out VolumetricClouds volumetricClouds)
 {
     volumetricClouds = null;
     if (profile != null)
     {
         profile.TryGet <VolumetricClouds>(out volumetricClouds);
     }
 }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        // 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);
        }
예제 #11
0
        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));
        }
예제 #12
0
        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);
                }
            }
        }
예제 #13
0
        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));
        }