public static IEnumerable <VFXExpression> SampleTriangleAttribute(VFXExpression source, VFXExpression triangleIndex, VFXExpression coord, VFXOperatorUtility.SequentialAddressingMode mode, SurfaceCoordinates coordMode, IEnumerable <VertexAttribute> vertexAttributes) { bool skinnedMesh = source.valueType == UnityEngine.VFX.VFXValueType.SkinnedMeshRenderer; var mesh = !skinnedMesh ? source : new VFXExpressionMeshFromSkinnedMeshRenderer(source); var UintThree = VFXOperatorUtility.ThreeExpression[UnityEngine.VFX.VFXValueType.Uint32]; var meshIndexCount = new VFXExpressionMeshIndexCount(mesh); var triangleCount = meshIndexCount / UintThree; triangleIndex = VFXOperatorUtility.ApplyAddressingMode(triangleIndex, triangleCount, mode); return(SampleTriangleAttribute(source, triangleIndex, coord, coordMode, vertexAttributes)); }
public static IEnumerable <VFXExpression> SampleTriangleAttribute(VFXExpression source, VFXExpression triangleIndex, VFXExpression coord, SurfaceCoordinates coordMode, IEnumerable <VertexAttribute> vertexAttributes) { bool skinnedMesh = source.valueType == UnityEngine.VFX.VFXValueType.SkinnedMeshRenderer; var mesh = !skinnedMesh ? source : new VFXExpressionMeshFromSkinnedMeshRenderer(source); var meshIndexCount = new VFXExpressionMeshIndexCount(mesh); var meshIndexFormat = new VFXExpressionMeshIndexFormat(mesh); var threeUint = VFXOperatorUtility.ThreeExpression[UnityEngine.VFX.VFXValueType.Uint32]; var baseIndex = triangleIndex * threeUint; var sampledIndex_A = new VFXExpressionSampleIndex(mesh, baseIndex, meshIndexFormat); var sampledIndex_B = new VFXExpressionSampleIndex(mesh, baseIndex + VFXValue.Constant <uint>(1u), meshIndexFormat); var sampledIndex_C = new VFXExpressionSampleIndex(mesh, baseIndex + VFXValue.Constant <uint>(2u), meshIndexFormat); var allInputValues = new List <VFXExpression>(); var sampling_A = SampleVertexAttribute(source, sampledIndex_A, vertexAttributes).ToArray(); var sampling_B = SampleVertexAttribute(source, sampledIndex_B, vertexAttributes).ToArray(); var sampling_C = SampleVertexAttribute(source, sampledIndex_C, vertexAttributes).ToArray(); VFXExpression barycentricCoordinates = null; var one = VFXOperatorUtility.OneExpression[UnityEngine.VFX.VFXValueType.Float]; if (coordMode == SurfaceCoordinates.Barycentric) { var barycentricCoordinateInput = coord; barycentricCoordinates = new VFXExpressionCombine(barycentricCoordinateInput.x, barycentricCoordinateInput.y, one - barycentricCoordinateInput.x - barycentricCoordinateInput.y); } else if (coordMode == SurfaceCoordinates.Uniform) { //https://hal.archives-ouvertes.fr/hal-02073696v2/document var input = coord; var half2 = VFXOperatorUtility.HalfExpression[UnityEngine.VFX.VFXValueType.Float2]; var zero = VFXOperatorUtility.ZeroExpression[UnityEngine.VFX.VFXValueType.Float]; var t = input * half2; var offset = t.y - t.x; var pred = new VFXExpressionCondition(UnityEngine.VFX.VFXValueType.Float, VFXCondition.Greater, offset, zero); var t2 = new VFXExpressionBranch(pred, t.y + offset, t.y); var t1 = new VFXExpressionBranch(pred, t.x, t.x - offset); var t3 = one - t2 - t1; barycentricCoordinates = new VFXExpressionCombine(t1, t2, t3); /* Possible variant See http://inis.jinr.ru/sl/vol1/CMC/Graphics_Gems_1,ed_A.Glassner.pdf (p24) uniform distribution from two numbers in triangle generating barycentric coordinate * var input = VFXOperatorUtility.Saturate(inputExpression[2]); * var s = input.x; * var t = VFXOperatorUtility.Sqrt(input.y); * var a = one - t; * var b = (one - s) * t; * var c = s * t; * barycentricCoordinates = new VFXExpressionCombine(a, b, c); */ } else { throw new InvalidOperationException("No supported surfaceCoordinates : " + coord); } for (int i = 0; i < vertexAttributes.Count(); ++i) { var outputValueType = sampling_A[i].valueType; var barycentricCoordinateX = VFXOperatorUtility.CastFloat(barycentricCoordinates.x, outputValueType); var barycentricCoordinateY = VFXOperatorUtility.CastFloat(barycentricCoordinates.y, outputValueType); var barycentricCoordinateZ = VFXOperatorUtility.CastFloat(barycentricCoordinates.z, outputValueType); var r = sampling_A[i] * barycentricCoordinateX + sampling_B[i] * barycentricCoordinateY + sampling_C[i] * barycentricCoordinateZ; yield return(r); } }