sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
        {
            var xReduce = constParents[0];
            var yReduce = constParents[1];
            var zReduce = constParents[2];
            var wReduce = constParents[3];

            var x = xReduce.Get <Vector3>();
            var y = yReduce.Get <Vector3>();
            var z = zReduce.Get <Vector3>();
            var w = wReduce.Get <Vector3>();

            Matrix4x4 matrix = new Matrix4x4();

            matrix.SetColumn(0, new Vector4(x.x, x.y, x.z, 0.0f));
            matrix.SetColumn(1, new Vector4(y.x, y.y, y.z, 0.0f));
            matrix.SetColumn(2, new Vector4(z.x, z.y, z.z, 0.0f));
            matrix.SetColumn(3, new Vector4(w.x, w.y, w.z, 1.0f));

            return(VFXValue.Constant(matrix));
        }
        sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
        {
            var xReduce = constParents[0];
            var yReduce = constParents[1];
            var zReduce = constParents[2];
            var wReduce = constParents[3];

            var x = xReduce.Get <Vector4>();
            var y = yReduce.Get <Vector4>();
            var z = zReduce.Get <Vector4>();
            var w = wReduce.Get <Vector4>();

            Matrix4x4 matrix = new Matrix4x4();

            matrix.SetColumn(0, x);
            matrix.SetColumn(1, y);
            matrix.SetColumn(2, z);
            matrix.SetColumn(3, w);

            return(VFXValue.Constant(matrix));
        }
Ejemplo n.º 3
0
        static private VFXValue GetValueFromType(VFXValueType type)
        {
            switch (type)
            {
            case VFXValueType.Boolean: return(VFXValue.Constant <bool>());

            case VFXValueType.Uint32: return(VFXValue.Constant <uint>());

            case VFXValueType.Int32: return(VFXValue.Constant <int>());

            case VFXValueType.Float: return(VFXValue.Constant <float>());

            case VFXValueType.Float2: return(VFXValue.Constant <Vector2>());

            case VFXValueType.Float3: return(VFXValue.Constant <Vector3>());

            case VFXValueType.Float4: return(VFXValue.Constant <Vector4>());

            default: throw new InvalidOperationException(string.Format("Unexpected attribute type: {0}", type));
            }
        }
