You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
3.1 KiB
Plaintext
72 lines
3.1 KiB
Plaintext
#pragma kernel SkinningKernel
|
|
#define SIZEOF_INT 4
|
|
#include "VerletSimulationInclude.hlsl"
|
|
#include "HairRendererInclude.hlsl"
|
|
#include "../NormalHelperInclude.cginc"
|
|
|
|
RWStructuredBuffer<HairStrandPoint> hairStrandPoints;
|
|
StructuredBuffer<float3> curvePoints;
|
|
StructuredBuffer<float2> uvBuffer;
|
|
StructuredBuffer<MeshProperties> sourceMesh;
|
|
RWByteAddressBuffer meshIndexBuffer;
|
|
uint maxX;
|
|
uint maxY;
|
|
|
|
bool isInsideTriangle(float3 bc)
|
|
{
|
|
return bc.x >= 0 && bc.y >= 0 && bc.x + bc.y <= 1;
|
|
}
|
|
|
|
float4x4 worldToLocalMatrix;
|
|
float4x4 inverseScaleMatrix;
|
|
|
|
[numthreads(16,16,1)]
|
|
void SkinningKernel(uint3 id : SV_DispatchThreadID)
|
|
{
|
|
const uint pointRootIndex = id.x * strandPointsCount;
|
|
const uint triInd = id.y * 3;
|
|
if (pointRootIndex >= maxX || triInd >= maxY) return;
|
|
|
|
uint triIndex1 = meshIndexBuffer.Load(triInd * SIZEOF_INT);
|
|
uint triIndex2 = meshIndexBuffer.Load((triInd + 1) * SIZEOF_INT);
|
|
uint triIndex3 = meshIndexBuffer.Load((triInd + 2) * SIZEOF_INT);
|
|
|
|
const MeshProperties sm1 = sourceMesh[triIndex1];
|
|
const MeshProperties sm2 = sourceMesh[triIndex2];
|
|
const MeshProperties sm3 = sourceMesh[triIndex3];
|
|
|
|
const float3 vert1 = mul(localToWorldMatrix, float4(sm1.sourceVertex, 1)).xyz;
|
|
const float3 vert2 = mul(localToWorldMatrix, float4(sm2.sourceVertex, 1)).xyz;
|
|
const float3 vert3 = mul(localToWorldMatrix, float4(sm3.sourceVertex, 1)).xyz;
|
|
|
|
const float3 curvePoint = curvePoints[pointRootIndex];
|
|
const float3 barycentricCoordinate = Barycentric(vert1, vert2, vert3, curvePoint);
|
|
|
|
const float3 baryCentricPosition = Interpolate3(vert1, vert2, vert3, barycentricCoordinate);
|
|
|
|
if (isInsideTriangle(barycentricCoordinate) && distance(baryCentricPosition, curvePoint) < 0.02f)
|
|
{
|
|
const float3 normal1 = mul(objectRotationMatrix, float4(sm1.sourceNormal, 1)).xyz;
|
|
const float3 normal2 = mul(objectRotationMatrix, float4(sm2.sourceNormal, 1)).xyz;
|
|
const float3 normal3 = mul(objectRotationMatrix, float4(sm3.sourceNormal, 1)).xyz;
|
|
|
|
const float3 barycentricNormal = Interpolate3(normal1, normal2, normal3, barycentricCoordinate);
|
|
const float2 uv = Interpolate2(uvBuffer[triIndex1], uvBuffer[triIndex2], uvBuffer[triIndex3], barycentricCoordinate);
|
|
for (uint j = pointRootIndex; j < pointRootIndex + strandPointsCount; j++)
|
|
{
|
|
const float3 localStrandPoint = curvePoints[j];
|
|
const float3 myRotVec = normalize(localStrandPoint - baryCentricPosition);
|
|
float originalDistance = distance(baryCentricPosition, localStrandPoint);
|
|
float4 inverseScaledDistance = float4(originalDistance, originalDistance, originalDistance, 1);
|
|
inverseScaledDistance = mul(inverseScaleMatrix, inverseScaledDistance);
|
|
HairStrandPoint p;
|
|
p.barycentricCoordinate = barycentricCoordinate;
|
|
p.triangleIndices = float3(triIndex1, triIndex2, triIndex3);
|
|
p.rotationDiffFromNormal = barycentricNormal - myRotVec;
|
|
p.distanceToRoot = distance(float3(0, 0, 0), inverseScaledDistance.xyz)*0.667;//OK this works whyyyy?!
|
|
p.uv = uv;
|
|
hairStrandPoints[j] = p;
|
|
}
|
|
}
|
|
}
|