Ejemplo n.º 1
0
        void UpdatePorts()
        {
            switch (keyword.keywordType)
            {
            case KeywordType.Boolean:
            {
                // Boolean type has preset slots
                AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
                AddSlot(new DynamicVectorMaterialSlot(1, "On", "On", SlotType.Input, Vector4.zero));
                AddSlot(new DynamicVectorMaterialSlot(2, "Off", "Off", SlotType.Input, Vector4.zero));
                RemoveSlotsNameNotMatching(new int[] { 0, 1, 2 });
                break;
            }

            case KeywordType.Enum:
            {
                // Get slots
                List <MaterialSlot> inputSlots = new List <MaterialSlot>();
                GetInputSlots(inputSlots);

                // Store the edges
                Dictionary <MaterialSlot, List <IEdge> > edgeDict = new Dictionary <MaterialSlot, List <IEdge> >();
                foreach (MaterialSlot slot in inputSlots)
                {
                    edgeDict.Add(slot, (List <IEdge>)slot.owner.owner.GetEdges(slot.slotReference));
                }

                // Remove old slots
                for (int i = 0; i < inputSlots.Count; i++)
                {
                    RemoveSlot(inputSlots[i].id);
                }

                // Add output slot
                AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));

                // Add input slots
                int[] slotIds = new int[keyword.entries.Count + 1];
                slotIds[keyword.entries.Count] = OutputSlotId;
                for (int i = 0; i < keyword.entries.Count; i++)
                {
                    // Get slot based on entry id
                    MaterialSlot slot = inputSlots.Where(x =>
                                                         x.id == keyword.entries[i].id &&
                                                         x.RawDisplayName() == keyword.entries[i].displayName &&
                                                         x.shaderOutputName == keyword.entries[i].referenceName).FirstOrDefault();

                    // If slot doesnt exist its new so create it
                    if (slot == null)
                    {
                        slot = new DynamicVectorMaterialSlot(keyword.entries[i].id, keyword.entries[i].displayName, keyword.entries[i].referenceName, SlotType.Input, Vector4.zero);
                    }

                    AddSlot(slot);
                    slotIds[i] = keyword.entries[i].id;
                }
                RemoveSlotsNameNotMatching(slotIds);

                // Reconnect the edges
                foreach (KeyValuePair <MaterialSlot, List <IEdge> > entry in edgeDict)
                {
                    foreach (IEdge edge in entry.Value)
                    {
                        owner.Connect(edge.outputSlot, edge.inputSlot);
                    }
                }
                break;
            }
            }

            ValidateNode();
        }
Ejemplo n.º 2
0
        public static bool RequiresVertexSkinning(this MaterialSlot slot)
        {
            var mayRequireVertexSkinning = slot as IMayRequireVertexSkinning;

            return(mayRequireVertexSkinning != null && mayRequireVertexSkinning.RequiresVertexSkinning());
        }
        public static bool RequiresDepthTexture(this MaterialSlot slot)
        {
            var mayRequireDepthTexture = slot as IMayRequireDepthTexture;

            return(mayRequireDepthTexture != null && mayRequireDepthTexture.RequiresDepthTexture());
        }
Ejemplo n.º 4
0
 public bool Equals(MaterialSlot other)
 {
     return(m_Id == other.m_Id && owner == other.owner);
 }
Ejemplo n.º 5
0
        public bool IsCompatibleStageWith(MaterialSlot otherSlot)
        {
            var candidateStage = otherSlot.stageCapability;

            return(stageCapability == ShaderStageCapability.All || candidateStage == stageCapability);
        }
