Skip to content

Conversation

he-ax
Copy link
Contributor

@he-ax he-ax commented Jan 21, 2021

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)
hybridhdrp_no_skinned_motionvecs
After (TAA + Motion Blur)
hybridhdrp_skinned_motionvecs


Changes

Compute Deformation Node has been removed
no_deform_node
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

  • Tested with HDRP Example project in DOTS Animation samples.
  • Tested with HybrdDHRPSamples project.
  • Tested with HybridURPSamples project.

Notes for testing:

  • Everything should compile with/without ENABLE_COMPUTE_DEFORMATION define.
  • Graphics packages should compile without linked Hybrid Renderer changes (even with Hybrid Renderer package included), but Compute Deformations will not work.
  • Verify that adding VertexID by default when DOTS_INSTANCING define is enabled does not break Shader Graph functionality.

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.

#define PackVaryingsType PackVaryingsToPS
#endif

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/ShaderPass/DotsDeformation.hlsl"
Copy link
Contributor Author

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?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes

@he-ax he-ax changed the title [Feature] Skinned motion vectors for HDRP Hybrid DRAFT [Feature] Skinned motion vectors for HDRP Hybrid Jan 27, 2021
@nigeljw-unity nigeljw-unity self-requested a review February 12, 2021 10:23
@cinight cinight self-requested a review February 12, 2021 10:24
@TomasKiniulis TomasKiniulis self-requested a review February 12, 2021 10:50
@sebastienlagarde sebastienlagarde self-requested a review February 12, 2021 17:43
Copy link
Contributor

@TomasKiniulis TomasKiniulis left a 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;
Copy link
Contributor

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.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

Copy link
Contributor

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?

Copy link
Contributor

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

@sebastienlagarde sebastienlagarde Feb 12, 2021

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?

Copy link
Contributor

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

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

@sebastienlagarde sebastienlagarde Feb 12, 2021

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

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

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

Copy link
Contributor

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 :)

Copy link
Contributor

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.

Copy link
Contributor

@sebastienlagarde sebastienlagarde left a 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
@sebastienlagarde
Copy link
Contributor

Hey, is there any new about this PR, is it going to be merge?

@sebastienlagarde
Copy link
Contributor

@hedvigaxelsson guess this PR have landed in private repo? can you close this one then? thanks

@he-ax he-ax closed this May 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants