Netcode Bootstrap

This commit is contained in:
Luis Gonzalez
2026-05-31 14:27:52 -07:00
parent 99d8d2d2a9
commit 7fa77ce821
1813 changed files with 2921554 additions and 84 deletions
@@ -0,0 +1,90 @@
#pragma once
/////////////////////////////////////////////////////////////////////////////////
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/ShaderConf.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/Debug.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/DeformationCommon.hlsl"
#ifdef RUKHANKA_INPLACE_SKINNING
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/Skinning.hlsl"
#endif
#ifdef RUKHANKA_HALF_DEFORMED_DATA
StructuredBuffer<PackedDeformedVertex> _DeformedMeshData;
#else
StructuredBuffer<DeformedVertex> _DeformedMeshData;
#endif
#undef _DeformedMeshIndex
#undef _DeformationParamsForMotionVectors
/////////////////////////////////////////////////////////////////////////////////
DeformedVertex GetDeformedVertexForMesh(uint vertexID, DeformedVertex originalVertex, uint vertexOffsetOrMeshIndex)
{
#ifndef RUKHANKA_INPLACE_SKINNING
uint vertexOffsetForMesh = vertexOffsetOrMeshIndex;
#ifdef RUKHANKA_HALF_DEFORMED_DATA
PackedDeformedVertex vertexData = _DeformedMeshData[vertexOffsetForMesh + vertexID];
DeformedVertex rv = vertexData.Unpack();
#else
DeformedVertex rv = _DeformedMeshData[vertexOffsetForMesh + vertexID];
#endif // RUKHANKA_HALF_DEFORMED_DATA
//-------- Inplace skinning code path -------------//
#else
DeformedVertex rv = originalVertex;
uint meshIndex = vertexOffsetOrMeshIndex;
if (meshIndex != 0xffffffff)
{
MeshFrameDeformationDescription mfd = frameDeformedMeshes[meshIndex];
uint absoluteInputMeshVertexIndex = vertexID + mfd.baseInputMeshVertexIndex;
SourceSkinnedMeshVertex smv = SourceSkinnedMeshVertex::ReadFromRawBuffer(inputMeshVertexData, absoluteInputMeshVertexIndex);
rv = ApplyBlendShapes(rv, vertexID, mfd);
rv = ApplySkinMatrices(rv, smv.boneWeightsOffset, smv.boneWeightsCount, mfd);
}
else
{
rv = (DeformedVertex)0;
}
#endif
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
void ComputeDeformedVertex_float(in uint vertexID, in float3 vertex, in float3 normal, in float3 tangent, out float3 deformedVertex, out float3 deformedNormal, out float3 deformedTangent)
{
deformedVertex = vertex;
deformedNormal = normal;
deformedTangent = tangent;
#ifdef DOTS_INSTANCING_ON
#ifdef RUKHANKA_ENABLE_DEFORMATION_MOTION_VECTORS
const uint4 materialProperty = asuint(UNITY_ACCESS_DOTS_INSTANCED_PROP(float4, _DeformationParamsForMotionVectors));
const uint currentFrameIndex = materialProperty[2];
const uint index = materialProperty[currentFrameIndex];
#else
const uint index = asuint(UNITY_ACCESS_DOTS_INSTANCED_PROP(float, _DeformedMeshIndex));
#endif // RUKHANKA_ENABLE_DEFORMATION_MOTION_VECTORS
DeformedVertex v;
v.position = deformedVertex;
v.normal = deformedNormal;
v.tangent = deformedTangent;
v = GetDeformedVertexForMesh(vertexID, v, index);
deformedVertex = v.position;
deformedNormal = v.normal;
deformedTangent = v.tangent;
#endif // DOTS_INSTANCING_ON
}
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: a387024f61981304ca17ea1e3ffd997b
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/ComputeDeformedVertex.hlsl
uploadId: 897522
@@ -0,0 +1,52 @@
#ifndef COPY_INITIAL_MESH_BLEND_SHAPES_HLSL_
#define COPY_INITIAL_MESH_BLEND_SHAPES_HLSL_
/////////////////////////////////////////////////////////////////////////////////
ByteAddressBuffer meshBlendShapesBuffer;
RWByteAddressBuffer outInitialMeshBlendShapesData;
uint inputBlendShapeVerticesCount;
uint inputBlendShapeVertexOffset;
uint outBlendShapeVertexOffset;
/////////////////////////////////////////////////////////////////////////////////
InputBlendShapeVertex ReadBlendShapeVertexDelta(uint vertexID)
{
uint vertexByteOffset = vertexID * InputBlendShapeVertex::size;
uint4 v0 = meshBlendShapesBuffer.Load4(vertexByteOffset + 0);
uint4 v1 = meshBlendShapesBuffer.Load4(vertexByteOffset + 16);
uint2 v2 = meshBlendShapesBuffer.Load2(vertexByteOffset + 32);
InputBlendShapeVertex rv;
rv.meshVertexIndex = v0.x;
rv.positionDelta = asfloat(v0.yzw);
rv.normalDelta = asfloat(v1.xyz);
rv.tangentDelta = asfloat(uint3(v1.w, v2.xy));
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
[numthreads(128, 1, 1)]
void CopyInitialMeshBlendShapes(uint tid: SV_DispatchThreadID)
{
if (tid >= inputBlendShapeVerticesCount)
return;
InputBlendShapeVertex v = ReadBlendShapeVertexDelta(tid + inputBlendShapeVertexOffset);
uint4 o0 = asuint(float4(v.positionDelta, v.normalDelta.x));
uint4 o1 = asuint(float4(v.normalDelta.yz, v.tangentDelta.xy));
uint o2 = asuint(v.tangentDelta.z);
uint outVertexOffset = v.meshVertexIndex + outBlendShapeVertexOffset;
uint outVertexByteOffset = outVertexOffset * DeformedVertex::size;
outInitialMeshBlendShapesData.Store4(outVertexByteOffset + 0, o0);
outInitialMeshBlendShapesData.Store4(outVertexByteOffset + 16, o1);
outInitialMeshBlendShapesData.Store(outVertexByteOffset + 32, o2);
}
#endif // COPY_INITIAL_MESH_BLEND_SHAPES_HLSL_
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: b3da0895509ba5a44b90be032bfb9819
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/CopyInitialMeshBlendShapes.hlsl
uploadId: 897522
@@ -0,0 +1,57 @@
#ifndef COPY_INITIAL_MESH_DATA_HLSL_
#define COPY_INITIAL_MESH_DATA_HLSL_
/////////////////////////////////////////////////////////////////////////////////
ByteAddressBuffer meshVertexData;
ByteAddressBuffer meshBonesPerVertexData;
RWByteAddressBuffer outInitialDeformedMeshData;
int inputVertexSizeInBytes;
int outDataVertexOffset;
uint totalMeshVertices;
int outBonesWeightsDataOffset;
int inputBonesWeightsDataOffset;
/////////////////////////////////////////////////////////////////////////////////
SourceSkinnedMeshVertex ReadSourceVertex(int vertexIndex)
{
int vertexByteOffset = vertexIndex * inputVertexSizeInBytes;
SourceSkinnedMeshVertex rv = (SourceSkinnedMeshVertex)0;
#ifndef RUKHANKA_INPLACE_SKINNING
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_COPY_MESH_DATA, vertexByteOffset, 40, meshVertexData);
float4 v0 = asfloat(meshVertexData.Load4(vertexByteOffset + 0));
float4 v1 = asfloat(meshVertexData.Load4(vertexByteOffset + 16));
float1 v2 = asfloat(meshVertexData.Load(vertexByteOffset + 32));
rv.position = v0.xyz;
rv.normal = float3(v0.w, v1.xy);
rv.tangent = float3(v1.zw, v2.x);
#endif
int baseBoneWeightIndex = inputBonesWeightsDataOffset + vertexIndex;
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_COPY_MESH_DATA, baseBoneWeightIndex * 4, 4, meshBonesPerVertexData);
uint boneWeightsOffsetAndCountPacked = meshBonesPerVertexData.Load(baseBoneWeightIndex * 4);
rv.boneWeightsOffset = SourceSkinnedMeshVertex::GetBoneWeightsOffsetFromPackedUINT(boneWeightsOffsetAndCountPacked) + outBonesWeightsDataOffset;
rv.boneWeightsCount = SourceSkinnedMeshVertex::GetBoneWeightsCountFromPackedUINT(boneWeightsOffsetAndCountPacked);
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
[numthreads(128, 1, 1)]
void CopyInitialMeshData(uint tid: SV_DispatchThreadID)
{
if (tid >= totalMeshVertices)
return;
SourceSkinnedMeshVertex v = ReadSourceVertex(tid);
int outVertexOffset = tid + outDataVertexOffset;
v.WriteIntoRawBuffer(outInitialDeformedMeshData, outVertexOffset);
}
#endif // COPY_INITIAL_MESH_DATA_HLSL_
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: e286f97e31bb11943af1a6b97b753b28
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/CopyInitialMeshData.hlsl
uploadId: 897522
@@ -0,0 +1,26 @@
#ifndef CREATE_PER_VERTEX_DEFORMATION_WORKLOAD_HLSL_
#define CREATE_PER_VERTEX_DEFORMATION_WORKLOAD_HLSL_
/////////////////////////////////////////////////////////////////////////////////
RWByteAddressBuffer outFramePerVertexWorkload;
uint totalDeformedMeshesCount;
/////////////////////////////////////////////////////////////////////////////////
[numthreads(128, 1, 1)]
void CreatePerVertexDeformationWorkload(uint tid: SV_DispatchThreadID)
{
if (tid >= totalDeformedMeshesCount)
return;
MeshFrameDeformationDescription md = frameDeformedMeshes[tid];
for (int i = 0; i < md.meshVerticesCount; ++i)
{
int outVertexIndex = i + md.baseOutVertexIndex;
outFramePerVertexWorkload.Store(outVertexIndex * 4, tid);
}
}
#endif // CREATE_PER_VERTEX_DEFORMATION_WORKLOAD_HLSL_
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: fd557c506788751409cfce5117c0adbc
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/CreatePerVertexDeformationWorkload.hlsl
uploadId: 897522
@@ -0,0 +1,205 @@
#ifndef DEFORMATION_COMMON_HLSL_
#define DEFORMATION_COMMON_HLSL_
/////////////////////////////////////////////////////////////////////////////////
struct SourceSkinnedMeshVertex
{
#ifndef RUKHANKA_INPLACE_SKINNING
float3 position;
float3 normal;
float3 tangent;
static const int size = 40;
#else
static const int size = 4;
#endif
uint boneWeightsOffset;
uint boneWeightsCount;
static uint GetBoneWeightsOffsetFromPackedUINT(uint boneWeightsOffsetAndCount)
{
return boneWeightsOffsetAndCount >> 8;
}
static uint GetBoneWeightsCountFromPackedUINT(uint boneWeightsOffsetAndCount)
{
return boneWeightsOffsetAndCount & 0xff;
}
static uint PackBoneOffsetAndCount(uint count, uint offset)
{
return count | (offset << 8);
}
void WriteIntoRawBuffer(RWByteAddressBuffer outBuffer, uint index)
{
uint boneWeightsOffsetAndCount = PackBoneOffsetAndCount(boneWeightsCount, boneWeightsOffset);
uint byteOffset = index * size;
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_SKINNED_MESH_VERTEX_WRITE, byteOffset, size, outBuffer);
#ifndef RUKHANKA_INPLACE_SKINNING
uint4 u0 = asuint(float4(position, normal.x));
uint4 u1 = asuint(float4(normal.yz, tangent.xy));
uint2 u2 = uint2(asuint(tangent.z), boneWeightsOffsetAndCount);
outBuffer.Store4(byteOffset + 0, u0);
outBuffer.Store4(byteOffset + 16, u1);
outBuffer.Store2(byteOffset + 32, u2);
#else
outBuffer.Store(byteOffset + 0, boneWeightsOffsetAndCount);
#endif
}
static SourceSkinnedMeshVertex ReadFromRawBuffer(ByteAddressBuffer inBuffer, uint index)
{
SourceSkinnedMeshVertex rv;
uint byteOffset = index * size;
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_SKINNED_MESH_VERTEX_READ, byteOffset, size, inBuffer);
#ifndef RUKHANKA_INPLACE_SKINNING
uint4 u0 = inBuffer.Load4(byteOffset + 0);
uint4 u1 = inBuffer.Load4(byteOffset + 16);
uint2 u2 = inBuffer.Load2(byteOffset + 32);
rv.position = asfloat(u0.xyz);
rv.normal = asfloat(uint3(u0.w, u1.xy));
rv.tangent = asfloat(uint3(u1.zw, u2.x));
uint boneWeightsOffsetAndCount = u2.y;
#else
uint boneWeightsOffsetAndCount = inBuffer.Load(byteOffset + 0);
#endif
rv.boneWeightsOffset = GetBoneWeightsOffsetFromPackedUINT(boneWeightsOffsetAndCount);
rv.boneWeightsCount = GetBoneWeightsCountFromPackedUINT(boneWeightsOffsetAndCount);
return rv;
}
};
/////////////////////////////////////////////////////////////////////////////////
struct DeformedVertex
{
float3 position;
float3 normal;
float3 tangent;
static const int size = 3 * 3 * 4;
static DeformedVertex ReadFromRawBuffer(ByteAddressBuffer inBuffer, uint index)
{
uint byteOffset = index * size;
uint4 v0 = inBuffer.Load4(byteOffset + 0);
uint4 v1 = inBuffer.Load4(byteOffset + 16);
uint v2 = inBuffer.Load(byteOffset + 32);
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_DEFORMED_VERTEX_READ, byteOffset, size * 4, inBuffer);
DeformedVertex rv;
rv.position = asfloat(v0.xyz);
rv.normal = asfloat(uint3(v0.w, v1.xy));
rv.tangent = asfloat(uint3(v1.zw, v2.x));
return rv;
}
void Scale(float v)
{
position *= v;
normal *= v;
tangent *= v;
}
};
/////////////////////////////////////////////////////////////////////////////////
struct PackedDeformedVertex
{
uint4 pack0;
uint pack1;
DeformedVertex Unpack()
{
DeformedVertex rv;
rv.position.x = f16tof32(pack0.x >> 16);
rv.position.y = f16tof32(pack0.x);
rv.position.z = f16tof32(pack0.y >> 16);
rv.normal.x = f16tof32(pack0.y);
rv.normal.y = f16tof32(pack0.z >> 16);
rv.normal.z = f16tof32(pack0.z);
rv.tangent.x = f16tof32(pack0.w >> 16);
rv.tangent.y = f16tof32(pack0.w);
rv.tangent.z = f16tof32(pack1 >> 16);
return rv;
}
static PackedDeformedVertex Pack(DeformedVertex v)
{
PackedDeformedVertex rv;
uint3 p = f32tof16(v.position);
uint3 n = f32tof16(v.normal);
uint3 t = f32tof16(v.tangent);
rv.pack0.x = p.x << 16 | p.y;
rv.pack0.y = p.z << 16 | n.x;
rv.pack0.z = n.y << 16 | n.z;
rv.pack0.w = t.x << 16 | t.y;
rv.pack1 = t.z << 16;
return rv;
}
};
/////////////////////////////////////////////////////////////////////////////////
struct BoneInfluence
{
float weight;
int boneIndex;
static BoneInfluence ReadFromRawBuffer(ByteAddressBuffer inBuffer, uint index)
{
uint byteOffset = index * 8;
uint2 u0 = inBuffer.Load2(byteOffset + 0);
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_BONE_INFLUENCE_READ, byteOffset, 8, inBuffer);
BoneInfluence rv;
rv.weight = asfloat(u0.x);
rv.boneIndex = u0.y;
return rv;
}
};
/////////////////////////////////////////////////////////////////////////////////
struct MeshFrameDeformationDescription
{
int baseSkinMatrixIndex;
int baseBlendShapeWeightIndex;
int baseOutVertexIndex;
int baseInputMeshVertexIndex;
int baseInputMeshBlendShapeIndex;
int meshVerticesCount;
int meshBlendShapesCount;
};
/////////////////////////////////////////////////////////////////////////////////
struct InputBlendShapeVertex
{
uint meshVertexIndex;
float3 positionDelta;
float3 normalDelta;
float3 tangentDelta;
static const int size = (1 + 3 * 3) * 4;
};
/////////////////////////////////////////////////////////////////////////////////
StructuredBuffer<MeshFrameDeformationDescription> frameDeformedMeshes;
#endif // DEFORMATION_COMMON_HLSL_
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: f4b5c1545ea2e514fb6d61c2b2215f6b
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/DeformationCommon.hlsl
uploadId: 897522
@@ -0,0 +1,17 @@
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/ShaderConf.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/Debug.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/DeformationCommon.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/CopyInitialMeshData.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/CopyInitialMeshBlendShapes.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/CreatePerVertexDeformationWorkload.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/Skinning.hlsl"
//#pragma enable_d3d11_debug_symbols
//#pragma use_dxc
/////////////////////////////////////////////////////////////////////////////////
#pragma kernel CopyInitialMeshData
#pragma kernel CopyInitialMeshBlendShapes
#pragma kernel CreatePerVertexDeformationWorkload
#pragma kernel Skinning
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: c82cd9a4a3fa4854a9b4dd3290fd978f
ComputeShaderImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/RukhankaMeshDeformation.compute
uploadId: 897522
@@ -0,0 +1,178 @@
#ifndef SKINNING_HLSL_
#define SKINNING_HLSL_
/////////////////////////////////////////////////////////////////////////////////
#pragma warning (disable: 4000)
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/GPUStructures/BoneTransform.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/GPUStructures/DualQuaternion.hlsl"
#include "Packages/com.rukhanka.animation/Rukhanka.Runtime/Common/Shaders/GPUStructures/SkinMatrix.hlsl"
/////////////////////////////////////////////////////////////////////////////////
ByteAddressBuffer framePerVertexWorkload;
// SourceSkinnedMeshVertex
ByteAddressBuffer inputMeshVertexData;
// BoneInfluence
ByteAddressBuffer inputBoneInfluences;
// DeformedVertex
ByteAddressBuffer inputBlendShapes;
// SkinMatrix
ByteAddressBuffer frameSkinMatrices;
StructuredBuffer<float> frameBlendShapeWeights;
#ifdef RUKHANKA_HALF_DEFORMED_DATA
RWStructuredBuffer<PackedDeformedVertex> outDeformedVertices;
#else
RWStructuredBuffer<DeformedVertex> outDeformedVertices;
#endif
uint totalSkinnedVerticesCount;
uint voidMeshVertexCount;
int currentSkinnedVertexOffset;
/////////////////////////////////////////////////////////////////////////////////
DeformedVertex ApplyBlendShapes(DeformedVertex v, uint meshVertexIndex, MeshFrameDeformationDescription mfd)
{
if (mfd.baseBlendShapeWeightIndex < 0)
return v;
for (int i = 0; i < mfd.meshBlendShapesCount; ++i)
{
float blendShapeWeight = frameBlendShapeWeights[mfd.baseBlendShapeWeightIndex + i];
if (blendShapeWeight == 0)
continue;
DeformedVertex blendShapeDelta = DeformedVertex::ReadFromRawBuffer
(
inputBlendShapes,
mfd.baseInputMeshBlendShapeIndex + meshVertexIndex + i * mfd.meshVerticesCount
);
blendShapeDelta.Scale(blendShapeWeight * 0.01f);
v.position += blendShapeDelta.position;
v.normal += blendShapeDelta.normal;
v.tangent += blendShapeDelta.tangent;
}
return v;
}
/////////////////////////////////////////////////////////////////////////////////
DeformedVertex ApplySkinMatrices
(
DeformedVertex v,
uint vertexBoneWeightsOffset,
uint vertexBoneWeightsCount,
MeshFrameDeformationDescription mfd
)
{
if (mfd.baseSkinMatrixIndex < 0 || vertexBoneWeightsCount == 0)
return v;
// Skinning loop
#ifdef RUKHANKA_DUAL_QUATERNION_SKINNING
DualQuaternion adq = (DualQuaternion)0;
#endif
DeformedVertex rv = (DeformedVertex)0;
float4 refRot = 0;
float3 skinnedScale = 0;
for (uint i = 0; i < vertexBoneWeightsCount; ++i)
{
uint boneInfluenceIndex = i + vertexBoneWeightsOffset;
BoneInfluence bi = BoneInfluence::ReadFromRawBuffer(inputBoneInfluences, boneInfluenceIndex);
int skinMatrixIndex = bi.boneIndex + mfd.baseSkinMatrixIndex;
float3x4 skinMatrix = SkinMatrix::ReadFromRawBuffer(frameSkinMatrices, skinMatrixIndex);
#ifdef RUKHANKA_DUAL_QUATERNION_SKINNING
BoneTransform skinPose = BoneTransform::FromMatrix(skinMatrix);
skinnedScale += skinPose.scale * bi.weight;
if (i == 0)
refRot = skinPose.rot.value;
else if (dot(skinPose.rot.value, refRot) < 0)
bi.weight = -bi.weight;
DualQuaternion dq = DualQuaternion::Construct(skinPose.pos, skinPose.rot);
DualQuaternion sdq = DualQuaternion::Scale(dq, bi.weight);
adq = DualQuaternion::Add(adq, sdq);
#else
rv.position += mul(skinMatrix, float4(v.position, 1)) * bi.weight;
rv.normal += mul(skinMatrix, float4(v.normal, 0)) * bi.weight;
rv.tangent += mul(skinMatrix, float4(v.tangent, 0)) * bi.weight;
#endif
}
#ifdef RUKHANKA_DUAL_QUATERNION_SKINNING
adq = DualQuaternion::Normalize(adq);
BoneTransform bt = adq.GetBoneTransform();
bt.scale = skinnedScale;
rv.position = BoneTransform::TransformPoint(bt, v.position);
rv.normal = BoneTransform::TransformDirection(bt, v.normal);
rv.tangent = BoneTransform::TransformDirection(bt, v.tangent);
#endif
return rv;
}
/////////////////////////////////////////////////////////////////////////////////
[numthreads(128, 1, 1)]
void Skinning(uint tid: SV_DispatchThreadID)
{
uint skinnedVertexIndex = tid + currentSkinnedVertexOffset;
// Skip zero vertex because it is uninitialized marker
if (skinnedVertexIndex >= totalSkinnedVerticesCount || skinnedVertexIndex == 0)
{
if (skinnedVertexIndex < totalSkinnedVerticesCount + voidMeshVertexCount)
{
#ifdef RUKHANKA_HALF_DEFORMED_DATA
outDeformedVertices[skinnedVertexIndex] = (PackedDeformedVertex)0;
#else
outDeformedVertices[skinnedVertexIndex] = (DeformedVertex)0;
#endif
CHECK_STRUCTURED_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_COPY_MESH_DATA, skinnedVertexIndex, outDeformedVertices);
}
return;
}
CHECK_RAW_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_PER_VERTEX_WORKLOAD_READ, skinnedVertexIndex * 4, 4, framePerVertexWorkload);
uint frameDeformedMeshIndex = framePerVertexWorkload.Load(skinnedVertexIndex * 4);
CHECK_STRUCTURED_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_FRAME_DEFORMED_VERTEX_READ, frameDeformedMeshIndex, frameDeformedMeshes);
MeshFrameDeformationDescription mfd = frameDeformedMeshes[frameDeformedMeshIndex];
uint meshVertexIndex = skinnedVertexIndex - mfd.baseOutVertexIndex;
uint absoluteInputMeshVertexIndex = meshVertexIndex + mfd.baseInputMeshVertexIndex;
SourceSkinnedMeshVertex smv = SourceSkinnedMeshVertex::ReadFromRawBuffer(inputMeshVertexData, absoluteInputMeshVertexIndex);
DeformedVertex rv = (DeformedVertex)0;
#ifndef RUKHANKA_INPLACE_SKINNING
rv.position = smv.position;
rv.tangent = smv.tangent;
rv.normal = smv.normal;
#endif
rv = ApplyBlendShapes(rv, meshVertexIndex, mfd);
rv = ApplySkinMatrices(rv, smv.boneWeightsOffset, smv.boneWeightsCount, mfd);
#ifdef RUKHANKA_HALF_DEFORMED_DATA
outDeformedVertices[skinnedVertexIndex] = PackedDeformedVertex::Pack(rv);
#else
outDeformedVertices[skinnedVertexIndex] = rv;
#endif
CHECK_STRUCTURED_BUFFER_OUT_OF_BOUNDS(RUKHANKADEBUGMARKERS_DEFORMATION_DEFORMED_VERTEX_WRITE, skinnedVertexIndex, outDeformedVertices);
}
/////////////////////////////////////////////////////////////////////////////////
#endif // SKINNING_HLSL_
@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: c99bf944d5948e649b631c5ae38ac8a2
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 298480
packageName: Rukhanka Animation System 2
packageVersion: 2.9.0
assetPath: Packages/com.rukhanka.animation/Rukhanka.Runtime/Deformation/Resources/Skinning.hlsl
uploadId: 897522