Exemplo n.º 1
0
        public override string GenerateShaderForOutput(int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar)
        {
            if (dataCollector.PortCategory == MasterNodePortCategory.Tessellation)
            {
                UIUtils.ShowMessage(m_nodeAttribs.Name + " cannot be used on Master Node Tessellation port");
                return("-1");
            }

            bool isVertex = (dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation);

            string portProperty = string.Empty;

            if (m_texPort.IsConnected)
            {
                portProperty = m_texPort.GenerateShaderForOutput(ref dataCollector, m_texPort.DataType, ignoreLocalVar);
            }

            if (m_referenceArrayId > -1)
            {
                TexturePropertyNode temp = UIUtils.GetTexturePropertyNode(m_referenceArrayId);
                if (temp != null)
                {
                    portProperty = temp.BaseGenerateShaderForOutput(outputId, ref dataCollector, ignoreLocalVar);
                }
            }

            //TEMPLATES
            if (dataCollector.MasterNodeCategory == AvailableShaderTypes.Template)
            {
                if (m_outputPorts[0].IsLocalValue)
                {
                    return(GetOutputVectorItem(0, outputId, m_outputPorts[0].LocalValue));
                }

                string uvName = string.Empty;
                if (dataCollector.TemplateDataCollectorInstance.HasUV(m_textureCoordChannel))
                {
                    uvName = dataCollector.TemplateDataCollectorInstance.GetUVName(m_textureCoordChannel);
                }
                else
                {
                    uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV(m_textureCoordChannel);
                    //string uvName = TemplateHelperFunctions.GenerateTextureSemantic( ref dataCollector, m_textureCoordChannel );
                    //uvName = ( dataCollector.IsFragmentCategory ? Constants.InputVarStr : Constants.VertexShaderInputStr ) + "." + uvName;
                }
                string currPropertyName = GetValidPropertyName();
                if (!string.IsNullOrEmpty(portProperty) && portProperty != "0.0")
                {
                    currPropertyName = portProperty;
                }
                if (!string.IsNullOrEmpty(currPropertyName))
                {
                    string finalTexCoordName      = "uv" + currPropertyName;
                    string dummyPropertyTexcoords = currPropertyName + "_ST";
                    dataCollector.AddToUniforms(UniqueId, "float4", dummyPropertyTexcoords);

                    if (m_texcoordSize > 2)
                    {
                        dataCollector.AddLocalVariable(UniqueId, m_currentPrecisionType, m_outputPorts[0].DataType, finalTexCoordName, uvName);
                        dataCollector.AddLocalVariable(UniqueId, finalTexCoordName + ".xy", string.Format(Constants.TilingOffsetFormat, uvName + ".xy", dummyPropertyTexcoords + ".xy", dummyPropertyTexcoords + ".zw") + ";");
                        m_outputPorts[0].SetLocalValue(finalTexCoordName);
                    }
                    else
                    {
                        RegisterLocalVariable(0, string.Format(Constants.TilingOffsetFormat, uvName, dummyPropertyTexcoords + ".xy", dummyPropertyTexcoords + ".zw"), ref dataCollector, finalTexCoordName);
                    }
                    //RegisterLocalVariable( 0, string.Format( Constants.TilingOffsetFormat, uvName, dummyPropertyTexcoords+".xy", dummyPropertyTexcoords+".zw" ), ref dataCollector, finalTexCoordName );
                }
                else
                {
                    string finalTexCoordName = "uv" + OutputId;
                    string tiling            = m_tilingPort.GeneratePortInstructions(ref dataCollector);
                    string offset            = m_offsetPort.GeneratePortInstructions(ref dataCollector);

                    if (m_texcoordSize > 2)
                    {
                        dataCollector.AddLocalVariable(UniqueId, m_currentPrecisionType, m_outputPorts[0].DataType, finalTexCoordName, uvName);
                        dataCollector.AddLocalVariable(UniqueId, finalTexCoordName + ".xy", string.Format(Constants.TilingOffsetFormat, uvName + ".xy", tiling, offset) + ";");
                        m_outputPorts[0].SetLocalValue(finalTexCoordName);
                    }
                    else
                    {
                        RegisterLocalVariable(0, string.Format(Constants.TilingOffsetFormat, uvName, tiling, offset), ref dataCollector, finalTexCoordName);
                    }
                    //RegisterLocalVariable( 0, string.Format( Constants.TilingOffsetFormat, uvName, tiling, offset ), ref dataCollector, finalTexCoordName );
                }
                return(GetOutputVectorItem(0, outputId, m_outputPorts[0].LocalValue));
            }

            //SURFACE
            string propertyName = GetValidPropertyName();

            if (!string.IsNullOrEmpty(portProperty) && portProperty != "0.0")
            {
                propertyName = portProperty;
            }

            if (!string.IsNullOrEmpty(propertyName) /*m_referenceArrayId > -1*/)
            {
                //m_referenceNode = UIUtils.GetTexturePropertyNode( m_referenceArrayId );
                //if ( m_referenceNode != null )
                //{
                //string propertyName = m_referenceNode.PropertyName;
                int    coordSet = ((m_textureCoordChannel < 0) ? 0 : m_textureCoordChannel);
                string uvName   = string.Empty;

                string dummyPropUV = "_tex" + (m_texcoordSize > 2 ? "" + m_texcoordSize : "") + "coord" + (coordSet > 0 ? (coordSet + 1).ToString() : "");
                string dummyUV     = "uv" + (coordSet > 0 ? (coordSet + 1).ToString() : "") + dummyPropUV;

                if (isVertex)
                {
                    uvName = IOUtils.GetUVChannelName(propertyName, coordSet) + m_texcoordSize.ToString() + coordSet.ToString();
                    string vertexInput = Constants.VertexShaderInputStr + ".texcoord";
                    if (coordSet > 0)
                    {
                        vertexInput += coordSet.ToString();
                    }

                    dataCollector.AddToVertexLocalVariables(UniqueId, "float" + m_texcoordSize + " " + uvName + " = " + vertexInput + ";");
                    dataCollector.AddToVertexLocalVariables(UniqueId, uvName + ".xy = " + vertexInput + ".xy * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw;");
                }
                else
                {
                    uvName = IOUtils.GetUVChannelName(propertyName, coordSet);
                    if (m_texcoordSize > 2)
                    {
                        uvName += m_texcoordSize;
                        dataCollector.UsingHigherSizeTexcoords = true;
                        dataCollector.AddToLocalVariables(UniqueId, "float" + m_texcoordSize + " " + uvName + " = " + Constants.InputVarStr + "." + dummyUV + ";");
                        dataCollector.AddToLocalVariables(UniqueId, uvName + ".xy = " + Constants.InputVarStr + "." + dummyUV + ".xy * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw;");
                    }
                    else
                    {
                        dataCollector.AddToLocalVariables(UniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw");
                    }
                }

                dataCollector.AddToUniforms(UniqueId, "uniform float4 " + propertyName + "_ST;");
                dataCollector.AddToProperties(UniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100);
                dataCollector.AddToInput(UniqueId, "float" + m_texcoordSize + " " + dummyUV, true);

                return(GetOutputVectorItem(0, outputId, uvName));
                //}
            }

            if (m_texcoordId < 0)
            {
                if (!isVertex && dataCollector.TesselationActive)
                {
                    return(GenerateFragShaderForOutput(outputId, ref dataCollector, ignoreLocalVar));
                }

                bool tessVertexMode = isVertex && dataCollector.TesselationActive;

                m_texcoordId = dataCollector.AvailableUvIndex;
                string texcoordName = TexCoordStr + m_texcoordId;



                string uvChannel = m_textureCoordChannel == 0 ? ".xy" : m_textureCoordChannel + ".xy";

                MasterNodePortCategory portCategory = dataCollector.PortCategory;
                if (dataCollector.PortCategory != MasterNodePortCategory.Vertex && dataCollector.PortCategory != MasterNodePortCategory.Tessellation)
                {
                    dataCollector.PortCategory = MasterNodePortCategory.Vertex;
                }

                // We need to reset local variables if there are already created to force them to be created in the vertex function
                int buffer = m_texcoordId;
                ContainerGraph.ResetNodesLocalVariablesIfNot(this, MasterNodePortCategory.Vertex);

                bool dirtySpecialVarsBefore = dataCollector.DirtySpecialLocalVariables;
                bool dirtyVertexVarsBefore  = dataCollector.DirtyVertexVariables;

                string tiling = m_tilingPort.GenerateShaderForOutput(ref dataCollector, WirePortDataType.FLOAT2, false, true);
                string offset = m_offsetPort.GenerateShaderForOutput(ref dataCollector, WirePortDataType.FLOAT2, false, true);
                dataCollector.PortCategory = portCategory;

                string vertexUV = Constants.VertexShaderInputStr + ".texcoord" + uvChannel;

                if (!tessVertexMode)
                {
                    dataCollector.AddToInput(UniqueId, "float" + m_texcoordSize + " " + texcoordName, true);
                }

                bool resetLocals = false;
                // new texture coordinates are calculated on the vertex shader so we need to register its local vars
                if (!dirtySpecialVarsBefore && dataCollector.DirtySpecialLocalVariables)
                {
                    dataCollector.AddVertexInstruction(dataCollector.SpecialLocalVariables, UniqueId, false);
                    dataCollector.ClearSpecialLocalVariables();
                    resetLocals = true;
                }

                if (!dirtyVertexVarsBefore && dataCollector.DirtyVertexVariables)
                {
                    dataCollector.AddVertexInstruction(dataCollector.VertexLocalVariables, UniqueId, false);
                    dataCollector.ClearVertexLocalVariables();
                    resetLocals = true;
                }

                //Reset local variables again so they wont be caught on the fragment shader
                if (resetLocals)
                {
                    ContainerGraph.ResetNodesLocalVariablesIfNot(this, MasterNodePortCategory.Vertex);
                }

                if (tessVertexMode)
                {
                    dataCollector.AddToVertexLocalVariables(UniqueId, vertexUV + " = " + vertexUV + " * " + tiling + " + " + offset + ";");
                    m_surfaceTexcoordName = Constants.VertexShaderInputStr + "." + IOUtils.GetVertexUVChannelName(m_textureCoordChannel) + ".xy";
                }
                else
                {
                    if (dataCollector.TesselationActive)
                    {
                        if (isVertex)
                        {
                            dataCollector.AddToVertexLocalVariables(UniqueId, vertexUV + " = " + vertexUV + " * " + tiling + " + " + offset + ";");
                            m_surfaceTexcoordName = Constants.VertexShaderOutputStr + "." + texcoordName;
                        }
                        else
                        {
                            string texCoordPrefix = (m_textureCoordChannel == 0) ? string.Empty : (m_textureCoordChannel + 1).ToString();

                            dataCollector.AddToProperties(UniqueId, string.Format(DummyPropertyDec, texCoordPrefix) + " {}", -1);
                            dataCollector.AddToUniforms(UniqueId, string.Format(DummyUniformDec, texCoordPrefix));

                            dataCollector.AddToInput(UniqueId, "float2 " + string.Format(DummyTexCoordDef, texCoordPrefix), true);
                            dataCollector.AddToSpecialLocalVariables(UniqueId, string.Format(DummyTexCoordSurfDef, OutputId, Constants.InputVarStr, texCoordPrefix, tiling, offset));
                            m_surfaceTexcoordName = string.Format(DummyTexCoordSurfVar, OutputId);
                        }
                    }
                    else
                    {
                        dataCollector.AddToVertexLocalVariables(UniqueId, Constants.VertexShaderOutputStr + "." + texcoordName + ".xy = " + vertexUV + " * " + tiling + " + " + offset + ";");
                        m_surfaceTexcoordName = (isVertex ? Constants.VertexShaderOutputStr : Constants.InputVarStr) + "." + texcoordName;
                    }
                }

                m_texcoordId = buffer;
            }

            return(GetOutputVectorItem(0, outputId, m_surfaceTexcoordName));
        }
        public override string GenerateShaderForOutput(int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalVar)
        {
            if (dataCollector.PortCategory == MasterNodePortCategory.Tessellation)
            {
                UIUtils.ShowMessage(m_nodeAttribs.Name + " cannot be used on Master Node Tessellation port");
                return("-1");
            }

            bool isVertex = (dataCollector.PortCategory == MasterNodePortCategory.Vertex || dataCollector.PortCategory == MasterNodePortCategory.Tessellation);

            if (m_referenceArrayId > -1)
            {
                //TexturePropertyNode node = UIUtils.GetTexturePropertyNode( m_referenceArrayId );
                m_referenceNode = UIUtils.GetTexturePropertyNode(m_referenceArrayId);
                if (m_referenceNode != null)
                {
                    string propertyName = m_referenceNode.PropertyName;
                    int    coordSet     = ((m_textureCoordChannel < 0) ? 0 : m_textureCoordChannel);
                    string uvName       = string.Empty;

                    string dummyPropUV = "_tex" + (m_texcoordSize > 2 ? "" + m_texcoordSize : "") + "coord" + (coordSet > 0 ? (coordSet + 1).ToString() : "");
                    string dummyUV     = "uv" + (coordSet > 0 ? (coordSet + 1).ToString() : "") + dummyPropUV;

                    if (isVertex)
                    {
                        uvName = IOUtils.GetUVChannelName(propertyName, coordSet);
                        string vertexInput = Constants.VertexShaderInputStr + ".texcoord";
                        if (coordSet > 0)
                        {
                            vertexInput += coordSet.ToString();
                        }
                        dataCollector.AddToVertexLocalVariables(m_uniqueId, "float" + m_texcoordSize + " " + uvName + " = " + vertexInput + ";");
                        dataCollector.AddToVertexLocalVariables(m_uniqueId, uvName + ".xy = " + vertexInput + ".xy * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw;");
                    }
                    else
                    {
                        uvName = IOUtils.GetUVChannelName(propertyName, coordSet);
                        if (m_texcoordSize > 2)
                        {
                            uvName += m_texcoordSize;
                            dataCollector.UsingHigherSizeTexcoords = true;
                            dataCollector.AddToLocalVariables(m_uniqueId, "float" + m_texcoordSize + " " + uvName + " = " + Constants.InputVarStr + "." + dummyUV + ";");
                            dataCollector.AddToLocalVariables(m_uniqueId, uvName + ".xy = " + Constants.InputVarStr + "." + dummyUV + ".xy * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw;");
                        }
                        else
                        {
                            dataCollector.AddToLocalVariables(m_uniqueId, PrecisionType.Float, WirePortDataType.FLOAT2, uvName, Constants.InputVarStr + "." + dummyUV + " * " + propertyName + "_ST.xy + " + propertyName + "_ST.zw");
                        }
                    }

                    dataCollector.AddToUniforms(m_uniqueId, "uniform float4 " + propertyName + "_ST;");
                    dataCollector.AddToProperties(m_uniqueId, "[HideInInspector] " + dummyPropUV + "( \"\", 2D ) = \"white\" {}", 100);
                    dataCollector.AddToInput(m_uniqueId, "float" + m_texcoordSize + " " + dummyUV, true);

                    return(GetOutputVectorItem(0, outputId, uvName));
                }
            }

            if (m_texcoordId < 0)
            {
                if (!isVertex && dataCollector.TesselationActive)
                {
                    return(GenerateFragShaderForOutput(outputId, ref dataCollector, ignoreLocalVar));
                }

                bool tessVertexMode = isVertex && dataCollector.TesselationActive;

                m_texcoordId = dataCollector.AvailableUvIndex;
                string texcoordName = TexCoordStr + m_texcoordId;



                string uvChannel = m_textureCoordChannel == 0 ? ".xy" : m_textureCoordChannel + ".xy";

                MasterNodePortCategory portCategory = dataCollector.PortCategory;
                if (dataCollector.PortCategory != MasterNodePortCategory.Vertex && dataCollector.PortCategory != MasterNodePortCategory.Tessellation)
                {
                    dataCollector.PortCategory = MasterNodePortCategory.Vertex;
                }

                // We need to reset local variables if there are already created to force them to be created in the vertex function
                int buffer = m_texcoordId;
                UIUtils.CurrentWindow.CurrentGraph.ResetNodesLocalVariables(this);

                bool dirtySpecialVarsBefore = dataCollector.DirtySpecialLocalVariables;
                bool dirtyVertexVarsBefore  = dataCollector.DirtyVertexVariables;

                string tiling = m_inputPorts[0].GenerateShaderForOutput(ref dataCollector, WirePortDataType.FLOAT2, false, true);
                string offset = m_inputPorts[1].GenerateShaderForOutput(ref dataCollector, WirePortDataType.FLOAT2, false, true);
                dataCollector.PortCategory = portCategory;

                string vertexUV = Constants.VertexShaderInputStr + ".texcoord" + uvChannel;

                if (!tessVertexMode)
                {
                    dataCollector.AddToInput(m_uniqueId, "float" + m_texcoordSize + " " + texcoordName, true);
                }

                bool resetLocals = false;
                // new texture coordinates are calculated on the vertex shader so we need to register its local vars
                if (!dirtySpecialVarsBefore && dataCollector.DirtySpecialLocalVariables)
                {
                    dataCollector.AddVertexInstruction(UIUtils.CurrentDataCollector.SpecialLocalVariables, m_uniqueId, false);
                    UIUtils.CurrentDataCollector.ClearSpecialLocalVariables();
                    resetLocals = true;
                }

                if (!dirtyVertexVarsBefore && dataCollector.DirtyVertexVariables)
                {
                    dataCollector.AddVertexInstruction(UIUtils.CurrentDataCollector.VertexLocalVariables, m_uniqueId, false);
                    UIUtils.CurrentDataCollector.ClearVertexLocalVariables();
                    resetLocals = true;
                }

                //Reset local variables again so they wont be caught on the fragment shader
                if (resetLocals)
                {
                    UIUtils.CurrentWindow.CurrentGraph.ResetNodesLocalVariables(this);
                }

                if (tessVertexMode)
                {
                    dataCollector.AddVertexInstruction(vertexUV + " = " + vertexUV + " * " + tiling + " + " + offset, m_uniqueId);
                    m_surfaceTexcoordName = Constants.VertexShaderInputStr + "." + IOUtils.GetVertexUVChannelName(m_textureCoordChannel) + ".xy";
                }
                else
                {
                    if (dataCollector.TesselationActive)
                    {
                        if (isVertex)
                        {
                            dataCollector.AddVertexInstruction(vertexUV + " = " + vertexUV + " * " + tiling + " + " + offset, m_uniqueId);
                            m_surfaceTexcoordName = Constants.VertexShaderOutputStr + "." + texcoordName;
                        }
                        else
                        {
                            dataCollector.AddToProperties(m_uniqueId, DummyPropertyDec + " {}", -1);
                            dataCollector.AddToUniforms(m_uniqueId, DummyUniformDec);
                            string texCoordPrefix = (m_textureCoordChannel == 0) ? string.Empty : (m_textureCoordChannel + 1).ToString();
                            dataCollector.AddToInput(m_uniqueId, "float2 " + string.Format(DummyTexCoordDef, texCoordPrefix), true);
                            dataCollector.AddToSpecialLocalVariables(m_uniqueId, string.Format(DummyTexCoordSurfDef, m_uniqueId, Constants.InputVarStr, texCoordPrefix, tiling, offset));
                            m_surfaceTexcoordName = string.Format(DummyTexCoordSurfVar, m_uniqueId);
                        }
                    }
                    else
                    {
                        dataCollector.AddVertexInstruction(Constants.VertexShaderOutputStr + "." + texcoordName + ".xy = " + vertexUV + " * " + tiling + " + " + offset, m_uniqueId);
                        m_surfaceTexcoordName = (isVertex ? Constants.VertexShaderOutputStr : Constants.InputVarStr) + "." + texcoordName;
                    }
                }

                m_texcoordId = buffer;
            }

            return(GetOutputVectorItem(0, outputId, m_surfaceTexcoordName));
        }