Ejemplo n.º 6
0
        public sealed override void UpdateNodeAfterDeserialization()
        {
            var method = GetFunctionToConvert();

            if (method == null)
            {
                throw new ArgumentException("Mapped method is null on node" + this);
            }

            if (method.ReturnType != typeof(string))
            {
                throw new ArgumentException("Mapped function should return string");
            }

            // validate no duplicates
            var slotAtributes = method.GetParameters().Select(GetSlotAttribute).ToList();

            if (slotAtributes.Any(x => x == null))
            {
                throw new ArgumentException("Missing SlotAttribute on " + method.Name);
            }

            if (slotAtributes.GroupBy(x => x.slotId).Any(x => x.Count() > 1))
            {
                throw new ArgumentException("Duplicate SlotAttribute on " + method.Name);
            }

            List <MaterialSlot> slots = new List <MaterialSlot>();

            foreach (var par in method.GetParameters())
            {
                var attribute = GetSlotAttribute(par);
                var name      = GraphUtil.ConvertCamelCase(par.Name, true);

                MaterialSlot s;
                if (attribute.binding == Binding.None && !par.IsOut && par.ParameterType == typeof(Color))
                {
                    s = new ColorRGBAMaterialSlot(attribute.slotId, name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, stageCapability: attribute.stageCapability, hidden: attribute.hidden);
                }
                else if (attribute.binding == Binding.None && !par.IsOut && par.ParameterType == typeof(ColorRGBA))
                {
                    s = new ColorRGBAMaterialSlot(attribute.slotId, name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, stageCapability: attribute.stageCapability, hidden: attribute.hidden);
                }
                else if (attribute.binding == Binding.None && !par.IsOut && par.ParameterType == typeof(ColorRGB))
                {
                    s = new ColorRGBMaterialSlot(attribute.slotId, name, par.Name, SlotType.Input, attribute.defaultValue ?? Vector4.zero, ColorMode.Default, stageCapability: attribute.stageCapability, hidden: attribute.hidden);
                }
                else if (attribute.binding == Binding.None || par.IsOut)
                {
                    s = MaterialSlot.CreateMaterialSlot(
                        ConvertTypeToSlotValueType(par),
                        attribute.slotId,
                        name,
                        par.Name,
                        par.IsOut ? SlotType.Output : SlotType.Input,
                        attribute.defaultValue ?? Vector4.zero,
                        shaderStageCapability: attribute.stageCapability,
                        hidden: attribute.hidden);
                }
                else
                {
                    s = CreateBoundSlot(attribute.binding, attribute.slotId, name, par.Name, attribute.stageCapability, attribute.hidden);
                }
                slots.Add(s);

                m_Slots.Add(attribute);
            }
            foreach (var slot in slots)
            {
                AddSlot(slot);
            }
            RemoveSlotsNameNotMatching(slots.Select(x => x.id));
        }
Ejemplo n.º 7
0
        public void ValidateGraph()
        {
            var propertyNodes = GetNodes <PropertyNode>().Where(n => !m_Properties.Any(p => p.guid == n.propertyGuid)).ToArray();

            foreach (var pNode in propertyNodes)
            {
                ReplacePropertyNodeWithConcreteNodeNoValidate(pNode);
            }

            messageManager?.ClearAllFromProvider(this);
            //First validate edges, remove any
            //orphans. This can happen if a user
            //manually modifies serialized data
            //of if they delete a node in the inspector
            //debug view.
            foreach (var edge in edges.ToArray())
            {
                var outputNode = GetNodeFromGuid(edge.outputSlot.nodeGuid);
                var inputNode  = GetNodeFromGuid(edge.inputSlot.nodeGuid);

                MaterialSlot outputSlot = null;
                MaterialSlot inputSlot  = null;
                if (outputNode != null && inputNode != null)
                {
                    outputSlot = outputNode.FindOutputSlot <MaterialSlot>(edge.outputSlot.slotId);
                    inputSlot  = inputNode.FindInputSlot <MaterialSlot>(edge.inputSlot.slotId);
                }

                if (outputNode == null ||
                    inputNode == null ||
                    outputSlot == null ||
                    inputSlot == null ||
                    !outputSlot.IsCompatibleWith(inputSlot))
                {
                    //orphaned edge
                    RemoveEdgeNoValidate(edge);
                }
            }

            var temporaryMarks = IndexSetPool.Get();
            var permanentMarks = IndexSetPool.Get();
            var slots          = ListPool <MaterialSlot> .Get();

            // Make sure we process a node's children before the node itself.
            var stack = StackPool <AbstractMaterialNode> .Get();

            foreach (var node in GetNodes <AbstractMaterialNode>())
            {
                stack.Push(node);
            }
            while (stack.Count > 0)
            {
                var node = stack.Pop();
                if (permanentMarks.Contains(node.tempId.index))
                {
                    continue;
                }

                if (temporaryMarks.Contains(node.tempId.index))
                {
                    node.ValidateNode();
                    permanentMarks.Add(node.tempId.index);
                }
                else
                {
                    temporaryMarks.Add(node.tempId.index);
                    stack.Push(node);
                    node.GetInputSlots(slots);
                    foreach (var inputSlot in slots)
                    {
                        var nodeEdges = GetEdges(inputSlot.slotReference);
                        foreach (var edge in nodeEdges)
                        {
                            var fromSocketRef = edge.outputSlot;
                            var childNode     = GetNodeFromGuid(fromSocketRef.nodeGuid);
                            if (childNode != null)
                            {
                                stack.Push(childNode);
                            }
                        }
                    }
                    slots.Clear();
                }
            }

            StackPool <AbstractMaterialNode> .Release(stack);

            ListPool <MaterialSlot> .Release(slots);

            IndexSetPool.Release(temporaryMarks);
            IndexSetPool.Release(permanentMarks);

            foreach (var edge in m_AddedEdges.ToList())
            {
                if (!ContainsNodeGuid(edge.outputSlot.nodeGuid) || !ContainsNodeGuid(edge.inputSlot.nodeGuid))
                {
                    Debug.LogWarningFormat("Added edge is invalid: {0} -> {1}\n{2}", edge.outputSlot.nodeGuid, edge.inputSlot.nodeGuid, Environment.StackTrace);
                    m_AddedEdges.Remove(edge);
                }
            }
        }