Ejemplo n.º 4
0
        protected virtual IEnumerable <VFXNamedExpression> CollectGPUExpressions(IEnumerable <VFXNamedExpression> slotExpressions)
        {
            if (blendMode == BlendMode.Masked)
            {
                yield return(slotExpressions.First(o => o.name == "alphaThreshold"));
            }

            if (supportSoftParticles)
            {
                var softParticleFade    = slotExpressions.First(o => o.name == "softParticlesFadeDistance");
                var invSoftParticleFade = (VFXValue.Constant(1.0f) / softParticleFade.exp);
                yield return(new VFXNamedExpression(invSoftParticleFade, "invSoftParticlesFadeDistance"));
            }

            if (supportsUV && uvMode != UVMode.Simple)
            {
                switch (uvMode)
                {
                case UVMode.Flipbook:
                case UVMode.FlipbookBlend:
                    var flipBookSizeExp = slotExpressions.First(o => o.name == "flipBookSize");
                    yield return(flipBookSizeExp);

                    yield return(new VFXNamedExpression(VFXValue.Constant(Vector2.one) / flipBookSizeExp.exp, "invFlipBookSize"));

                    break;

                case UVMode.ScaleAndBias:
                    yield return(slotExpressions.First(o => o.name == "uvScale"));

                    yield return(slotExpressions.First(o => o.name == "uvBias"));

                    break;

                default: throw new NotImplementedException("Unimplemented UVMode: " + uvMode);
                }
            }
        }
        sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
        {
            bool  res   = false;
            float left  = constParents[0].Get <float>();
            float right = constParents[1].Get <float>();

            switch (condition)
            {
            case VFXCondition.Equal:            res = left == right;    break;

            case VFXCondition.NotEqual:         res = left != right;    break;

            case VFXCondition.Less:             res = left < right;     break;

            case VFXCondition.LessOrEqual:      res = left <= right;    break;

            case VFXCondition.Greater:          res = left > right;     break;

            case VFXCondition.GreaterOrEqual:   res = left >= right;    break;
            }

            return(VFXValue.Constant <bool>(res));
        }
        public static VFXExpression ApplyToExpressionGraph(VFXPropertyAttribute[] attributes, VFXExpression exp)
        {
            if (attributes != null)
            {
                foreach (VFXPropertyAttribute attribute in attributes)
                {
                    switch (attribute.m_Type)
                    {
                    case Type.kRange:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant(attribute.m_Min), VFXValue.Constant(attribute.m_Max));
                        break;

                    case Type.kMin:
                        exp = new VFXExpressionMax(exp, VFXOperatorUtility.CastFloat(VFXValue.Constant(attribute.m_Min), exp.valueType));
                        break;

                    case Type.kNormalize:
                        exp = VFXOperatorUtility.Normalize(exp);
                        break;

                    case Type.kTooltip:
                    case Type.kAngle:
                    case Type.kColor:
                    case Type.kRegex:
                    case Type.kDelayed:
                    case Type.kBitField:
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }

            return(exp);
        }
Ejemplo n.º 7
0
        sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
        {
            var matrix = constParents[0].Get <Matrix4x4>();

            return(VFXValue.Constant(matrix.transpose));
        }
Ejemplo n.º 8
0
        protected virtual IEnumerable <VFXNamedExpression> CollectGPUExpressions(IEnumerable <VFXNamedExpression> slotExpressions)
        {
            if (exposeAlphaThreshold)
            {
                yield return(slotExpressions.First(o => o.name == "alphaThreshold"));
            }

            if (colorMapping == ColorMappingMode.GradientMapped)
            {
                yield return(slotExpressions.First(o => o.name == "gradient"));
            }

            if (hasSoftParticles)
            {
                var softParticleFade    = slotExpressions.First(o => o.name == "softParticleFadeDistance");
                var invSoftParticleFade = (VFXValue.Constant(1.0f) / softParticleFade.exp);
                yield return(new VFXNamedExpression(invSoftParticleFade, "invSoftParticlesFadeDistance"));
            }

            if (supportsUV && uvMode != UVMode.Default)
            {
                VFXNamedExpression flipBookSizeExp;
                switch (uvMode)
                {
                case UVMode.Flipbook:
                case UVMode.FlipbookBlend:
                case UVMode.FlipbookMotionBlend:
                    if (flipbookLayout == FlipbookLayout.Texture2D)
                    {
                        flipBookSizeExp = slotExpressions.First(o => o.name == "flipBookSize");
                        yield return(flipBookSizeExp);

                        yield return(new VFXNamedExpression(VFXValue.Constant(Vector2.one) / flipBookSizeExp.exp, "invFlipBookSize"));
                    }
                    else if (flipbookLayout == FlipbookLayout.Texture2DArray)
                    {
                        VFXNamedExpression mainTextureExp;
                        try
                        {
                            mainTextureExp = slotExpressions.First(o => (o.name == "mainTexture") | (o.name == "baseColorMap") | (o.name == "distortionBlurMap") | (o.name == "normalMap"));
                        }
                        catch (InvalidOperationException)
                        {
                            throw new NotImplementedException("Trying to fetch an inexistent slot Main Texture or Base Color Map or Distortion Blur Map or Normal Map. ");
                        }
                        yield return(new VFXNamedExpression(new VFXExpressionCastUintToFloat(new VFXExpressionTextureDepth(mainTextureExp.exp)), "flipBookSize"));
                    }
                    if (uvMode == UVMode.FlipbookMotionBlend)
                    {
                        yield return(slotExpressions.First(o => o.name == "motionVectorMap"));

                        yield return(slotExpressions.First(o => o.name == "motionVectorScale"));
                    }

                    break;

                case UVMode.ScaleAndBias:
                    yield return(slotExpressions.First(o => o.name == "uvScale"));

                    yield return(slotExpressions.First(o => o.name == "uvBias"));

                    break;

                default: throw new NotImplementedException("Unimplemented UVMode: " + uvMode);
                }
            }

            if (hasExposure && useExposureWeight)
            {
                yield return(slotExpressions.First(o => o.name == "exposureWeight"));
            }
        }
Ejemplo n.º 9
0
 public VFXExpressionMatrixToVector4s() : this(new VFXExpression[] { VFXValue <Matrix4x4> .Default, VFXValue.Constant <int>(0) } // TODO row index should not be an expression!
                                               )
 {
 }
Ejemplo n.º 10
0
        protected override VFXExpression Evaluate(VFXExpression[] constParents)
        {
            var graphicsBuffer = constParents[0].Get <GraphicsBuffer>();

            return(VFXValue.Constant <uint>(graphicsBuffer != null ? (uint)graphicsBuffer.stride : 0u));
        }
 public static VFXExpression operator>>(VFXExpression a, int shift)
 {
     return(new VFXExpressionBitwiseRightShift(a, VFXValue.Constant((uint)shift)));
 }
Ejemplo n.º 12
0
        protected override IEnumerable <VFXNamedExpression> CollectGPUExpressions(IEnumerable <VFXNamedExpression> slotExpressions)
        {
            foreach (var exp in base.CollectGPUExpressions(slotExpressions))
            {
                yield return(exp);
            }

            yield return(slotExpressions.First(o => o.name == "smoothness"));

            uint diffusionProfileHash;

            switch (materialType)
            {
            case MaterialType.Standard:
            case MaterialType.SimpleLit:
                yield return(slotExpressions.First(o => o.name == "metallic"));

                break;

            case MaterialType.SpecularColor:
                yield return(slotExpressions.First(o => o.name == "specularColor"));

                break;

            case MaterialType.Translucent:
            case MaterialType.SimpleLitTranslucent:
                yield return(slotExpressions.First(o => o.name == "thickness"));

#if VFX_HAS_HDRP
                diffusionProfileHash = (diffusionProfileAsset?.profile != null) ? diffusionProfileAsset.profile.hash : 0;
#else
                diffusionProfileHash = 0;
#endif
                yield return(new VFXNamedExpression(VFXValue.Constant(diffusionProfileHash), "diffusionProfileHash"));

                break;

            default: break;
            }

            if (allowTextures)
            {
                if (useBaseColorMap != BaseColorMapMode.None)
                {
                    yield return(slotExpressions.First(o => o.name == "baseColorMap"));
                }
                if (useMaskMap)
                {
                    yield return(slotExpressions.First(o => o.name == "maskMap"));
                }
                if (useNormalMap)
                {
                    yield return(slotExpressions.First(o => o.name == "normalMap"));

                    yield return(slotExpressions.First(o => o.name == "normalScale"));
                }
                if (useEmissiveMap)
                {
                    yield return(slotExpressions.First(o => o.name == "emissiveMap"));

                    yield return(slotExpressions.First(o => o.name == "emissiveScale"));
                }
            }

            if ((colorMode & ColorMode.BaseColor) == 0)
            {
                yield return(slotExpressions.First(o => o.name == "baseColor"));
            }

            if (((colorMode & ColorMode.Emissive) == 0) && useEmissive)
            {
                yield return(slotExpressions.First(o => o.name == "emissiveColor"));
            }
        }
 static public VFXExpression RadToDeg(VFXExpression radians)
 {
     return(radians * CastFloat(VFXValue.Constant(180.0f / Mathf.PI), radians.valueType));
 }
Ejemplo n.º 14
0
        // return size
        private int GenerateBucketLayout(List <VFXAttribute> attributes, int bucketId)
        {
            var sortedAttrib = attributes.OrderByDescending(a => VFXValue.TypeToSize(a.type));

            var attribBlocks = new List <List <VFXAttribute> >();

            foreach (var value in sortedAttrib)
            {
                var block = attribBlocks.FirstOrDefault(b => b.Sum(a => VFXValue.TypeToSize(a.type)) + VFXValue.TypeToSize(value.type) <= 4);
                if (block != null)
                {
                    block.Add(value);
                }
                else
                {
                    attribBlocks.Add(new List <VFXAttribute>()
                    {
                        value
                    });
                }
            }

            int currentOffset = 0;
            int minAlignment  = 0;

            foreach (var block in attribBlocks)
            {
                foreach (var attrib in block)
                {
                    int size      = VFXValue.TypeToSize(attrib.type);
                    int alignment = size > 2 ? 4 : size;
                    minAlignment = Math.Max(alignment, minAlignment);
                    // align offset
                    currentOffset = (currentOffset + alignment - 1) & ~(alignment - 1);
                    m_AttributeLayout.Add(attrib, new AttributeLayout(bucketId, currentOffset));
                    currentOffset += size;
                }
            }

            return((currentOffset + minAlignment - 1) & ~(minAlignment - 1));
        }
Ejemplo n.º 15
0
 static public VFXExpression FixedRandom(uint hash, VFXSeedMode mode)
 {
     return(FixedRandom(VFXValue.Constant <uint>(hash), mode));
 }
Ejemplo n.º 16
0
 sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
 {
     return(VFXValue.Constant(UnityEngine.Random.value));
 }
Ejemplo n.º 17
0
        public VFXExpression ApplyToExpressionGraph(VFXExpression exp)
        {
            if (m_GraphAttributes == null)
            {
                return(exp);
            }

            foreach (PropertyAttribute attribute in m_GraphAttributes)
            {
                if (attribute is RangeAttribute)
                {
                    var rangeAttribute = (RangeAttribute)attribute;
                    switch (exp.valueType)
                    {
                    case VFXValueType.Int32:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((int)rangeAttribute.min), VFXValue.Constant((int)rangeAttribute.max), false);
                        break;

                    case VFXValueType.Uint32:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((uint)rangeAttribute.min), VFXValue.Constant((uint)rangeAttribute.max), false);
                        break;

                    case VFXValueType.Float:
                    case VFXValueType.Float2:
                    case VFXValueType.Float3:
                    case VFXValueType.Float4:
                        exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant(rangeAttribute.min), VFXValue.Constant(rangeAttribute.max));
                        break;

                    default:
                        throw new NotImplementedException(string.Format("Cannot use RangeAttribute on value of type: {0}", exp.valueType));
                    }
                }
                else if (attribute is MinAttribute)
                {
                    var minAttribute = (MinAttribute)attribute;
                    switch (exp.valueType)
                    {
                    case VFXValueType.Int32:
                        exp = new VFXExpressionMax(exp, VFXValue.Constant((int)minAttribute.min));
                        break;

                    case VFXValueType.Uint32:
                        exp = new VFXExpressionMax(exp, VFXValue.Constant((uint)minAttribute.min));
                        break;

                    case VFXValueType.Float:
                    case VFXValueType.Float2:
                    case VFXValueType.Float3:
                    case VFXValueType.Float4:
                        exp = new VFXExpressionMax(exp, VFXOperatorUtility.CastFloat(VFXValue.Constant(minAttribute.min), exp.valueType));
                        break;

                    default:
                        throw new NotImplementedException(string.Format("Cannot use MinAttribute on value of type: {0}", exp.valueType));
                    }
                }
                else if (attribute is NormalizeAttribute)
                {
                    exp = VFXOperatorUtility.Normalize(exp);
                }
                else if (attribute is EnumAttribute)
                {
                    var enumAttribute = (EnumAttribute)attribute;
                    exp = new VFXExpressionMin(exp, VFXValue.Constant((uint)enumAttribute.values.Length - 1));
                }
                else
                {
                    throw new NotImplementedException("Unrecognized expression attribute: " + attribute);
                }
            }

            return(exp);
        }
