static void TraceVolumetricClouds_Sky_Low(CommandBuffer cmd, VolumetricCloudsSkyLowPassData passData, MaterialPropertyBlock mpb) { // Compute the number of tiles to evaluate int traceTX = (passData.traceWidth + (8 - 1)) / 8; int traceTY = (passData.traceHeight + (8 - 1)) / 8; // Bind the sampling textures BlueNoise.BindDitheredTextureSet(cmd, passData.commonData.ditheredTextureSet); // Bind the constant buffer ConstantBuffer.Push(cmd, passData.commonData.cloudsCB, passData.commonData.volumetricCloudsCS, HDShaderIDs._ShaderVariablesClouds); CoreUtils.SetKeyword(cmd, "LOCAL_VOLUMETRIC_CLOUDS", false); // Ray-march the clouds for this frame CoreUtils.SetKeyword(cmd, "PHYSICALLY_BASED_SUN", passData.commonData.cloudsCB._PhysicallyBasedSun == 1); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._MaxZMaskTexture, passData.maxZMask); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._Worley128RGBA, passData.commonData.worley128RGBA); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._ErosionNoise, passData.commonData.erosionNoise); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudMapTexture, passData.commonData.cloudMapTexture); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudLutTexture, passData.commonData.cloudLutTexture); cmd.SetComputeBufferParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._VolumetricCloudsAmbientProbeBuffer, passData.ambientProbeBuffer); // Output buffers cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudsLightingTextureRW, passData.intermediateLightingBuffer); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudsDepthTextureRW, passData.intermediateDepthBuffer); cmd.DispatchCompute(passData.commonData.volumetricCloudsCS, passData.renderKernel, traceTX, traceTY, 1); CoreUtils.SetKeyword(cmd, "PHYSICALLY_BASED_SUN", false); mpb.SetTexture(HDShaderIDs._VolumetricCloudsUpscaleTextureRW, passData.intermediateLightingBuffer); CoreUtils.SetRenderTarget(cmd, passData.output, ClearFlag.None, miplevel: 2, cubemapFace: passData.cubemapFace); CoreUtils.DrawFullScreen(cmd, passData.cloudCombinePass, mpb, 3); }
static void RenderVolumetricClouds_Sky_High(CommandBuffer cmd, VolumetricCloudsSkyHighPassData passData, MaterialPropertyBlock mpb) { // Compute the number of tiles to evaluate int finalTX = (passData.finalWidth + (8 - 1)) / 8; int finalTY = (passData.finalHeight + (8 - 1)) / 8; // Bind the sampling textures BlueNoise.BindDitheredTextureSet(cmd, passData.commonData.ditheredTextureSet); // Set the multi compile CoreUtils.SetKeyword(cmd, "LOCAL_VOLUMETRIC_CLOUDS", false); // Bind the constant buffer ConstantBuffer.Push(cmd, passData.commonData.cloudsCB, passData.commonData.volumetricCloudsCS, HDShaderIDs._ShaderVariablesClouds); // Ray-march the clouds for this frame CoreUtils.SetKeyword(cmd, "PHYSICALLY_BASED_SUN", passData.commonData.cloudsCB._PhysicallyBasedSun == 1); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._MaxZMaskTexture, passData.maxZMask); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._Worley128RGBA, passData.commonData.worley128RGBA); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._ErosionNoise, passData.commonData.erosionNoise); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudMapTexture, passData.commonData.cloudMapTexture); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudLutTexture, passData.commonData.cloudLutTexture); cmd.SetComputeBufferParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._VolumetricCloudsAmbientProbeBuffer, passData.ambientProbeBuffer); // Output buffers cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudsLightingTextureRW, passData.intermediateLightingBuffer0); cmd.SetComputeTextureParam(passData.commonData.volumetricCloudsCS, passData.renderKernel, HDShaderIDs._CloudsDepthTextureRW, passData.intermediateDepthBuffer); // Trace the clouds cmd.DispatchCompute(passData.commonData.volumetricCloudsCS, passData.renderKernel, finalTX, finalTY, 1); // Reset the multi compile CoreUtils.SetKeyword(cmd, "PHYSICALLY_BASED_SUN", false); 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 cmd.CopyTexture(passData.output, (int)passData.cubemapFace, 0, passData.intermediateLightingBuffer1, 0, 0); // Output the result into the output buffer mpb.SetTexture(HDShaderIDs._CameraColorTexture, passData.intermediateLightingBuffer1); mpb.SetTexture(HDShaderIDs._VolumetricCloudsUpscaleTextureRW, passData.intermediateLightingBuffer0); CoreUtils.SetRenderTarget(cmd, passData.output, ClearFlag.None, 0, passData.cubemapFace); CoreUtils.DrawFullScreen(cmd, passData.cloudCombinePass, mpb, 1); } else { // Output the result into the output buffer mpb.SetTexture(HDShaderIDs._VolumetricCloudsUpscaleTextureRW, passData.intermediateLightingBuffer0); CoreUtils.SetRenderTarget(cmd, passData.output, ClearFlag.None, 0, passData.cubemapFace); CoreUtils.DrawFullScreen(cmd, passData.cloudCombinePass, mpb, 2); } }
static void TraceVolumetricClouds_FullResolution(CommandBuffer cmd, VolumetricCloudsParameters_FullResolution parameters, ComputeBuffer ambientProbeBuffer, RTHandle colorBuffer, RTHandle depthPyramid, RTHandle volumetricLightingTexture, RTHandle scatteringFallbackTexture, RTHandle maxZMask, RTHandle intermediateLightingBuffer0, RTHandle intermediateDepthBuffer0, RTHandle intermediateColorBuffer, RTHandle intermediateUpscaleBuffer) { // Compute the number of tiles to evaluate int finalTX = (parameters.finalWidth + (8 - 1)) / 8; int finalTY = (parameters.finalHeight + (8 - 1)) / 8; // Bind the sampling textures BlueNoise.BindDitheredTextureSet(cmd, parameters.commonData.ditheredTextureSet); // Set the multi compiles CoreUtils.SetKeyword(cmd, "LOCAL_VOLUMETRIC_CLOUDS", parameters.commonData.localClouds); // Bind the constant buffer ConstantBuffer.Push(cmd, parameters.commonData.cloudsCB, parameters.commonData.volumetricCloudsCS, HDShaderIDs._ShaderVariablesClouds); using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricCloudsTrace))) { // Ray-march the clouds for this frame CoreUtils.SetKeyword(cmd, "PHYSICALLY_BASED_SUN", parameters.commonData.cloudsCB._PhysicallyBasedSun == 1); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._MaxZMaskTexture, maxZMask); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._VolumetricCloudsSourceDepth, depthPyramid); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._Worley128RGBA, parameters.commonData.worley128RGBA); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._ErosionNoise, parameters.commonData.erosionNoise); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._CloudMapTexture, parameters.commonData.cloudMapTexture); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._CloudLutTexture, parameters.commonData.cloudLutTexture); cmd.SetComputeBufferParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._VolumetricCloudsAmbientProbeBuffer, ambientProbeBuffer); // Output buffers cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._CloudsLightingTextureRW, intermediateLightingBuffer0); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, HDShaderIDs._CloudsDepthTextureRW, intermediateDepthBuffer0); cmd.DispatchCompute(parameters.commonData.volumetricCloudsCS, parameters.renderKernel, finalTX, finalTY, parameters.viewCount); CoreUtils.SetKeyword(cmd, "PHYSICALLY_BASED_SUN", false); } using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricCloudsUpscaleAndCombine))) { if (parameters.needExtraColorBufferCopy) { HDUtils.BlitCameraTexture(cmd, colorBuffer, intermediateColorBuffer); } // Define which kernel to use cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._VolumetricCloudsTexture, intermediateLightingBuffer0); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._DepthStatusTexture, intermediateDepthBuffer0); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._DepthTexture, depthPyramid); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._CameraColorTexture, intermediateColorBuffer); cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._VBufferLighting, volumetricLightingTexture); if (parameters.commonData.cloudsCB._PhysicallyBasedSun == 0) { // This has to be done in the global space given that the "correct" one happens in the global space. // If we do it in the local space, there are some cases when the previous frames local take precedence over the current frame global one. cmd.SetGlobalTexture(HDShaderIDs._AirSingleScatteringTexture, scatteringFallbackTexture); cmd.SetGlobalTexture(HDShaderIDs._AerosolSingleScatteringTexture, scatteringFallbackTexture); cmd.SetGlobalTexture(HDShaderIDs._MultipleScatteringTexture, scatteringFallbackTexture); } if (parameters.needsTemporaryBuffer) { CoreUtils.SetKeyword(cmd, "USE_INTERMEDIATE_BUFFER", true); // Provide this second upscaling + combine strategy in case a temporary buffer is requested (ie MSAA). // In the case of an MSAA color target, we cannot use the in-place blending of the clouds with the color target. cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._VolumetricCloudsUpscaleTextureRW, intermediateUpscaleBuffer); // Perform the upscale into an intermediate buffer. cmd.DispatchCompute(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, finalTX, finalTY, parameters.viewCount); parameters.cloudCombinePass.SetTexture(HDShaderIDs._VolumetricCloudsUpscaleTextureRW, intermediateUpscaleBuffer); // Composite the clouds into the MSAA target via hardware blending. HDUtils.DrawFullScreen(cmd, parameters.cloudCombinePass, colorBuffer, null, 0); CoreUtils.SetKeyword(cmd, "USE_INTERMEDIATE_BUFFER", false); } else { cmd.SetComputeTextureParam(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, HDShaderIDs._VolumetricCloudsUpscaleTextureRW, colorBuffer); // Perform the upscale and combine with the color buffer in place. cmd.DispatchCompute(parameters.commonData.volumetricCloudsCS, parameters.combineKernel, finalTX, finalTY, parameters.viewCount); } } // Reset all the multi-compiles CoreUtils.SetKeyword(cmd, "LOCAL_VOLUMETRIC_CLOUDS", false); }
TextureHandle RenderUnderWaterVolume(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle colorBuffer, TextureHandle depthBuffer) { // Are we in the volume of any surface at all? if (m_UnderWaterSurfaceIndex == -1 || WaterSurface.instancesAsArray == null || !hdCamera.frameSettings.IsEnabled(FrameSettingsField.Water)) { return(colorBuffer); } // Execute the unique lighting pass using (var builder = renderGraph.AddRenderPass <UnderWaterRenderingData>("Render Under Water", out var passData, ProfilingSampler.Get(HDProfileId.WaterSurfaceRenderingUnderWater))) { // Fetch the water surface we will be using WaterSurface waterSurface = WaterSurface.instancesAsArray[m_UnderWaterSurfaceIndex]; // Prepare all the parameters passData.width = hdCamera.actualWidth; passData.height = hdCamera.actualHeight; passData.viewCount = hdCamera.viewCount; passData.waterLightingCS = m_WaterLightingCS; passData.underWaterKernel = m_UnderWaterKernel; // Fill the under water CB passData.underWaterCB._MaxViewDistanceMultiplier = waterSurface.absorbtionDistanceMultiplier; passData.underWaterCB._WaterScatteringColor = waterSurface.scatteringColor; passData.underWaterCB._WaterRefractionColor = waterSurface.refractionColor; passData.underWaterCB._OutScatteringCoeff = -Mathf.Log(0.02f) / waterSurface.absorptionDistance; passData.underWaterCB._WaterTransitionSize = waterSurface.transitionSize; // All the required textures passData.colorBuffer = builder.ReadTexture(colorBuffer); passData.depthBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read); passData.cameraHeightBuffer = builder.ReadComputeBuffer(renderGraph.ImportComputeBuffer(m_WaterCameraHeightBuffer)); // Bind the caustics buffer that may be required bool simulationCaustics = waterSurface.caustics && waterSurface.causticsAlgorithm == WaterSurface.WaterCausticsType.Simulation; passData.causticsData = simulationCaustics ? renderGraph.ImportTexture(waterSurface.simulation.causticsBuffer) : renderGraph.defaultResources.blackTexture; // Fill the water rendering CB passData.waterRenderingCB._CausticsIntensity = waterSurface.causticsIntensity; passData.waterRenderingCB._CausticsTiling = waterSurface.causticsTiling; passData.waterRenderingCB._CausticsPlaneBlendDistance = waterSurface.causticsPlaneBlendDistance; passData.waterRenderingCB._PatchOffset = waterSurface.transform.position; passData.waterRenderingCB._WaterCausticsType = waterSurface.caustics ? (simulationCaustics ? 0 : 1) : 0; // Fill the water CB passData.waterCB._CausticsRegionSize = waterSurface.simulation.patchSizes[waterSurface.causticsBand]; // Request the output textures passData.outputColorBuffer = builder.WriteTexture(CreateColorBuffer(m_RenderGraph, hdCamera, false)); // Run the deferred lighting builder.SetRenderFunc( (UnderWaterRenderingData data, RenderGraphContext ctx) => { // Evaluate the dispatch parameters int tileX = (data.width + 7) / 8; int tileY = (data.height + 7) / 8; // Bind the input gbuffer data ConstantBuffer.Push(ctx.cmd, data.underWaterCB, data.waterLightingCS, HDShaderIDs._ShaderVariablesUnderWater); ConstantBuffer.Push(ctx.cmd, data.waterRenderingCB, data.waterLightingCS, HDShaderIDs._ShaderVariablesWaterRendering); ConstantBuffer.Push(ctx.cmd, data.waterCB, data.waterLightingCS, HDShaderIDs._ShaderVariablesWater); ctx.cmd.SetComputeTextureParam(data.waterLightingCS, data.underWaterKernel, HDShaderIDs._WaterCausticsDataBuffer, data.causticsData); ctx.cmd.SetComputeTextureParam(data.waterLightingCS, data.underWaterKernel, HDShaderIDs._CameraColorTexture, data.colorBuffer); ctx.cmd.SetComputeTextureParam(data.waterLightingCS, data.underWaterKernel, HDShaderIDs._DepthTexture, data.depthBuffer); ctx.cmd.SetComputeTextureParam(data.waterLightingCS, data.underWaterKernel, HDShaderIDs._StencilTexture, data.depthBuffer, 0, RenderTextureSubElement.Stencil); ctx.cmd.SetComputeBufferParam(data.waterLightingCS, data.underWaterKernel, HDShaderIDs._WaterCameraHeightBuffer, data.cameraHeightBuffer); // Bind the output texture ctx.cmd.SetComputeTextureParam(data.waterLightingCS, data.underWaterKernel, HDShaderIDs._CameraColorTextureRW, data.outputColorBuffer); // Run the lighting ctx.cmd.DispatchCompute(data.waterLightingCS, data.underWaterKernel, tileX, tileY, data.viewCount); }); // Return the new color buffer return(passData.outputColorBuffer); } }