Skip to content

Fix Motion Vectors written by transparent when rendering with MSAA #315

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
May 6, 2020
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 @@ -578,6 +578,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed cookie texture not updated when changing an import settings (srgb for example).
- Fixed flickering of the game/scene view when lookdev is running.
- Fixed issue with reflection probes in realtime time mode with OnEnable baking having wrong lighting with sky set to dynamic (case 1238047).
- Fixed transparent motion vectors not working when in MSAA.

### Changed
- Improve MIP selection for decals on Transparents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class SharedRTManager
// MSAA resolve materials
Material m_DepthResolveMaterial = null;
Material m_ColorResolveMaterial = null;
Material m_MotionVectorResolve = null;

// Flags that defines if we are using a local texture or external
bool m_ReuseGBufferMemory = false;
Expand Down Expand Up @@ -94,6 +95,7 @@ public void InitSharedBuffers(GBufferManager gbufferManager, RenderPipelineSetti
// Create the required resolve materials
m_DepthResolveMaterial = CoreUtils.CreateEngineMaterial(resources.shaders.depthValuesPS);
m_ColorResolveMaterial = CoreUtils.CreateEngineMaterial(resources.shaders.colorResolvePS);
m_MotionVectorResolve = CoreUtils.CreateEngineMaterial(resources.shaders.resolveMotionVecPS);

CoreUtils.SetKeyword(m_DepthResolveMaterial, "_HAS_MOTION_VECTORS", m_MotionVectorsSupport);
}
Expand Down Expand Up @@ -310,6 +312,7 @@ public void Cleanup()
// Do not forget to release the materials
CoreUtils.Destroy(m_DepthResolveMaterial);
CoreUtils.Destroy(m_ColorResolveMaterial);
CoreUtils.Destroy(m_MotionVectorResolve);
}
}

Expand Down Expand Up @@ -372,6 +375,20 @@ public void ResolveSharedRT(CommandBuffer cmd, HDCamera hdCamera)
}
}
}

public void ResolveMotionVectorTexture(CommandBuffer cmd, HDCamera hdCamera)
{
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA) && m_MotionVectorsSupport)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.ResolveMSAAMotionVector)))
{
CoreUtils.SetRenderTarget(cmd, m_MotionVectorsRT, m_CameraDepthStencilBuffer);
Shader.SetGlobalTexture(HDShaderIDs._MotionVectorTextureMS, m_MotionVectorsMSAART);
cmd.DrawProcedural(Matrix4x4.identity, m_MotionVectorResolve, SampleCountToPassIndex(m_MSAASamples), MeshTopology.Triangles, 3, 1);
}
}
}

public void ResolveMSAAColor(CommandBuffer cmd, HDCamera hdCamera, RTHandle msaaTarget, RTHandle simpleTarget)
{
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ internal enum HDProfileId
RenderWireFrame,
PushToColorPicker,
ResolveMSAAColor,
ResolveMSAAMotionVector,
ResolveMSAADepth,
ConvolveReflectionProbe,
ConvolvePlanarReflectionProbe,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ void ExecuteWithRenderGraph( RenderRequest renderRequest,

colorBuffer = RenderTransparency(m_RenderGraph, hdCamera, colorBuffer, prepassOutput.depthBuffer, prepassOutput.motionVectorsBuffer, currentColorPyramid, prepassOutput.depthPyramidTexture, shadowResult, cullingResults);

if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.TransparentsWriteMotionVector))
{
prepassOutput.motionVectorsBuffer = ResolveMotionVector(m_RenderGraph, hdCamera, prepassOutput.motionVectorsBuffer);
}

// TODO RENDERGRAPH : Move this to the end after we do move semantic and graph pruning to avoid doing the rest of the frame for nothing
// Transparent objects may write to the depth and motion vectors buffers.
aovRequest.PushCameraTexture(m_RenderGraph, AOVBuffers.DepthStencil, hdCamera, prepassOutput.resolvedDepthBuffer, aovBuffers);
Expand Down Expand Up @@ -1015,6 +1020,48 @@ TextureHandle ResolveMSAAColor(RenderGraph renderGraph, HDCamera hdCamera, Textu
}
}

class ResolveMotionVectorData
{
public TextureHandle input;
public TextureHandle output;
public Material resolveMaterial;
public int passIndex;
}

TextureHandle ResolveMotionVector(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle input)
{
if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.MSAA))
{
using (var builder = renderGraph.AddRenderPass<ResolveMotionVectorData>("ResolveMotionVector", out var passData))
{
var outputDesc = renderGraph.GetTextureDesc(input);
outputDesc.enableMSAA = false;
outputDesc.enableRandomWrite = true;
outputDesc.bindTextureMS = false;
outputDesc.name = string.Format("{0}Resolved", outputDesc.name);

passData.input = builder.ReadTexture(input);
passData.output = builder.UseColorBuffer(renderGraph.CreateTexture(outputDesc), 0);
passData.resolveMaterial = m_MotionVectorResolve;
passData.passIndex = SampleCountToPassIndex(m_MSAASamples);

builder.SetRenderFunc(
(ResolveColorData data, RenderGraphContext context) =>
{
var res = context.resources;
var mpb = context.renderGraphPool.GetTempMaterialPropertyBlock();
mpb.SetTexture(HDShaderIDs._MotionVectorTextureMS, res.GetTexture(data.input));
context.cmd.DrawProcedural(Matrix4x4.identity, data.resolveMaterial, data.passIndex, MeshTopology.Triangles, 3, 1, mpb);
});

return passData.output;
}
}
else
{
return input;
}
}
#if UNITY_EDITOR
class RenderGizmosPassData
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ internal bool showCascade