Ejemplo n.º 8
0
        public static bool RequiresScreenPosition(this MaterialSlot slot, ShaderStageCapability stageCapability = ShaderStageCapability.All)
        {
            var mayRequireScreenPosition = slot as IMayRequireScreenPosition;

            return(mayRequireScreenPosition != null && mayRequireScreenPosition.RequiresScreenPosition(stageCapability));
        }
Ejemplo n.º 9
0
 public override void CopyValuesFrom(MaterialSlot foundSlot)
 {
     // This is a funky slot, that doesn't directly hold a value.
 }
Ejemplo n.º 10
0
        public static bool RequiresPixelPosition(this MaterialSlot slot, ShaderStageCapability stageCapability = ShaderStageCapability.All)
        {
            var mayRequirePixelPosition = slot as IMayRequirePixelPosition;

            return(mayRequirePixelPosition?.RequiresPixelPosition(stageCapability) ?? false);
        }
        public virtual void UpdateSlots()
        {
            var validNames = new List <int>();

            if (subGraphData == null)
            {
                return;
            }

            var props = subGraphData.inputs;

            foreach (var prop in props)
            {
                var           propType = prop.propertyType;
                SlotValueType slotType;

                switch (propType)
                {
                case PropertyType.Color:
                    slotType = SlotValueType.Vector4;
                    break;

                case PropertyType.Texture2D:
                    slotType = SlotValueType.Texture2D;
                    break;

                case PropertyType.Texture2DArray:
                    slotType = SlotValueType.Texture2DArray;
                    break;

                case PropertyType.Texture3D:
                    slotType = SlotValueType.Texture3D;
                    break;

                case PropertyType.Cubemap:
                    slotType = SlotValueType.Cubemap;
                    break;

                case PropertyType.Gradient:
                    slotType = SlotValueType.Gradient;
                    break;

                case PropertyType.Vector1:
                    slotType = SlotValueType.Vector1;
                    break;

                case PropertyType.Vector2:
                    slotType = SlotValueType.Vector2;
                    break;

                case PropertyType.Vector3:
                    slotType = SlotValueType.Vector3;
                    break;

                case PropertyType.Vector4:
                    slotType = SlotValueType.Vector4;
                    break;

                case PropertyType.Boolean:
                    slotType = SlotValueType.Boolean;
                    break;

                case PropertyType.Matrix2:
                    slotType = SlotValueType.Matrix2;
                    break;

                case PropertyType.Matrix3:
                    slotType = SlotValueType.Matrix3;
                    break;

                case PropertyType.Matrix4:
                    slotType = SlotValueType.Matrix4;
                    break;

                case PropertyType.SamplerState:
                    slotType = SlotValueType.SamplerState;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                var propertyString = prop.guid.ToString();
                var propertyIndex  = m_PropertyGuids.IndexOf(propertyString);
                if (propertyIndex < 0)
                {
                    propertyIndex = m_PropertyGuids.Count;
                    m_PropertyGuids.Add(propertyString);
                    m_PropertyIds.Add(prop.guid.GetHashCode());
                }
                var          id   = m_PropertyIds[propertyIndex];
                MaterialSlot slot = MaterialSlot.CreateMaterialSlot(slotType, id, prop.displayName, prop.referenceName, SlotType.Input, prop.defaultValue, ShaderStageCapability.All);

                // copy default for texture for niceness
                if (slotType == SlotValueType.Texture2D && propType == PropertyType.Texture2D)
                {
                    var tSlot = slot as Texture2DInputMaterialSlot;
                    var tProp = prop as TextureShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.texture = tProp.value.texture;
                    }
                }
                // copy default for texture array for niceness
                else if (slotType == SlotValueType.Texture2DArray && propType == PropertyType.Texture2DArray)
                {
                    var tSlot = slot as Texture2DArrayInputMaterialSlot;
                    var tProp = prop as Texture2DArrayShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.textureArray = tProp.value.textureArray;
                    }
                }
                // copy default for texture 3d for niceness
                else if (slotType == SlotValueType.Texture3D && propType == PropertyType.Texture3D)
                {
                    var tSlot = slot as Texture3DInputMaterialSlot;
                    var tProp = prop as Texture3DShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.texture = tProp.value.texture;
                    }
                }
                // copy default for cubemap for niceness
                else if (slotType == SlotValueType.Cubemap && propType == PropertyType.Cubemap)
                {
                    var tSlot = slot as CubemapInputMaterialSlot;
                    var tProp = prop as CubemapShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.cubemap = tProp.value.cubemap;
                    }
                }
                // copy default for gradient for niceness
                else if (slotType == SlotValueType.Gradient && propType == PropertyType.Gradient)
                {
                    var tSlot = slot as GradientInputMaterialSlot;
                    var tProp = prop as GradientShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                AddSlot(slot);
                validNames.Add(id);
            }

            var outputStage = subGraphData.effectiveShaderStage;

            foreach (var slot in subGraphData.outputs)
            {
                AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(),
                                                        slot.shaderOutputName, SlotType.Output, Vector4.zero, outputStage));
                validNames.Add(slot.id);
            }

            RemoveSlotsNameNotMatching(validNames, true);
        }
        public static NeededCoordinateSpace RequiresBitangent(this MaterialSlot slot)
        {
            var mayRequireBitangent = slot as IMayRequireBitangent;

            return(mayRequireBitangent != null?mayRequireBitangent.RequiresBitangent() : NeededCoordinateSpace.None);
        }