Ejemplo n.º 18
0
 sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
 {
     return(VFXValue.Constant <Texture2D>(null));
 }
 public VFXExpressionCondition()
     : this(VFXCondition.Equal, VFXValue.Constant(0.0f), VFXValue.Constant(0.0f))
 {
 }
 public VFXExpressionBranch()
     : this(VFXValue.Constant(true), VFXValue.Constant(0.0f), VFXValue.Constant(0.0f))
 {
 }
Ejemplo n.º 21
0
        public static VFXExpression ApplyToExpressionGraph(VFXPropertyAttribute[] attributes, VFXExpression exp)
        {
            if (attributes != null)
            {
                foreach (VFXPropertyAttribute attribute in attributes)
                {
                    switch (attribute.m_Type)
                    {
                    case Type.kRange:
                        switch (exp.valueType)
                        {
                        case VFXValueType.Int32:
                            exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((int)attribute.m_Min), VFXValue.Constant((int)attribute.m_Max), false);
                            break;

                        case VFXValueType.Uint32:
                            exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant((uint)attribute.m_Min), VFXValue.Constant((uint)attribute.m_Max), false);
                            break;

                        case VFXValueType.Float:
                        case VFXValueType.Float2:
                        case VFXValueType.Float3:
                        case VFXValueType.Float4:
                            exp = VFXOperatorUtility.Clamp(exp, VFXValue.Constant(attribute.m_Min), VFXValue.Constant(attribute.m_Max));
                            break;

                        default:
                            throw new NotImplementedException(string.Format("Cannot use RangeAttribute on value of type: {0}", exp.valueType));
                        }
                        break;

                    case Type.kMin:
                        switch (exp.valueType)
                        {
                        case VFXValueType.Int32:
                            exp = new VFXExpressionMax(exp, VFXValue.Constant((int)attribute.m_Min));
                            break;

                        case VFXValueType.Uint32:
                            exp = new VFXExpressionMax(exp, VFXValue.Constant((uint)attribute.m_Min));
                            break;

                        case VFXValueType.Float:
                        case VFXValueType.Float2:
                        case VFXValueType.Float3:
                        case VFXValueType.Float4:
                            exp = new VFXExpressionMax(exp, VFXOperatorUtility.CastFloat(VFXValue.Constant(attribute.m_Min), exp.valueType));
                            break;

                        default:
                            throw new NotImplementedException(string.Format("Cannot use MinAttribute on value of type: {0}", exp.valueType));
                        }
                        break;

                    case Type.kNormalize:
                        exp = VFXOperatorUtility.Normalize(exp);
                        break;

                    case Type.kTooltip:
                    case Type.kAngle:
                    case Type.kColor:
                    case Type.kRegex:
                    case Type.kDelayed:
                    case Type.kBitField:
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }

            return(exp);
        }
