diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/5011_VolumetricClouds.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/5011_VolumetricClouds.png index 6b1b1ea6281..50dec5d791e 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/5011_VolumetricClouds.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/LinuxEditor/Vulkan/None/5011_VolumetricClouds.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ada3182a3c1273998acab0d7f504fd8ec9eca71f956f7939a065211d93235582 -size 246760 +oid sha256:540acb4a7d8b309257278d753f3779b1811acef2a49c784b952d865058f0f45a +size 245848 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/5011_VolumetricClouds.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/5011_VolumetricClouds.png index 33f664a069d..a2e3b2054ea 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/5011_VolumetricClouds.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/5011_VolumetricClouds.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:04f74e2a9286788d8292326c148acecfe1358e6f8ebea68a05591bf20fb2d0af -size 246611 +oid sha256:22a0e67a476dae1cf06f60974c64502fffe39f48f8db32f14e6dabe59bb17a75 +size 246378 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/5011_VolumetricClouds.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/5011_VolumetricClouds.png index b6a7fc2e009..4003424e7b1 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/5011_VolumetricClouds.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/5011_VolumetricClouds.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:39fc6fd45259bb85ad3a2d46a2a490c159bc0768a0cec9b1d65267339a5fb973 -size 247002 +oid sha256:965f032c9e7fa6e13146a09be1d5527e2ee79983443a41bb3673b1a43c73bf2f +size 245928 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5011_VolumetricClouds.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5011_VolumetricClouds.png index 874c7e438f1..310c9035f5e 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5011_VolumetricClouds.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D12/None/5011_VolumetricClouds.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0fa77da28f7786e859d755a59d85ad94ea18872af66f203955dadb99ba9d5c2a -size 246899 +oid sha256:e768be073080d68f05239328fb9c9a128f41fd1ef87117cedb35c702bc2d2c5a +size 246010 diff --git a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/5011_VolumetricClouds.png b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/5011_VolumetricClouds.png index 9ebbe3c0590..a1d67f66e6c 100644 --- a/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/5011_VolumetricClouds.png +++ b/TestProjects/HDRP_Tests/Assets/ReferenceImages/Linear/WindowsEditor/Vulkan/None/5011_VolumetricClouds.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ecb62e70616b5f8aec980e37ed86dea817418f1d418be341e2c3509e01253f1e -size 246734 +oid sha256:7669caad256b02acbf2935761f1ba135f1b00ddd131259f7b3fa8ab652bd80d5 +size 245928 diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 6380f9c0441..791a95f25a0 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed geometry scale issue with the Eye Shader. - Fixed motion vector buffer not accessible from custom passes in the BeforeTransparent, BeforePreRefraction and AfterDepthAndNormal injection points. - Fixed the point distribution for the diffuse denoiser sometimes not being properly intialized. +- Fixed the bad blending between the sun and the clouds (case 1373282). ### Changed - Use RayTracingAccelerationStructure.CullInstances to filter Renderers and populate the acceleration structure with ray tracing instances for improved CPU performance on the main thread. diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Override-Volumetric-Clouds.md b/com.unity.render-pipelines.high-definition/Documentation~/Override-Volumetric-Clouds.md index 0e0f6206315..e94abf18b88 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Override-Volumetric-Clouds.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Override-Volumetric-Clouds.md @@ -157,3 +157,4 @@ When importing these two map Textures, disable **sRGB**. For best results, do no * When enabled for [Reflection Probes](Reflection-Probe.md), the volumetric clouds are rendered at low resolution, without any form of temporal accumulation for performance and stability reasons. * By default volumetric clouds are enabled on the baked [Reflection Probes](Reflection-Probe.md) if the asset allows it. They are rendered at full resolution without any form of temporal accumulation. * Volumetric clouds do not appear in ray-traced effects. +* Transmittance is not applied linearly on the camera color to provide a better blending with the sun light (or high intensity pixels). If [Multi-sample anti-aliasing (MSAA)](#MSAA) is enabled on the camera, due to internal limitations, a different blending profile is used that may result in darker cloud edges. diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricClouds.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricClouds.cs index 68b65d2c71c..bf3bf6655f8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricClouds.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricClouds.cs @@ -455,7 +455,7 @@ void UpdateShaderVariableslClouds(ref ShaderVariablesClouds cb, HDCamera hdCamer // If this is a planar reflection, we need to compute the non oblique matrices cb._IsPlanarReflection = (cameraData.cameraType == TVolumetricCloudsCameraType.PlanarReflection) ? 1 : 0; - if (cameraData.cameraType == TVolumetricCloudsCameraType.PlanarReflection) + if (cb._IsPlanarReflection == 1) { // Build a non-oblique projection matrix var projectionMatrixNonOblique = Matrix4x4.Perspective(hdCamera.camera.fieldOfView, hdCamera.camera.aspect, hdCamera.camera.nearClipPlane, hdCamera.camera.farClipPlane); diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricCloudsAccumulation.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricCloudsAccumulation.cs index efd1587fb2f..bf0221fa854 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricCloudsAccumulation.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/HDRenderPipeline.VolumetricCloudsAccumulation.cs @@ -162,6 +162,10 @@ VolumetricCloudsParameters_Accumulation PrepareVolumetricCloudsParameters_Accumu 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; } @@ -198,8 +202,8 @@ static void TraceVolumetricClouds_Accumulation(CommandBuffer cmd, VolumetricClou parameters.commonData.cloudsCB._HistoryViewportSize = new Vector2(previousViewportSize.x, previousViewportSize.y); parameters.commonData.cloudsCB._HistoryBufferSize = new Vector2(previousHistory0Buffer.rt.width, previousHistory0Buffer.rt.height); - // Bind the constant buffer - ConstantBuffer.Push(cmd, parameters.commonData.cloudsCB, parameters.commonData.volumetricCloudsCS, HDShaderIDs._ShaderVariablesClouds); + // Bind the constant buffer (global as we need it for the .shader as well) + ConstantBuffer.PushGlobal(cmd, parameters.commonData.cloudsCB, HDShaderIDs._ShaderVariablesClouds); RTHandle currentDepthBuffer = depthPyramid; @@ -293,7 +297,7 @@ static void TraceVolumetricClouds_Accumulation(CommandBuffer cmd, VolumetricClou parameters.cloudCombinePass.SetTexture(HDShaderIDs._VolumetricCloudsUpscaleTextureRW, intermediateUpscaleBuffer); // Composite the clouds into the MSAA target via hardware blending. - HDUtils.DrawFullScreen(cmd, parameters.cloudCombinePass, colorBuffer); + HDUtils.DrawFullScreen(cmd, parameters.cloudCombinePass, colorBuffer, null, 0); CoreUtils.SetKeyword(cmd, "USE_INTERMEDIATE_BUFFER", false); } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricClouds.compute b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricClouds.compute index 224dc2614ab..aeeeb9406d6 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricClouds.compute +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricClouds.compute @@ -1401,13 +1401,13 @@ void UPSAMPLE_KERNEL(uint3 finalCoord : SV_DispatchThreadID, cloudPosInput.positionWS = -viewDir * cloudDistance; #endif +#ifdef USE_INTERMEDIATE_BUFFER // Compute the fog attenuation of the clouds float3 fogColor; float3 fogOpacity; EvaluateAtmosphericScattering(cloudPosInput, viewDir, fogColor, fogOpacity); - currentClouds.xyz = currentClouds.xyz * (1 - fogOpacity) + fogColor * (1.0 - currentClouds.a); + currentClouds.xyz = currentClouds.xyz * (1 - fogOpacity) + fogColor * (1.0 - (_CubicTransmittance ? currentClouds.a * currentClouds.a : currentClouds.a)); -#ifdef USE_INTERMEDIATE_BUFFER // Store the upscaled result only, composite in later pass. _VolumetricCloudsUpscaleTextureRW[COORD_TEXTURE2D_X(finalCoord.xy)] = currentClouds; #else @@ -1417,8 +1417,18 @@ void UPSAMPLE_KERNEL(uint3 finalCoord : SV_DispatchThreadID, #else float4 currentColor = _CameraColorTexture[COORD_TEXTURE2D_X(finalCoord.xy)]; #endif - // If this is a background pixel, we want the cloud value, otherwise we do not. - _VolumetricCloudsUpscaleTextureRW[COORD_TEXTURE2D_X(finalCoord.xy)] = float4(currentColor.xyz * currentClouds.a + currentClouds.xyz, currentColor.a); + + // Estimate the transmittance that shall be used + float finalTransmittance = EvaluateFinalTransmittance(currentColor, currentClouds.w); + + // Compute the fog attenuation of the clouds + float3 fogColor; + float3 fogOpacity; + EvaluateAtmosphericScattering(cloudPosInput, viewDir, fogColor, fogOpacity); + currentClouds.xyz = currentClouds.xyz * (1 - fogOpacity) + fogColor * (1.0 - finalTransmittance); + + // Apply the transmittance + _VolumetricCloudsUpscaleTextureRW[COORD_TEXTURE2D_X(finalCoord.xy)] = float4(currentColor.xyz * finalTransmittance + currentClouds.xyz, currentColor.a); #endif } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsCombine.shader b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsCombine.shader index 74b08af5263..27431259d63 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsCombine.shader +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsCombine.shader @@ -62,7 +62,9 @@ Shader "Hidden/HDRP/VolumetricCloudsCombine" UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); // Composite the result via hardware blending. - return LOAD_TEXTURE2D_X(_VolumetricCloudsUpscaleTextureRW, input.positionCS.xy); + // If MSAA is enabled on the camera, due to internal limitations, a different blending profile is used that may result in darker cloud edges. + float4 cloudData = LOAD_TEXTURE2D_X(_VolumetricCloudsUpscaleTextureRW, input.positionCS.xy); + return float4(cloudData.xyz, _CubicTransmittance ? cloudData.w * cloudData.w : cloudData.w); } ENDHLSL } diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs index a421259d3d6..f89139e4bc8 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs @@ -151,9 +151,11 @@ unsafe struct ShaderVariablesClouds // Flag that allows us to know if the maxZMask texture is valid public int _ValidMaxZMask; - // Padding - public int _Padding0; - public Vector2 _Padding1; + // Flag that allows to know if we should be using the improved transmittance blending + public int _ImprovedTransmittanceBlend; + // Flag that defines if the transmittance should follow a cubic profile (For MSAA) + public int _CubicTransmittance; + public int _Padding1; [HLSLArray(3 * 4, typeof(Vector4))] public fixed float _DistanceBasedWeights[12 * 4]; diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs.hlsl index bf976b0d046..80579aea9e0 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsDef.cs.hlsl @@ -71,8 +71,9 @@ CBUFFER_START(ShaderVariablesClouds) int _EnableFastToneMapping; int _IsPlanarReflection; int _ValidMaxZMask; - int _Padding0; - float2 _Padding1; + int _ImprovedTransmittanceBlend; + int _CubicTransmittance; + int _Padding1; float4 _DistanceBasedWeights[12]; CBUFFER_END diff --git a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsUtilities.hlsl b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsUtilities.hlsl index edacf33bb86..ba6574f5fff 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsUtilities.hlsl +++ b/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/VolumetricCloudsUtilities.hlsl @@ -499,6 +499,13 @@ void FillCloudUpscaleNeighborhoodData(int2 groupThreadId, int subRegionIdx, out neighborhoodData.lowWeightC = _DistanceBasedWeights[subRegionIdx * 3 + 2].x; } +float EvaluateFinalTransmittance(float3 color, float transmittance) +{ + // Due to the high intensity of the sun, we often need apply the transmittance in a tonemapped space + float3 resultColor = color / (1.0 + color) * transmittance; + resultColor = resultColor / (1.0 - resultColor); + return _ImprovedTransmittanceBlend ? (resultColor / color) : transmittance; +} #endif // REAL_TIME_VOLUMETRIC_CLOUDS #endif // VOLUMETRIC_CLOUD_UTILITIES_H