public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
        {
            var vertexOutputStruct = new ShaderStringBuilder(2);

            var vertexShader = new ShaderStringBuilder(2);
            var vertexShaderDescriptionInputs = new ShaderStringBuilder(2);
            var vertexShaderOutputs           = new ShaderStringBuilder(1);

            var pixelShader = new ShaderStringBuilder(2);
            var pixelShaderSurfaceInputs = new ShaderStringBuilder(2);
            var pixelShaderSurfaceRemap  = new ShaderStringBuilder(2);

            ShaderGenerator.GenerateStandardTransforms(
                0,
                16,
                vertexOutputStruct,
                vertexShader,
                vertexShaderDescriptionInputs,
                vertexShaderOutputs,
                pixelShader,
                pixelShaderSurfaceInputs,
                shaderGraphRequirements,
                shaderGraphRequirements,
                ShaderGraphRequirements.none,
                ShaderGraphRequirements.none,
                CoordinateSpace.World);

            vertexShader.AppendLines(vertexShaderDescriptionInputs.ToString());
            vertexShader.AppendLines(vertexShaderOutputs.ToString());

            if (node != null)
            {
                var outputSlot = node.GetOutputSlots <MaterialSlot>().FirstOrDefault();
                if (outputSlot != null)
                {
                    var result = string.Format("surf.{0}", node.GetVariableNameForSlot(outputSlot.id));
                    pixelShaderSurfaceRemap.AppendLine("return {0};", AdaptNodeOutputForPreview(node, outputSlot.id, result));
                }
                else
                {
                    pixelShaderSurfaceRemap.AppendLine("return 0;");
                }
            }
            else
            {
                pixelShaderSurfaceRemap.AppendLine("return surf.PreviewOutput;");
            }

            var res = subShaderTemplate.Replace("${Interpolators}", vertexOutputStruct.ToString());

            res = res.Replace("${VertexShader}", vertexShader.ToString());
            res = res.Replace("${LocalPixelShader}", pixelShader.ToString());
            res = res.Replace("${SurfaceInputs}", pixelShaderSurfaceInputs.ToString());
            res = res.Replace("${SurfaceOutputRemap}", pixelShaderSurfaceRemap.ToString());
            return(res);
        }
Beispiel #2
0
        public static string GetPreviewSubShader(AbstractMaterialNode node, ShaderGraphRequirements shaderGraphRequirements)
        {
            var interpolators = new ShaderGenerator();
            var vertexShader  = new ShaderGenerator();
            var pixelShader   = new ShaderGenerator();
            var surfaceInputs = new ShaderGenerator();

            ShaderGenerator.GenerateStandardTransforms(
                0,
                16,
                interpolators,
                vertexShader,
                pixelShader,
                surfaceInputs,
                shaderGraphRequirements,
                ShaderGraphRequirements.none,
                CoordinateSpace.World);

            var outputs = new ShaderGenerator();

            if (node != null)
            {
                var outputSlot = node.GetOutputSlots <MaterialSlot>().FirstOrDefault();
                if (outputSlot != null)
                {
                    var result = string.Format("surf.{0}", node.GetVariableNameForSlot(outputSlot.id));
                    outputs.AddShaderChunk(string.Format("return {0};", AdaptNodeOutputForPreview(node, outputSlot.id, result)), true);
                }
                else
                {
                    outputs.AddShaderChunk("return 0;", true);
                }
            }
            else
            {
                outputs.AddShaderChunk("return surf.PreviewOutput;", false);
            }

            var res = subShaderTemplate.Replace("${Interpolators}", interpolators.GetShaderString(0));

            res = res.Replace("${VertexShader}", vertexShader.GetShaderString(0));
            res = res.Replace("${LocalPixelShader}", pixelShader.GetShaderString(0));
            res = res.Replace("${SurfaceInputs}", surfaceInputs.GetShaderString(0));
            res = res.Replace("${SurfaceOutputRemap}", outputs.GetShaderString(0));
            return(res);
        }
Beispiel #3
0
        public static string AdaptNodeOutputForPreview(AbstractMaterialNode node, int outputSlotId)
        {
            var rawOutput = node.GetVariableNameForSlot(outputSlotId);

            return(AdaptNodeOutputForPreview(node, outputSlotId, rawOutput));
        }