Ejemplo n.º 22
0
 sealed protected override VFXExpression Evaluate(VFXExpression[] reducedParents)
 {
     return(VFXValue.Constant((uint)reducedParents[0].Get <float>()));
 }
Ejemplo n.º 23
0
        public void WriteCBuffer(VFXUniformMapper mapper, string bufferName)
        {
            var uniformValues = mapper.uniforms
                                .Where(e => !e.IsAny(VFXExpression.Flags.Constant | VFXExpression.Flags.InvalidOnCPU)) // Filter out constant expressions
                                .OrderByDescending(e => VFXValue.TypeToSize(e.valueType));

            var uniformBlocks = new List <List <VFXExpression> >();

            foreach (var value in uniformValues)
            {
                var block = uniformBlocks.FirstOrDefault(b => b.Sum(e => VFXValue.TypeToSize(e.valueType)) + VFXValue.TypeToSize(value.valueType) <= 4);
                if (block != null)
                {
                    block.Add(value);
                }
                else
                {
                    uniformBlocks.Add(new List <VFXExpression>()
                    {
                        value
                    });
                }
            }

            if (uniformBlocks.Count > 0)
            {
                WriteLineFormat("CBUFFER_START({0})", bufferName);
                Indent();

                int paddingIndex = 0;
                foreach (var block in uniformBlocks)
                {
                    int currentSize = 0;
                    foreach (var value in block)
                    {
                        string type = VFXExpression.TypeToUniformCode(value.valueType);
                        string name = mapper.GetName(value);
                        if (name.StartsWith("unity_")) //Reserved unity variable name (could be filled manually see : VFXMotionVector)
                        {
                            continue;
                        }

                        currentSize += VFXExpression.TypeToSize(value.valueType);

                        WriteLineFormat("{0} {1};", type, name);
                    }

                    WritePadding(4, currentSize, ref paddingIndex);
                }

                Deindent();
                WriteLine("CBUFFER_END");
            }
        }
