Ejemplo n.º 1
0
        public static IEnumerable <VFXExpression> SampleEdgeAttribute(VFXExpression source, VFXExpression index, VFXExpression lerp, IEnumerable <VertexAttribute> vertexAttributes)
        {
            bool skinnedMesh = source.valueType == UnityEngine.VFX.VFXValueType.SkinnedMeshRenderer;
            var  mesh        = !skinnedMesh ? source : new VFXExpressionMeshFromSkinnedMeshRenderer(source);

            var meshIndexFormat = new VFXExpressionMeshIndexFormat(mesh);

            var oneInt    = VFXOperatorUtility.OneExpression[UnityEngine.VFX.VFXValueType.Int32];
            var oneUint   = VFXOperatorUtility.OneExpression[UnityEngine.VFX.VFXValueType.Uint32];
            var threeUint = VFXOperatorUtility.ThreeExpression[UnityEngine.VFX.VFXValueType.Uint32];

            var nextIndex = index + oneUint;

            //Loop triangle
            var loop     = VFXOperatorUtility.Modulo(nextIndex, threeUint);
            var predicat = new VFXExpressionCondition(UnityEngine.VFX.VFXValueType.Uint32, VFXCondition.NotEqual, loop, VFXOperatorUtility.ZeroExpression[UnityEngine.VFX.VFXValueType.Uint32]);

            nextIndex = new VFXExpressionBranch(predicat, nextIndex, nextIndex - threeUint);

            var sampledIndex_A = new VFXExpressionSampleIndex(mesh, index, meshIndexFormat);
            var sampledIndex_B = new VFXExpressionSampleIndex(mesh, nextIndex, meshIndexFormat);

            var sampling_A = SampleVertexAttribute(source, sampledIndex_A, vertexAttributes).ToArray();
            var sampling_B = SampleVertexAttribute(source, sampledIndex_B, vertexAttributes).ToArray();

            for (int i = 0; i < vertexAttributes.Count(); ++i)
            {
                var outputValueType = sampling_A[i].valueType;
                var s = VFXOperatorUtility.CastFloat(lerp, outputValueType);
                yield return(VFXOperatorUtility.Lerp(sampling_A[i], sampling_B[i], s));
            }
        }
Ejemplo n.º 2
0
        protected override sealed VFXExpression[] BuildExpression(VFXExpression[] inputExpression)
        {
            var mesh = inputExpression[0].valueType == VFXValueType.Mesh ? inputExpression[0] : new VFXExpressionMeshFromSkinnedMeshRenderer(inputExpression[0]);

            var indexFormat = new VFXExpressionMeshIndexFormat(mesh);
            var indexCount  = new VFXExpressionMeshIndexCount(mesh);
            var index       = VFXOperatorUtility.ApplyAddressingMode(inputExpression[1], indexCount, VFXOperatorUtility.SequentialAddressingMode.Wrap);

            var sampledIndex = new VFXExpressionSampleIndex(mesh, index, indexFormat);

            return(new[] { sampledIndex });
        }
Ejemplo n.º 3
0
        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);
            }
        }