Ejemplo n.º 13
0
        void UpdatePorts()
        {
            switch (keyword.keywordType)
            {
            case KeywordType.Boolean:
            {
                // Boolean type has preset slots
                PooledList <MaterialSlot> temp = PooledList <MaterialSlot> .Get();

                GetInputSlots(temp);
                if (temp.Any())
                {
                    temp.Dispose();
                    break;
                }
                else
                {
                    temp.Dispose();
                }
                AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
                AddSlot(new DynamicVectorMaterialSlot(1, "On", "On", SlotType.Input, Vector4.zero));
                AddSlot(new DynamicVectorMaterialSlot(2, "Off", "Off", SlotType.Input, Vector4.zero));
                RemoveSlotsNameNotMatching(new int[] { 0, 1, 2 });
                break;
            }

            case KeywordType.Enum:
                using (var inputSlots = PooledList <MaterialSlot> .Get())
                    using (var slotIDs = PooledList <int> .Get())
                    {
                        // Get slots
                        GetInputSlots(inputSlots);


                        // Add output slot
                        AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero));
                        slotIDs.Add(OutputSlotId);

                        // Add input slots
                        for (int i = 0; i < keyword.entries.Count; i++)
                        {
                            // Get slot based on entry id
                            MaterialSlot slot = inputSlots.Find(x =>
                                                                x.id == keyword.entries[i].id &&
                                                                x.RawDisplayName() == keyword.entries[i].displayName &&
                                                                x.shaderOutputName == keyword.entries[i].referenceName);

                            // If slot doesn't exist, it's new so create it
                            if (slot == null)
                            {
                                slot = new DynamicVectorMaterialSlot(keyword.entries[i].id, keyword.entries[i].displayName, keyword.entries[i].referenceName, SlotType.Input, Vector4.zero);
                            }

                            AddSlot(slot);
                            slotIDs.Add(keyword.entries[i].id);
                        }
                        RemoveSlotsNameNotMatching(slotIDs);
                        bool orderChanged = SetSlotOrder(slotIDs);
                        if (orderChanged)
                        {
                            // unfortunately there is no way to get the view to update slot order other than Topological
                            Dirty(ModificationScope.Topological);
                        }
                        break;
                    }
            }

            ValidateNode();
        }