Ejemplo n.º 24
0
 public VFXAttribute(string name, VFXValue value, VFXVariadic variadic = VFXVariadic.False)
 {
     this.name     = name;
     this.value    = value;
     this.variadic = variadic;
 }
Ejemplo n.º 25
0
        public override VFXExpressionMapper GetExpressionMapper(VFXDeviceTarget target)
        {
            var meshData = (VFXDataMesh)GetData();

            switch (target)
            {
            case VFXDeviceTarget.GPU:
            {
                var mapper = new VFXExpressionMapper();
                for (int i = 2; i < GetNbInputSlots(); ++i)
                {
                    VFXExpression exp  = GetInputSlot(i).GetExpression();
                    VFXProperty   prop = GetInputSlot(i).property;

                    // As there's not shader generation here, we need expressions that can be evaluated on CPU
                    if (exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU))
                    {
                        throw new InvalidOperationException(string.Format("Expression for slot {0} must be evaluable on CPU: {1}", prop.name, exp));
                    }

                    // needs to convert to srgb as color are linear in vfx graph
                    // This should not be performed for colors with the attribute [HDR] and be performed for vector4 with the attribute [Gamma]
                    // But property attributes cannot seem to be accessible from C# :(
                    if (prop.type == typeof(Color))
                    {
                        exp = VFXOperatorUtility.LinearToGamma(exp);
                    }

                    mapper.AddExpression(exp, prop.name, -1);
                }
                return(mapper);
            }

            case VFXDeviceTarget.CPU:
            {
                var mapper = new VFXExpressionMapper();
                mapper.AddExpression(GetInputSlot(0).GetExpression(), "mesh", -1);
                mapper.AddExpression(GetInputSlot(1).GetExpression(), "transform", -1);
                mapper.AddExpression(GetInputSlot(2).GetExpression(), "subMeshMask", -1);

                // TODO Remove this once material are serialized
                // Add material properties
                if (shader != null)
                {
                    var mat = meshData.GetOrCreateMaterial();
                    for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); ++i)
                    {
                        if (ShaderUtil.IsShaderPropertyHidden(shader, i))
                        {
                            var name   = ShaderUtil.GetPropertyName(shader, i);
                            var nameId = Shader.PropertyToID(name);
                            if (!mat.HasProperty(nameId))
                            {
                                continue;
                            }

                            VFXExpression expr = null;
                            switch (ShaderUtil.GetPropertyType(shader, i))
                            {
                            case ShaderUtil.ShaderPropertyType.Float:
                                expr = VFXValue.Constant <float>(mat.GetFloat(nameId));
                                break;

                            default:
                                break;
                            }

                            if (expr != null)
                            {
                                mapper.AddExpression(expr, name, -1);
                            }
                        }
                    }
                }

                return(mapper);
            }

            default:
                return(null);
            }
        }
