From 885d6a9d5bf568f7a1ab72b37de32963ec7679e1 Mon Sep 17 00:00:00 2001 From: John Parsaie Date: Fri, 7 Jul 2023 15:10:19 -0400 Subject: [PATCH] Begin support for resampling texcoord --- Editor/HairAssetBuilder.cs | 36 ++++++++++++++++++++++++------------ Runtime/HairAsset.cs | 1 + Runtime/HairSim.cs | 6 +++++- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Editor/HairAssetBuilder.cs b/Editor/HairAssetBuilder.cs index 7be424d..1d87203 100644 --- a/Editor/HairAssetBuilder.cs +++ b/Editor/HairAssetBuilder.cs @@ -24,7 +24,7 @@ using UnityEngine.Formats.Alembic.Importer; namespace Unity.DemoTeam.Hair { public static class HairAssetBuilder - { + { [Flags] public enum BuildFlags { @@ -401,12 +401,14 @@ namespace Unity.DemoTeam.Hair } // Use the blend weights to resample any non-positional data requested by the vertex features. - if (uniformCurveSet.vertexFeatures.HasFlag(HairAsset.VertexFeatures.Diameter) || - uniformCurveSet.vertexFeatures.HasFlag(HairAsset.VertexFeatures.TexCoord)) + if (uniformCurveSet.vertexFeatures.HasFlag(~HairAsset.VertexFeatures.Position)) { srcVertexOffset = 0; dstVertexOffset = 0; + bool resampleDiameter = uniformCurveSet.vertexFeatures.HasFlag(HairAsset.VertexFeatures.Diameter); + bool resampleTexCoord = uniformCurveSet.vertexFeatures.HasFlag(HairAsset.VertexFeatures.TexCoord); + for (int i = 0; i != curveSet.curveCount; i++) { for (int j = 0; j < dstVertexCount; j++) @@ -416,16 +418,12 @@ namespace Unity.DemoTeam.Hair var w = blendWeightsPtr[d]; var s0 = srcVertexOffset + (int) w.x; var s1 = srcVertexOffset + (int) w.y; - - if (uniformCurveSet.vertexFeatures.HasFlag(HairAsset.VertexFeatures.Diameter)) - { - dstDataDiameterPtr[d] = Mathf.Lerp(srcDataDiameterPtr[s0], srcDataDiameterPtr[s1], w.z); - } - if (uniformCurveSet.vertexFeatures.HasFlag(HairAsset.VertexFeatures.TexCoord)) - { + if (resampleDiameter) + dstDataDiameterPtr[d] = Mathf.Lerp(srcDataDiameterPtr[s0], srcDataDiameterPtr[s1], w.z); + + if (resampleTexCoord) dstDataTexCoordPtr[d] = Vector2.Lerp(srcDataTexCoordPtr[s0], srcDataTexCoordPtr[s1], w.z); - } } srcVertexOffset += srcVertexCountPtr[i]; @@ -463,7 +461,9 @@ namespace Unity.DemoTeam.Hair uniformCurveSet.curveCount * uniformVertexCount : 1; } - strandGroup.particleDiameter = new float[GetAllocationSize(HairAsset.VertexFeatures.Diameter)]; + // conserve disk space by allocating only the memory required by existing vertex features + strandGroup.particleDiameter = new float [GetAllocationSize(HairAsset.VertexFeatures.Diameter)]; + strandGroup.particleTexCoord = new Vector2[GetAllocationSize(HairAsset.VertexFeatures.TexCoord)]; } // build strand buffers @@ -558,12 +558,15 @@ namespace Unity.DemoTeam.Hair { var srcBasePositionPtr = uniformVertexDataPositionPtr; var srcBaseDiameterPtr = uniformVertexDataDiameterPtr; + var srcBaseTexCoordPtr = uniformVertexDataTexCoordPtr; var srcPositionLength = sizeof(Vector3) * uniformCurveSet.curveCount * uniformVertexCount; var srcDiameterLength = sizeof(float) * uniformCurveSet.curveCount * uniformVertexCount; + var srcTexCoordLength = sizeof(Vector2) * uniformCurveSet.curveCount * uniformVertexCount; fixed (Vector3* dstBasePositionPtr = strandGroup.particlePosition) fixed (float* dstBaseDiameterPtr = strandGroup.particleDiameter) + fixed (Vector2* dstBaseTexCoordPtr = strandGroup.particleTexCoord) { UnsafeUtility.MemCpy(dstBasePositionPtr, srcBasePositionPtr, srcPositionLength); @@ -576,6 +579,7 @@ namespace Unity.DemoTeam.Hair } MemCpyIfNeeded(HairAsset.VertexFeatures.Diameter, dstBaseDiameterPtr, srcBaseDiameterPtr, srcDiameterLength); + MemCpyIfNeeded(HairAsset.VertexFeatures.TexCoord, dstBaseTexCoordPtr, srcBaseTexCoordPtr, srcTexCoordLength); } } } @@ -586,15 +590,19 @@ namespace Unity.DemoTeam.Hair { var srcBasePositionPtr = uniformVertexDataPositionPtr; var srcBaseDiameterPtr = uniformVertexDataDiameterPtr; + var srcBaseTexCoordPtr = uniformVertexDataTexCoordPtr; var srcPositionStride = sizeof(Vector3); var srcDiameterStride = sizeof(float); + var srcTexCoordStride = sizeof(Vector2); var dstPositionStride = sizeof(Vector3) * strandGroup.strandCount; var dstDiameterStride = sizeof(float) * strandGroup.strandCount; + var dstTexCoordStride = sizeof(Vector2) * strandGroup.strandCount; fixed (Vector3* dstBasePositionPtr = strandGroup.particlePosition) fixed (float* dstBaseDiameterPtr = strandGroup.particleDiameter) + fixed (Vector2* dstBaseTexCoordPtr = strandGroup.particleTexCoord) { for (int i = 0; i != uniformCurveSet.curveCount; i++) { @@ -603,6 +611,9 @@ namespace Unity.DemoTeam.Hair var srcDiameterPtr = srcBaseDiameterPtr + i * uniformVertexCount; var dstDiameterPtr = dstBaseDiameterPtr + i; + + var srcTexCoordPtr = srcBaseTexCoordPtr + i * uniformVertexCount; + var dstTexCoordPtr = dstBaseTexCoordPtr + i; UnsafeUtility.MemCpyStride(dstPositionPtr, dstPositionStride, srcPositionPtr, srcPositionStride, srcPositionStride, uniformVertexCount); @@ -615,6 +626,7 @@ namespace Unity.DemoTeam.Hair } MemCpyStrideIfNeeded(HairAsset.VertexFeatures.Diameter, dstDiameterPtr, srcDiameterPtr, dstDiameterStride, srcDiameterStride, uniformVertexCount); + MemCpyStrideIfNeeded(HairAsset.VertexFeatures.TexCoord, dstTexCoordPtr, srcTexCoordPtr, dstTexCoordStride, srcTexCoordStride, uniformVertexCount); } } } diff --git a/Runtime/HairAsset.cs b/Runtime/HairAsset.cs index 4a3f281..1ca5ab8 100644 --- a/Runtime/HairAsset.cs +++ b/Runtime/HairAsset.cs @@ -457,6 +457,7 @@ namespace Unity.DemoTeam.Hair [HideInInspector] public uint vertexFeatureFlags; [HideInInspector] public float[] particleDiameter; + [HideInInspector] public Vector2[] particleTexCoord; [HideInInspector] public Vector3[] particlePosition; [HideInInspector] public MemoryLayout particleMemoryLayout; diff --git a/Runtime/HairSim.cs b/Runtime/HairSim.cs index 213356c..83c1d15 100644 --- a/Runtime/HairSim.cs +++ b/Runtime/HairSim.cs @@ -908,7 +908,11 @@ namespace Unity.DemoTeam.Hair target.BindComputeBuffer(UniformIDs._ParticlePositionCorr, solverData.particlePositionCorr); target.BindComputeBuffer(UniformIDs._ParticleVelocity, solverData.particleVelocity); target.BindComputeBuffer(UniformIDs._ParticleVelocityPrev, solverData.particleVelocityPrev); - target.BindComputeBuffer(UniformIDs._ParticleDiameter, solverData.particleDiameter); + + // optional vertex data + { + target.BindComputeBuffer(UniformIDs._ParticleDiameter, solverData.particleDiameter); + } target.BindComputeBuffer(UniformIDs._LODGuideCount, solverData.lodGuideCount); target.BindComputeBuffer(UniformIDs._LODGuideIndex, solverData.lodGuideIndex);