Ejemplo n.º 14
0
        // Internal validation
        // -------------------------------------------------

        public override void EvaluateDynamicMaterialSlots()
        {
            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            using (var tempSlots = PooledList <MaterialSlot> .Get())
            {
                GetInputSlots(tempSlots);
                foreach (var inputSlot in tempSlots)
                {
                    inputSlot.hasError = false;

                    // if there is a connection
                    var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                    if (!edges.Any())
                    {
                        if (inputSlot is DynamicValueMaterialSlot)
                        {
                            skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                        }
                        continue;
                    }

                    // get the output details
                    var outputSlotRef = edges[0].outputSlot;
                    var outputNode    = outputSlotRef.node;
                    if (outputNode == null)
                    {
                        continue;
                    }

                    var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                    if (outputSlot == null)
                    {
                        continue;
                    }

                    if (outputSlot.hasError)
                    {
                        inputSlot.hasError = true;
                        continue;
                    }

                    var outputConcreteType = outputSlot.concreteValueType;
                    // dynamic input... depends on output from other node.
                    // we need to compare ALL dynamic inputs to make sure they
                    // are compatable.
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                        continue;
                    }
                }

                m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

                // Resolve dynamics depending on matrix/vector configuration
                switch (m_MultiplyType)
                {
                // If all matrix resolve as per dynamic matrix
                case MultiplyType.Matrix:
                    var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(dynamicMatrixType);
                    }
                    break;

                // If mixed handle differently:
                // Iterate all slots and set their concretes based on their edges
                // Find matrix slot and convert its type to a vector type
                // Reiterate all slots and set non matrix slots to the vector type
                case MultiplyType.Mixed:
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                    }
                    MaterialSlot          matrixSlot = GetMatrixSlot();
                    ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        if (dynamicKvP.Key != matrixSlot)
                        {
                            dynamicKvP.Key.SetConcreteType(vectorType);
                        }
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(vectorType);
                    }
                    break;

                // If all vector resolve as per dynamic vector
                default:
                    var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                    foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                    {
                        dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                    }
                    foreach (var skippedSlot in skippedDynamicSlots)
                    {
                        skippedSlot.SetConcreteType(dynamicVectorType);
                    }
                    break;
                }

                tempSlots.Clear();
                GetInputSlots(tempSlots);
                bool inputError = tempSlots.Any(x => x.hasError);
                if (inputError)
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had input error", objectId));
                    hasError = true;
                }
                // configure the output slots now
                // their slotType will either be the default output slotType
                // or the above dynanic slotType for dynamic nodes
                // or error if there is an input error
                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                foreach (var outputSlot in tempSlots)
                {
                    outputSlot.hasError = false;

                    if (inputError)
                    {
                        outputSlot.hasError = true;
                        continue;
                    }

                    if (outputSlot is DynamicValueMaterialSlot)
                    {
                        // Apply similar logic to output slot
                        switch (m_MultiplyType)
                        {
                        // As per dynamic matrix
                        case MultiplyType.Matrix:
                            var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                            break;

                        // Mixed configuration
                        // Find matrix slot and convert type to vector
                        // Set output concrete to vector
                        case MultiplyType.Mixed:
                            MaterialSlot          matrixSlot = GetMatrixSlot();
                            ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                            break;

                        // As per dynamic vector
                        default:
                            var dynamicVectorType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                            (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                            break;
                        }
                        continue;
                    }
                }

                tempSlots.Clear();
                GetOutputSlots(tempSlots);
                if (tempSlots.Any(x => x.hasError))
                {
                    owner.AddConcretizationError(objectId, string.Format("Node {0} had output error", objectId));
                    hasError = true;
                }
            }

            CalculateNodeHasError();

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Ejemplo n.º 15
0
        // Internal validation
        // -------------------------------------------------

        public override void ValidateNode()
        {
            var isInError    = false;
            var errorMessage = k_validationErrorMessage;

            // all children nodes needs to be updated first
            // so do that here
            var slots = ListPool <MaterialSlot> .Get();

            GetInputSlots(slots);
            foreach (var inputSlot in slots)
            {
                inputSlot.hasError = false;

                var edges = owner.GetEdges(inputSlot.slotReference);
                foreach (var edge in edges)
                {
                    var fromSocketRef = edge.outputSlot;
                    var outputNode    = owner.GetNodeFromGuid(fromSocketRef.nodeGuid);
                    if (outputNode == null)
                    {
                        continue;
                    }

                    outputNode.ValidateNode();
                }
            }
            ListPool <MaterialSlot> .Release(slots);

            var dynamicInputSlotsToCompare = DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Get();

            var skippedDynamicSlots = ListPool <DynamicValueMaterialSlot> .Get();

            // iterate the input slots
            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            foreach (var inputSlot in s_TempSlots)
            {
                // if there is a connection
                var edges = owner.GetEdges(inputSlot.slotReference).ToList();
                if (!edges.Any())
                {
                    if (inputSlot is DynamicValueMaterialSlot)
                    {
                        skippedDynamicSlots.Add(inputSlot as DynamicValueMaterialSlot);
                    }
                    continue;
                }

                // get the output details
                var outputSlotRef = edges[0].outputSlot;
                var outputNode    = owner.GetNodeFromGuid(outputSlotRef.nodeGuid);
                if (outputNode == null)
                {
                    continue;
                }

                var outputSlot = outputNode.FindOutputSlot <MaterialSlot>(outputSlotRef.slotId);
                if (outputSlot == null)
                {
                    continue;
                }

                if (outputSlot.hasError)
                {
                    inputSlot.hasError = true;
                    continue;
                }

                var outputConcreteType = outputSlot.concreteValueType;
                // dynamic input... depends on output from other node.
                // we need to compare ALL dynamic inputs to make sure they
                // are compatable.
                if (inputSlot is DynamicValueMaterialSlot)
                {
                    dynamicInputSlotsToCompare.Add((DynamicValueMaterialSlot)inputSlot, outputConcreteType);
                    continue;
                }

                // if we have a standard connection... just check the types work!
                if (!ImplicitConversionExists(outputConcreteType, inputSlot.concreteValueType))
                {
                    inputSlot.hasError = true;
                }
            }

            m_MultiplyType = GetMultiplyType(dynamicInputSlotsToCompare.Values);

            // Resolve dynamics depending on matrix/vector configuration
            switch (m_MultiplyType)
            {
            // If all matrix resolve as per dynamic matrix
            case MultiplyType.Matrix:
                var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicMatrixType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicMatrixType);
                }
                break;

            // If mixed handle differently:
            // Iterate all slots and set their concretes based on their edges
            // Find matrix slot and convert its type to a vector type
            // Reiterate all slots and set non matrix slots to the vector type
            case MultiplyType.Mixed:
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    SetConcreteValueTypeFromEdge(dynamicKvP.Key);
                }
                MaterialSlot          matrixSlot = GetMatrixSlot();
                ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    if (dynamicKvP.Key != matrixSlot)
                    {
                        dynamicKvP.Key.SetConcreteType(vectorType);
                    }
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(vectorType);
                }
                break;

            // If all vector resolve as per dynamic vector
            default:
                var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                foreach (var dynamicKvP in dynamicInputSlotsToCompare)
                {
                    dynamicKvP.Key.SetConcreteType(dynamicVectorType);
                }
                foreach (var skippedSlot in skippedDynamicSlots)
                {
                    skippedSlot.SetConcreteType(dynamicVectorType);
                }
                break;
            }

            s_TempSlots.Clear();
            GetInputSlots(s_TempSlots);
            var inputError = s_TempSlots.Any(x => x.hasError);

            // configure the output slots now
            // their slotType will either be the default output slotType
            // or the above dynanic slotType for dynamic nodes
            // or error if there is an input error
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            foreach (var outputSlot in s_TempSlots)
            {
                outputSlot.hasError = false;

                if (inputError)
                {
                    outputSlot.hasError = true;
                    continue;
                }

                if (outputSlot is DynamicValueMaterialSlot)
                {
                    // Apply similar logic to output slot
                    switch (m_MultiplyType)
                    {
                    // As per dynamic matrix
                    case MultiplyType.Matrix:
                        var dynamicMatrixType = ConvertDynamicMatrixInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicMatrixType);
                        break;

                    // Mixed configuration
                    // Find matrix slot and convert type to vector
                    // Set output concrete to vector
                    case MultiplyType.Mixed:
                        MaterialSlot          matrixSlot = GetMatrixSlot();
                        ConcreteSlotValueType vectorType = SlotValueHelper.ConvertMatrixToVectorType(matrixSlot.concreteValueType);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(vectorType);
                        break;

                    // As per dynamic vector
                    default:
                        var dynamicVectorType = ConvertDynamicInputTypeToConcrete(dynamicInputSlotsToCompare.Values);
                        (outputSlot as DynamicValueMaterialSlot).SetConcreteType(dynamicVectorType);
                        break;
                    }
                    continue;
                }
            }

            isInError |= inputError;
            s_TempSlots.Clear();
            GetOutputSlots(s_TempSlots);
            isInError |= s_TempSlots.Any(x => x.hasError);
            isInError |= CalculateNodeHasError(ref errorMessage);
            hasError   = isInError;

            if (isInError)
            {
                ((AbstractMaterialGraph)owner).AddValidationError(tempId, errorMessage);
            }
            else
            {
                ++version;
            }

            ListPool <DynamicValueMaterialSlot> .Release(skippedDynamicSlots);

            DictionaryPool <DynamicValueMaterialSlot, ConcreteSlotValueType> .Release(dynamicInputSlotsToCompare);
        }