Ejemplo n.º 26
0
        sealed protected override VFXExpression Evaluate(VFXExpression[] constParents)
        {
            var tex = constParents[0].Get <Texture>();

            return(VFXValue.Constant <uint>(tex ? (uint)tex.height : 0u));
        }
 static public VFXExpression DegToRad(VFXExpression degrees)
 {
     return(degrees * CastFloat(VFXValue.Constant(Mathf.PI / 180.0f), degrees.valueType));
 }
 public static VFXExpression operator&(VFXExpression a, uint b)
 {
     return(new VFXExpressionBitwiseAnd(a, VFXValue.Constant(b)));
 }
 static public VFXExpression FixedRandom(uint hash, bool perElement)
 {
     return(FixedRandom(VFXValue.Constant <uint>(hash), perElement));
 }
Ejemplo n.º 30
0
        public override VFXExpressionMapper GetExpressionMapper(VFXDeviceTarget target)
        {
            if (!m_Output)
            {
                throw new NullReferenceException("Unexpected call of GetExpressionMapper with a null output");
            }
            if (features == Features.None)
            {
                throw new InvalidOperationException("This additional update context has no feature set");
            }


            if (target == VFXDeviceTarget.GPU)
            {
                var expressionMapper = m_Output.GetExpressionMapper(target);

                var exp = GetExpressionsFromSlots(m_Output);

                if (HasFeature(Features.LOD))
                {
                    var lodExp   = exp.FirstOrDefault(e => e.name == VFXMultiMeshHelper.lodName);
                    var ratioExp = lodExp.exp * VFXValue.Constant(new Vector4(0.01f, 0.01f, 0.01f, 0.01f));
                    expressionMapper.AddExpression(ratioExp, VFXMultiMeshHelper.lodName, -1);
                }

                if (HasFeature(Features.LOD) || HasFeature(Features.FrustumCulling))
                {
                    var radiusScaleExp = exp.FirstOrDefault(e => e.name == "radiusScale").exp;
                    if (radiusScaleExp == null) // Not found, assume it's 1
                    {
                        radiusScaleExp = VFXValue.Constant(1.0f);
                    }
                    expressionMapper.AddExpression(radiusScaleExp, "radiusScale", -1);
                }

                if (HasFeature(Features.MotionVector))
                {
                    var currentFrameIndex = expressionMapper.FromNameAndId("currentFrameIndex", -1);
                    if (currentFrameIndex == null)
                    {
                        Debug.LogError("CurrentFrameIndex isn't reachable in encapsulatedOutput for motionVector");
                    }
                }

                //Since it's a compute shader without renderer associated, these entries aren't automatically sent
                expressionMapper.AddExpression(VFXBuiltInExpression.LocalToWorld, "unity_ObjectToWorld", -1);
                expressionMapper.AddExpression(VFXBuiltInExpression.WorldToLocal, "unity_WorldToObject", -1);
                if (m_Output.HasCustomSortingCriterion())
                {
                    var sortKeyExp = m_Output.inputSlots.First(s => s.name == "sortKey").GetExpression();
                    expressionMapper.AddExpression(sortKeyExp, "sortKey", -1);
                }


                return(expressionMapper);
            }
            else
            {
                return(new VFXExpressionMapper());
            }
        }