-
Notifications
You must be signed in to change notification settings - Fork 855
[Feature] Skinned motion vectors for HDRP Hybrid #3224
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
Conversation
- Add separate shader for skinning - Set DOTS_SKINNING define for all passes when hybrid v2 is enabled - Add new builtin property that determines if skinning should be applied
…ing the object itself.
com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDTarget.cs
Outdated
Show resolved
Hide resolved
com.unity.shadergraph/Editor/Generation/Descriptors/PragmaDescriptor.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.high-definition/Editor/Material/ShaderGraph/HDShaderPasses.cs
Outdated
Show resolved
Hide resolved
com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/Skinning.hlsl
Outdated
Show resolved
Hide resolved
#define PackVaryingsType PackVaryingsToPS | ||
#endif | ||
|
||
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/DotsDeformation.hlsl" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
surround with dots instancing on define?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
… vertices from compute buffer in ShaderVariablesFunctions
…ward/GBuffer, Depth/DepthNormal, ShadowCaster, Unlit, PostProcessing, ScreenSpaceShadows, SimpleLit-Forward/GBiffer, PreviewPass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested with and without dots repo PR.
Same review as here: https://github.com/Unity-Technologies/dots/pull/7101#pullrequestreview-589699280
Please take a look at the few issues mentioned in test doc: https://confluence.unity3d.com/display/HDRP/%5BHybrid%5D+Skinned+motion+vectors+for+HDRP+Hybrid
m_ShaderVariablesGlobalCB._SpecularOcclusionBlend = 1.0f; | ||
} | ||
|
||
m_ShaderVariablesGlobalCB._HybridDeformedVertexStreamIndex = UnityEngine.Time.frameCount & 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to use
UnityEngine.Time.frameCount here. we have get so many issue with it (#3173)
We have a FrameCount per Camera. So I guess here we should use camera.GetCameraFrameCount();
cc @adrien-de-tocqueville / @JulienIgnace-Unity for confirmation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, UnityEngine.Time.frameCount is not always incremented in the editor
uniform StructuredBuffer<DeformedVertexData> _PreviousFrameDeformedMeshData; | ||
|
||
// Reads vertex data for compute skinned meshes in Hybdrid Renderer | ||
void FetchComputeVertexData(inout AttributesMesh input) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this almost a duplication of this: https://github.com/Unity-Technologies/Graphics/pull/3224/files#diff-a6dc0267c305f8c7397a906b7ccdb070d168bd45350cac9b7b75ceaef24f2e44R14 ? Can't we share more code there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same below FetchComputeVertexPosition. Or maybe the question is more, why do we have code in Core package if it need to be rewrite per pipeline anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah now I read more code I udnerstand that the Core version is the URP version. Core shouldn't be use as URP code, Core is also use for custom SRP. So the code specific to pipeline must in in pipeline.
const int prevMeshStart = deformProperty[prevStreamIndex]; | ||
|
||
if(prevMeshStart == -1) | ||
prevPos = _DeformedMeshData[prevMeshStart + vertexID].Position; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggetsion / Remark. It could be more efficient to have a single StructuredBuffer with both the previous and current position and dealing with and offset instead of branching on buffer read like this which waste VGPR.
i.e
StructuredBuffer _FrameDeformedMeshData
int offset = (prevMeshStart == -1) ? 0 : nextStart;
offset += vertexID;
prevPos = _FrameDeformedMeshData[offset].Position;
=> no branch, less sgpr/vgpr use to store the two uniform structureBuffer.
thought?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm currently I am confuse by the code, it looks like you alrady do that. with prevMeshStart and currMeshStart , so why is there a different _PreviousFrameDeformedMeshData structure buffer?
sorry if my question is stupid I don't know the underlaying of DOTS skinning
currPos = _DeformedMeshData[currMeshStart + vertexID].Position; | ||
} | ||
|
||
const int skinMotionVec = deformProperty.w; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't deformProperty.w; be dependent on deformProperty.z; ?
i.e we can have skinMotionVector only if computeSkin is true. Right now the code allow to have skin motion vector without skin which seems weird.
float3 deformedPrevPos = inputPass.previousPositionOS; | ||
|
||
#if defined(DOTS_INSTANCING_ON) | ||
FetchComputeVertexPosition(inputMesh.positionOS, deformedPrevPos, inputMesh.vertexID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: is dots skinning cumulative with regular skinning?
inputPass.previousPositionOS contain the previous skinned mesh if any otherwise it is empty, so I am curious.
Also not all DOTS instancing object have skin right? And in this case there is no need to call FetchComputeVertexPosition?
I have the feeling that we should rather have a code like this:
#if defined(DOTS_INSTANCING_ON)
bool hasDeformation = asint(unity_DOTSDeformationParams).z; // DOTS skinning
if (hasDeformation)
FetchComputeVertexPosition(inputMesh.positionOS, inputPass.previousPositionOS, inputMesh.vertexID);
#else
bool hasDeformation = unity_MotionVectorsParams.x > 0.0; // Skin or morph target
#endif
float3 effectivePositionOS = (hasDeformation ? inputPass.previousPositionOS: inputMesh.positionOS);
Thought?
|
||
// Reads vertex position for compute skinned meshes in Hybdrid Renderer | ||
// and also previous frame position if skinned motion vectors are used | ||
void FetchComputeVertexPosition(inout float3 currPos, inout float3 prevPos, uint vertexID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why inout float3 currPos, inout float3 prevPos are currently inout? they should be out only no ?
#endif | ||
|
||
#ifdef DOTS_INSTANCING_ON | ||
uint vertexID : SV_VertexID; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: be sure this compile on DX12 / PS4 / Xbox. We have get various surprise with system sematic ordering on those platform (with double sided, instance id etc...)
also we need to use VERTEXID_SEMANTIC and not SV_VertexID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Guess for now Vertex_ID is only used with skinned mesh right?
so it should not be define when DOTS_INSTANCING_ON is on, but when DOTS_SKINNING_INSTANCING_ON ? (which doesnt exist but you get the idea). Just wondering :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok reading more code it seems that we can only know dynamically if we use skinning or not, so fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall the PR seems good, I have just various question and suggestion but it could be related to my non knowledge of dots intancing code.
…enerated unique GUID. Fixes GUID conflict with the HDRP version of DotsDeformation.hlsl.meta
Hey, is there any new about this PR, is it going to be merge? |
@hedvigaxelsson guess this PR have landed in private repo? can you close this one then? thanks |
Purpose of this PR
Adding support for deformed motion vectors for High-Definition RP Hybrid. Universal RP does not currently support motion vectors, but changes relating to Compute Deformation Node has been applied there as well.
Before (TAA + Motion Blur)


After (TAA + Motion Blur)
Changes
Compute Deformation Node has been removed

Skinned meshes will now use compute skinning path as default when Hybrid Renderer is used and ENABLE_COMPUTE_DEFORMATION define is set in the project.
This means meshes will automatically get the Vertex ID property, and that default HDRP Shaders (like Lit) now supports skinning without the need to add a custom node.
Linear Blend Skinning Node does not support skinned motion vectors.
These changes are dependent on following changes for Hybrid Renderer in DOTS repo: https://github.com/Unity-Technologies/dots/pull/7101
Testing status
Notes for testing:
Comments to reviewers
This adds a variable to global HDRP cbuffer.
https://github.com/Unity-Technologies/Graphics/pull/3224/files#diff-b237e8d61dae81c57d2ccfaee3b722f7d75a872b97368e3ba79ecfb6f79182e4
It would be preferable if this variable could be in the same place for both Universal and HDRP, any suggestions on where that would be is welcome.