Ejemplo n.º 16
0
 public override void CopyValuesFrom(MaterialSlot foundSlot)
 {
     var slot = foundSlot as Vector1MaterialSlot;
     if (slot != null)
         value = slot.value;
 }
Ejemplo n.º 17
0
 bool Equals(MaterialSlot other)
 {
     return(m_Id == other.m_Id && owner.guid.Equals(other.owner.guid));
 }
Ejemplo n.º 18
0
 public override void CopyDefaultValue(MaterialSlot other)
 {
 }
 public override void CopyValuesFrom(MaterialSlot foundSlot)
 {
     var slot = foundSlot as DynamicMatrixMaterialSlot;
     if (slot != null)
         value = slot.value;
 }
 private string GetParamTypeName(MaterialSlot slot)
 {
     return(NodeUtils.ConvertConcreteSlotValueTypeToString(precision, slot.concreteValueType));
 }
Ejemplo n.º 21
0
        public virtual void UpdateSlots()
        {
            var validNames = new List <int>();

            if (asset == null)
            {
                return;
            }

            var props = asset.inputs;

            foreach (var prop in props)
            {
                SlotValueType valueType      = prop.concreteShaderValueType.ToSlotValueType();
                var           propertyString = prop.guid.ToString();
                var           propertyIndex  = m_PropertyGuids.IndexOf(propertyString);
                if (propertyIndex < 0)
                {
                    propertyIndex = m_PropertyGuids.Count;
                    m_PropertyGuids.Add(propertyString);
                    m_PropertyIds.Add(prop.guid.GetHashCode());
                }
                var          id   = m_PropertyIds[propertyIndex];
                MaterialSlot slot = MaterialSlot.CreateMaterialSlot(valueType, id, prop.displayName, prop.referenceName, SlotType.Input, Vector4.zero, ShaderStageCapability.All);

                // Copy defaults
                switch (prop.concreteShaderValueType)
                {
                case ConcreteSlotValueType.Matrix4:
                {
                    var tSlot = slot as Matrix4MaterialSlot;
                    var tProp = prop as Matrix4ShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Matrix3:
                {
                    var tSlot = slot as Matrix3MaterialSlot;
                    var tProp = prop as Matrix3ShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Matrix2:
                {
                    var tSlot = slot as Matrix2MaterialSlot;
                    var tProp = prop as Matrix2ShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Texture2D:
                {
                    var tSlot = slot as Texture2DInputMaterialSlot;
                    var tProp = prop as Texture2DShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.texture = tProp.value.texture;
                    }
                }
                break;

                case ConcreteSlotValueType.Texture2DArray:
                {
                    var tSlot = slot as Texture2DArrayInputMaterialSlot;
                    var tProp = prop as Texture2DArrayShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.textureArray = tProp.value.textureArray;
                    }
                }
                break;

                case ConcreteSlotValueType.Texture3D:
                {
                    var tSlot = slot as Texture3DInputMaterialSlot;
                    var tProp = prop as Texture3DShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.texture = tProp.value.texture;
                    }
                }
                break;

                case ConcreteSlotValueType.Cubemap:
                {
                    var tSlot = slot as CubemapInputMaterialSlot;
                    var tProp = prop as CubemapShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.cubemap = tProp.value.cubemap;
                    }
                }
                break;

                case ConcreteSlotValueType.Gradient:
                {
                    var tSlot = slot as GradientInputMaterialSlot;
                    var tProp = prop as GradientShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Vector4:
                {
                    var tSlot       = slot as Vector4MaterialSlot;
                    var vector4Prop = prop as Vector4ShaderProperty;
                    var colorProp   = prop as ColorShaderProperty;
                    if (tSlot != null && vector4Prop != null)
                    {
                        tSlot.value = vector4Prop.value;
                    }
                    else if (tSlot != null && colorProp != null)
                    {
                        tSlot.value = colorProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Vector3:
                {
                    var tSlot = slot as Vector3MaterialSlot;
                    var tProp = prop as Vector3ShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Vector2:
                {
                    var tSlot = slot as Vector2MaterialSlot;
                    var tProp = prop as Vector2ShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Vector1:
                {
                    var tSlot = slot as Vector1MaterialSlot;
                    var tProp = prop as Vector1ShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;

                case ConcreteSlotValueType.Boolean:
                {
                    var tSlot = slot as BooleanMaterialSlot;
                    var tProp = prop as BooleanShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.value = tProp.value;
                    }
                }
                break;
                }

                AddSlot(slot);
                validNames.Add(id);
            }

            var outputStage = asset.effectiveShaderStage;

            foreach (var slot in asset.outputs)
            {
                var newSlot = MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(),
                                                              slot.shaderOutputName, SlotType.Output, Vector4.zero, outputStage, slot.hidden);
                AddSlot(newSlot);
                validNames.Add(slot.id);
            }

            RemoveSlotsNameNotMatching(validNames, true);
        }
Ejemplo n.º 22
0
        public static bool RequiresScreenPosition(this MaterialSlot slot)
        {
            var mayRequireScreenPosition = slot as IMayRequireScreenPosition;

            return(mayRequireScreenPosition != null && mayRequireScreenPosition.RequiresScreenPosition());
        }
 public override void CopyValuesFrom(MaterialSlot foundSlot)
 {
 }
        public virtual void UpdateSlots()
        {
            var validNames = new List <int>();

            if (referencedGraph == null)
            {
                RemoveSlotsNameNotMatching(validNames);
                return;
            }

            var props = referencedGraph.properties;

            foreach (var prop in props)
            {
                var           propType = prop.propertyType;
                SlotValueType slotType;

                switch (propType)
                {
                case PropertyType.Color:
                    slotType = SlotValueType.Vector4;
                    break;

                case PropertyType.Texture:
                    slotType = SlotValueType.Texture2D;
                    break;

                case PropertyType.Cubemap:
                    slotType = SlotValueType.Cubemap;
                    break;

                case PropertyType.Vector1:
                    slotType = SlotValueType.Vector1;
                    break;

                case PropertyType.Vector2:
                    slotType = SlotValueType.Vector2;
                    break;

                case PropertyType.Vector3:
                    slotType = SlotValueType.Vector3;
                    break;

                case PropertyType.Vector4:
                    slotType = SlotValueType.Vector4;
                    break;

                case PropertyType.Matrix2:
                    slotType = SlotValueType.Matrix2;
                    break;

                case PropertyType.Matrix3:
                    slotType = SlotValueType.Matrix3;
                    break;

                case PropertyType.Matrix4:
                    slotType = SlotValueType.Matrix4;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                var          id   = prop.guid.GetHashCode();
                MaterialSlot slot = MaterialSlot.CreateMaterialSlot(slotType, id, prop.displayName, prop.referenceName, SlotType.Input, prop.defaultValue);
                // copy default for texture for niceness
                if (slotType == SlotValueType.Texture2D && propType == PropertyType.Texture)
                {
                    var tSlot = slot as Texture2DInputMaterialSlot;
                    var tProp = prop as TextureShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.texture = tProp.value.texture;
                    }
                }
                // copy default for cubemap for niceness
                else if (slotType == SlotValueType.Cubemap && propType == PropertyType.Cubemap)
                {
                    var tSlot = slot as CubemapInputMaterialSlot;
                    var tProp = prop as CubemapShaderProperty;
                    if (tSlot != null && tProp != null)
                    {
                        tSlot.cubemap = tProp.value.cubemap;
                    }
                }
                AddSlot(slot);
                validNames.Add(id);
            }

            var subGraphOutputNode = outputNode;

            if (outputNode != null)
            {
                foreach (var slot in NodeExtensions.GetInputSlots <MaterialSlot>(subGraphOutputNode))
                {
                    AddSlot(MaterialSlot.CreateMaterialSlot(slot.valueType, slot.id, slot.RawDisplayName(), slot.shaderOutputName, SlotType.Output, Vector4.zero));
                    validNames.Add(slot.id);
                }
            }

            RemoveSlotsNameNotMatching(validNames);
        }
Ejemplo n.º 25
0
 public abstract void CopyValuesFrom(MaterialSlot foundSlot);
        public static bool RequiresFaceSign(this MaterialSlot slot)
        {
            var mayRequireFaceSign = slot as IMayRequireFaceSign;

            return(mayRequireFaceSign != null && mayRequireFaceSign.RequiresFaceSign());
        }