// MSAA resolve materials
Material m_ColorResolveMaterial = null;
Material m_MotionVectorResolve = null;

// Flag that defines if ray tracing is supported by the current asset and platform
bool m_RayTracingSupported = false;
Expand Down Expand Up @@ -513,6 +514,7 @@ public HDRenderPipeline(HDRenderPipelineAsset asset, HDRenderPipelineAsset defau

InitializePrepass(m_Asset);
m_ColorResolveMaterial = CoreUtils.CreateEngineMaterial(asset.renderPipelineResources.shaders.colorResolvePS);
m_MotionVectorResolve = CoreUtils.CreateEngineMaterial(asset.renderPipelineResources.shaders.resolveMotionVecPS);

InitializeProbeVolumes();
}
Expand Down Expand Up @@ -975,6 +977,7 @@ protected override void Dispose(bool disposing)
m_RenderGraph.UnRegisterDebug();
CleanupPrepass();
CoreUtils.Destroy(m_ColorResolveMaterial);
CoreUtils.Destroy(m_MotionVectorResolve);

#if UNITY_EDITOR
SceneViewDrawMode.ResetDrawMode();
Expand Down Expand Up @@ -2481,6 +2484,11 @@ void Callback(CommandBuffer c, HDCamera cam)
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForwardTransparent(cullingResults, hdCamera, false, renderContext, cmd);

if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.TransparentsWriteMotionVector))
{
m_SharedRTManager.ResolveMotionVectorTexture(cmd, hdCamera);
}

// We push the motion vector debug texture here as transparent object can overwrite the motion vector texture content.
if(m_Asset.currentPlatformRenderPipelineSettings.supportMotionVectors)
PushFullScreenDebugTexture(hdCamera, cmd, m_SharedRTManager.GetMotionVectorsBuffer(), FullScreenDebugMode.MotionVectors);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
Shader "Hidden/HDRP/MotionVecResolve"
{
HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 playstation xboxone vulkan metal switch

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
// #pragma enable_d3d11_debug_symbols

// Target multisampling textures
TEXTURE2D_X_MSAA(float2, _MotionVectorTextureMS);

struct Attributes
{
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};

struct Varyings
{
float4 positionCS : SV_POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};

struct FragOut
{
float2 motionVectors : SV_Target0;
};

Varyings Vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID) * _ScreenSize.xy;
return output;
}

FragOut Frag1X(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
FragOut fragO;
int2 pixelCoords = int2(input.texcoord);
fragO.motionVectors = LOAD_TEXTURE2D_X_MSAA(_MotionVectorTextureMS, pixelCoords, 0);
return fragO;
}

FragOut Frag2X(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
FragOut fragO;
int2 pixelCoords = int2(input.texcoord);
float2 outMotionVec = 0;
for(int sampleIdx = 0; sampleIdx < 2; ++sampleIdx)
{
outMotionVec += LOAD_TEXTURE2D_X_MSAA(_MotionVectorTextureMS, pixelCoords, sampleIdx);
}
fragO.motionVectors = outMotionVec * 0.5f;
return fragO;
}

FragOut Frag4X(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
FragOut fragO;
int2 pixelCoords = int2(input.texcoord);
float2 outMotionVec = 0;
for(int sampleIdx = 0; sampleIdx < 4; ++sampleIdx)
{
outMotionVec += LOAD_TEXTURE2D_X_MSAA(_MotionVectorTextureMS, pixelCoords, sampleIdx);
}
fragO.motionVectors = outMotionVec * 0.25f;

return fragO;
}

FragOut Frag8X(Varyings input)
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
FragOut fragO;
int2 pixelCoords = int2(input.texcoord);
float2 outMotionVec = 0;
for(int sampleIdx = 0; sampleIdx < 8; ++sampleIdx)
{
outMotionVec += LOAD_TEXTURE2D_X_MSAA(_MotionVectorTextureMS, pixelCoords, sampleIdx);
}
fragO.motionVectors = outMotionVec * 0.125f;
return fragO;
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }

// 0: MSAA 1x
Pass
{
ZWrite On ZTest Always Blend Off Cull Off

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag1X
ENDHLSL
}

// 1: MSAA 2x
Pass
{
ZWrite On ZTest Always Blend Off Cull Off

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag2X
ENDHLSL
}

// 2: MSAA 4X
Pass
{
ZWrite On ZTest Always Blend Off Cull Off

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag4X
ENDHLSL
}

// 3: MSAA 8X
Pass
{
ZWrite On ZTest Always Blend Off Cull Off

HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Frag8X
ENDHLSL
}
}
Fallback Off
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ public sealed class ShaderResources
public Shader depthValuesPS;
[Reload("Runtime/RenderPipeline/RenderPass/MSAA/ColorResolve.shader")]
public Shader colorResolvePS;
[Reload("Runtime/RenderPipeline/RenderPass/MSAA/MotionVecResolve.shader")]
public Shader resolveMotionVecPS;

// Post-processing
[Reload("Runtime/PostProcessing/Shaders/AlphaCopy.compute")]
Expand Down