Skip to content

Fix for volumetric clouds performing Read and Write on same texture [Unsupported on some platforms] #4356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.render-pipelines.high-definition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed fog precision in some camera positions (case 1329603).
- Fixed contact shadows tile coordinates calculations.
- Fixed issue with history buffer allocation for AOVs when the request does not come in first frame.
- Fix Clouds on Metal or platforms that don't support RW in same shader of R11G11B10 textures.

### Changed
- Changed Window/Render Pipeline/HD Render Pipeline Wizard to Window/Rendering/HDRP Wizard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,6 @@ public override void OnEnable()

public override void OnInspectorGUI()
{
#if UNITY_EDITOR
UnityEditor.BuildTarget activeBuildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
if (activeBuildTarget == UnityEditor.BuildTarget.StandaloneOSX)
#else
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal)
#endif
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Volumetric Clouds are not supported on the current target platform.", MessageType.Error, wide: true);
return;
}

// This whole editor has nothing to display if the SSR feature is not supported
HDRenderPipelineAsset currentAsset = HDRenderPipeline.currentAsset;
if (!currentAsset?.currentPlatformRenderPipelineSettings.supportVolumetricClouds ?? false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public partial class HDRenderPipeline
int m_CloudDownscaleDepthKernel;
int m_CloudRenderKernel;
int m_CloudReprojectKernel;
int m_UpscaleAndCombineCloudsKernel;
int m_UpscaleAndCombineCloudsKernelColorCopy;
int m_UpscaleAndCombineCloudsKernelColorRW;

void InitializeVolumetricClouds()
{
Expand All @@ -39,7 +40,8 @@ void InitializeVolumetricClouds()
m_CloudDownscaleDepthKernel = volumetricCloudsCS.FindKernel("DownscaleDepth");
m_CloudRenderKernel = volumetricCloudsCS.FindKernel("RenderClouds");
m_CloudReprojectKernel = volumetricCloudsCS.FindKernel("ReprojectClouds");
m_UpscaleAndCombineCloudsKernel = volumetricCloudsCS.FindKernel("UpscaleAndCombineClouds");
m_UpscaleAndCombineCloudsKernelColorCopy = volumetricCloudsCS.FindKernel("UpscaleAndCombineClouds_ColorCopy");
m_UpscaleAndCombineCloudsKernelColorRW = volumetricCloudsCS.FindKernel("UpscaleAndCombineClouds_ColorRW");

// Allocate all the texture initially
AllocatePresetTextures();
Expand Down Expand Up @@ -141,14 +143,6 @@ static RTHandle RequestPreviousVolumetricCloudsHistoryTexture1(HDCamera hdCamera
// Function to evaluate if a camera should have volumetric clouds
static bool HasVolumetricClouds(HDCamera hdCamera, in VolumetricClouds settings)
{
#if UNITY_EDITOR
UnityEditor.BuildTarget activeBuildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
if (activeBuildTarget == UnityEditor.BuildTarget.StandaloneOSX)
return false;
#else
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal)
return false;
#endif
// If the current volume does not enable the feature, quit right away.
return hdCamera.frameSettings.IsEnabled(FrameSettingsField.VolumetricClouds) && settings.enable.value;
}
Expand All @@ -172,6 +166,7 @@ struct VolumetricCloudsParameters
public int viewCount;
public bool historyValidity;
public bool planarReflection;
public bool needExtraColorBufferCopy;
public Vector2Int previousViewportSize;

// Static textures
Expand Down Expand Up @@ -444,13 +439,21 @@ VolumetricCloudsParameters PrepareVolumetricCloudsParameters(HDCamera hdCamera,
parameters.historyValidity = historyValidity;
parameters.planarReflection = (hdCamera.camera.cameraType == CameraType.Reflection);

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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can add one more check here for MSAA, I think we can close #4345

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes good point, MSAA fix should be integrate in this PR



// Compute shader and kernels
parameters.volumetricCloudsCS = m_Asset.renderPipelineResources.shaders.volumetricCloudsCS;
parameters.convertObliqueDepthKernel = m_ConvertObliqueDepthKernel;
parameters.depthDownscaleKernel = m_CloudDownscaleDepthKernel;
parameters.renderKernel = m_CloudRenderKernel;
parameters.reprojectKernel = m_CloudReprojectKernel;
parameters.upscaleAndCombineKernel = m_UpscaleAndCombineCloudsKernel;
parameters.upscaleAndCombineKernel = parameters.needExtraColorBufferCopy ? m_UpscaleAndCombineCloudsKernelColorCopy : m_UpscaleAndCombineCloudsKernelColorRW;
parameters.shadowsKernel = m_ComputeShadowCloudsKernel;

// Static textures
Expand Down Expand Up @@ -486,7 +489,8 @@ static void TraceVolumetricClouds(CommandBuffer cmd, VolumetricCloudsParameters
RTHandle colorBuffer, RTHandle depthPyramid, TextureHandle motionVectors, TextureHandle volumetricLightingTexture, TextureHandle scatteringFallbackTexture,
RTHandle currentHistory0Buffer, RTHandle previousHistory0Buffer,
RTHandle currentHistory1Buffer, RTHandle previousHistory1Buffer,
RTHandle intermediateLightingBuffer0, RTHandle intermediateLightingBuffer1, RTHandle intermediateDepthBuffer0, RTHandle intermediateDepthBuffer1, RTHandle intermediateDepthBuffer2)
RTHandle intermediateLightingBuffer0, RTHandle intermediateLightingBuffer1, RTHandle intermediateDepthBuffer0, RTHandle intermediateDepthBuffer1, RTHandle intermediateDepthBuffer2,
RTHandle intermediateColorBuffer)
{
// Compute the number of tiles to evaluate
int traceTX = (parameters.traceWidth + (8 - 1)) / 8;
Expand Down Expand Up @@ -574,11 +578,17 @@ static void TraceVolumetricClouds(CommandBuffer cmd, VolumetricCloudsParameters

using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.VolumetricCloudsUpscaleAndCombine)))
{
if (parameters.needExtraColorBufferCopy)
{
HDUtils.BlitCameraTexture(cmd, colorBuffer, intermediateColorBuffer);
}

// Compute the final resolution parameters
cmd.SetComputeTextureParam(parameters.volumetricCloudsCS, parameters.upscaleAndCombineKernel, HDShaderIDs._DepthTexture, currentDepthBuffer);
cmd.SetComputeTextureParam(parameters.volumetricCloudsCS, parameters.upscaleAndCombineKernel, HDShaderIDs._DepthStatusTexture, currentHistory1Buffer);
cmd.SetComputeTextureParam(parameters.volumetricCloudsCS, parameters.upscaleAndCombineKernel, HDShaderIDs._VolumetricCloudsTexture, currentHistory0Buffer);
cmd.SetComputeTextureParam(parameters.volumetricCloudsCS, parameters.upscaleAndCombineKernel, HDShaderIDs._CameraColorTextureRW, colorBuffer);
cmd.SetComputeTextureParam(parameters.volumetricCloudsCS, parameters.upscaleAndCombineKernel, HDShaderIDs._CameraColorTexture, intermediateColorBuffer);
cmd.SetComputeTextureParam(parameters.volumetricCloudsCS, parameters.upscaleAndCombineKernel, HDShaderIDs._VBufferLighting, volumetricLightingTexture);
if (parameters.cloudsCB._PhysicallyBasedSun == 0)
{
Expand Down Expand Up @@ -612,6 +622,8 @@ class VolumetricCloudsData
public TextureHandle intermediateBufferDepth0;
public TextureHandle intermediateBufferDepth1;
public TextureHandle intermediateBufferDepth2;

public TextureHandle intermediateColorBufferCopy;
}

private bool EvaluateVolumetricCloudsHistoryValidity(HDCamera hdCamera)
Expand Down Expand Up @@ -653,6 +665,10 @@ TextureHandle TraceVolumetricClouds(RenderGraph renderGraph, HDCamera hdCamera,
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.planarReflection)
{
passData.intermediateBufferDepth2 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
Expand All @@ -669,7 +685,7 @@ TextureHandle TraceVolumetricClouds(RenderGraph renderGraph, HDCamera hdCamera,
TraceVolumetricClouds(ctx.cmd, data.parameters,
data.colorBuffer, data.depthPyramid, data.motionVectors, data.volumetricLighting, data.scatteringFallbackTexture,
data.currentHistoryBuffer0, data.previousHistoryBuffer0, data.currentHistoryBuffer1, data.previousHistoryBuffer1,
data.intermediateBuffer0, data.intermediateBuffer1, data.intermediateBufferDepth0, data.intermediateBufferDepth1, data.intermediateBufferDepth2);
data.intermediateBuffer0, data.intermediateBuffer1, data.intermediateBufferDepth0, data.intermediateBufferDepth1, data.intermediateBufferDepth2, data.intermediateColorBufferCopy);
});

PushFullScreenDebugTexture(m_RenderGraph, passData.currentHistoryBuffer0, FullScreenDebugMode.VolumetricClouds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
#pragma kernel DownscaleDepth
#pragma kernel RenderClouds
#pragma kernel ReprojectClouds
#pragma kernel UpscaleAndCombineClouds
#pragma kernel UpscaleAndCombineClouds_ColorRW UPSAMPLE_KERNEL=UpscaleAndCombineClouds_ColorRW CAN_RW_ON_COLOR_BUFFER
#pragma kernel UpscaleAndCombineClouds_ColorCopy UPSAMPLE_KERNEL=UpscaleAndCombineClouds_ColorCopy
#pragma kernel ComputeVolumetricCloudsShadow

#pragma multi_compile _ PHYSICALLY_BASED_SUN
Expand Down Expand Up @@ -941,6 +942,9 @@ TEXTURE2D_X(_VolumetricCloudsTexture);
TEXTURE2D_X(_DepthStatusTexture);

// Input output camera color buffer
#ifndef CAN_RW_ON_COLOR_BUFFER
TEXTURE2D_X(_CameraColorTexture);
#endif
RW_TEXTURE2D_X(float4, _CameraColorTextureRW);

void FillLDSUpscale(uint groupIndex, uint2 groupOrigin)
Expand Down Expand Up @@ -973,7 +977,7 @@ void FillLDSUpscale(uint groupIndex, uint2 groupOrigin)
}

[numthreads(8, 8, 1)]
void UpscaleAndCombineClouds(uint3 finalCoord : SV_DispatchThreadID,
void UPSAMPLE_KERNEL(uint3 finalCoord : SV_DispatchThreadID,
int groupIndex : SV_GroupIndex,
uint2 groupThreadId : SV_GroupThreadID,
uint2 groupId : SV_GroupID)
Expand Down Expand Up @@ -1001,7 +1005,11 @@ void UpscaleAndCombineClouds(uint3 finalCoord : SV_DispatchThreadID,
float highDepth = LOAD_TEXTURE2D_X(_DepthTexture, finalCoord.xy).x;

// Read the color buffer
#ifdef CAN_RW_ON_COLOR_BUFFER
float4 currentColor = _CameraColorTextureRW[COORD_TEXTURE2D_X(finalCoord.xy)];
#else
float4 currentColor = _CameraColorTexture[COORD_TEXTURE2D_X(finalCoord.xy)];
#endif

// Fill the sample data
FillCloudUpscaleNeighborhoodData(groupThreadId.xy, upsampleData);
Expand Down