Beispiel #4
0
        public static string AdaptNodeOutput(AbstractMaterialNode node, int outputSlotId, ConcreteSlotValueType convertToType)
        {
            var outputSlot = node.FindOutputSlot <MaterialSlot>(outputSlotId);

            if (outputSlot == null)
            {
                return(kErrorString);
            }

            var convertFromType = outputSlot.concreteValueType;
            var rawOutput       = node.GetVariableNameForSlot(outputSlotId);

            if (convertFromType == convertToType)
            {
                return(rawOutput);
            }

            switch (convertToType)
            {
            case ConcreteSlotValueType.Vector1:
                return(string.Format("({0}).x", rawOutput));

            case ConcreteSlotValueType.Vector2:
                switch (convertFromType)
                {
                case ConcreteSlotValueType.Vector1:
                    return(string.Format("({0}.xx)", rawOutput));

                case ConcreteSlotValueType.Vector3:
                case ConcreteSlotValueType.Vector4:
                    return(string.Format("({0}.xy)", rawOutput));

                default:
                    return(kErrorString);
                }

            case ConcreteSlotValueType.Vector3:
                switch (convertFromType)
                {
                case ConcreteSlotValueType.Vector1:
                    return(string.Format("({0}.xxx)", rawOutput));

                case ConcreteSlotValueType.Vector2:
                    return(string.Format("({0}3({1}, 0.0))", node.precision, rawOutput));

                case ConcreteSlotValueType.Vector4:
                    return(string.Format("({0}.xyz)", rawOutput));

                default:
                    return(kErrorString);
                }

            case ConcreteSlotValueType.Vector4:
                switch (convertFromType)
                {
                case ConcreteSlotValueType.Vector1:
                    return(string.Format("({0}.xxxx)", rawOutput));

                case ConcreteSlotValueType.Vector2:
                    return(string.Format("({0}4({1}, 0.0, 1.0))", node.precision, rawOutput));

                case ConcreteSlotValueType.Vector3:
                    return(string.Format("({0}4({1}, 1.0))", node.precision, rawOutput));

                default:
                    return(kErrorString);
                }

            case ConcreteSlotValueType.Matrix3:
                return(rawOutput);

            case ConcreteSlotValueType.Matrix2:
                return(rawOutput);

            default:
                return(kErrorString);
            }
        }
        internal static void GenerateSurfaceDescription(
            List <INode> activeNodeList,
            AbstractMaterialNode masterNode,
            AbstractMaterialGraph graph,
            ShaderGenerator surfaceDescriptionFunction,
            FunctionRegistry functionRegistry,
            PropertyCollector shaderProperties,
            ShaderGraphRequirements requirements,
            GenerationMode mode,
            string functionName                  = "PopulateSurfaceData",
            string surfaceDescriptionName        = "SurfaceDescription",
            FloatShaderProperty outputIdProperty = null,
            IEnumerable <MaterialSlot> slots     = null)
        {
            if (graph == null)
            {
                return;
            }

            surfaceDescriptionFunction.AddShaderChunk(String.Format("{0} {1}(SurfaceInputs IN) {{", surfaceDescriptionName, functionName), false);
            surfaceDescriptionFunction.Indent();
            surfaceDescriptionFunction.AddShaderChunk(String.Format("{0} surface = ({0})0;", surfaceDescriptionName), false);

            graph.CollectShaderProperties(shaderProperties, mode);

            foreach (var activeNode in activeNodeList.OfType <AbstractMaterialNode>())
            {
                if (activeNode is IGeneratesFunction)
                {
                    functionRegistry.builder.currentNode = activeNode;
                    (activeNode as IGeneratesFunction).GenerateNodeFunction(functionRegistry, mode);
                }
                if (activeNode is IGeneratesBodyCode)
                {
                    (activeNode as IGeneratesBodyCode).GenerateNodeCode(surfaceDescriptionFunction, mode);
                }
                if (masterNode == null && activeNode.hasPreview)
                {
                    var outputSlot = activeNode.GetOutputSlots <MaterialSlot>().FirstOrDefault();
                    if (outputSlot != null)
                    {
                        surfaceDescriptionFunction.AddShaderChunk(String.Format("if ({0} == {1}) {{ surface.PreviewOutput = {2}; return surface; }}", outputIdProperty.referenceName, activeNode.tempId.index, ShaderGenerator.AdaptNodeOutputForPreview(activeNode, outputSlot.id, activeNode.GetVariableNameForSlot(outputSlot.id))), false);
                    }
                }

                activeNode.CollectShaderProperties(shaderProperties, mode);
            }
            functionRegistry.builder.currentNode = null;

            if (masterNode != null)
            {
                if (masterNode is IMasterNode)
                {
                    var usedSlots = slots ?? masterNode.GetInputSlots <MaterialSlot>();
                    foreach (var input in usedSlots)
                    {
                        var foundEdges = graph.GetEdges(input.slotReference).ToArray();
                        if (foundEdges.Any())
                        {
                            var outputRef = foundEdges[0].outputSlot;
                            var fromNode  = graph.GetNodeFromGuid <AbstractMaterialNode>(outputRef.nodeGuid);
                            surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), fromNode.GetVariableNameForSlot(outputRef.slotId)), true);
                        }
                        else
                        {
                            surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(input.shaderOutputName), input.GetDefaultValue(mode)), true);
                        }
                    }
                }
                else if (masterNode.hasPreview)
                {
                    foreach (var slot in masterNode.GetOutputSlots <MaterialSlot>())
                    {
                        surfaceDescriptionFunction.AddShaderChunk(string.Format("surface.{0} = {1};", NodeUtils.GetHLSLSafeName(slot.shaderOutputName), masterNode.GetVariableNameForSlot(slot.id)), true);
                    }
                }
            }

            surfaceDescriptionFunction.AddShaderChunk("return surface;", false);
            surfaceDescriptionFunction.Deindent();
            surfaceDescriptionFunction.AddShaderChunk("}", false);
        }