public override string GenerateShaderForOutput(int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar)
        {
            if (!m_outputPorts[0].IsLocalValue(dataCollector.PortCategory))
            {
                base.GenerateShaderForOutput(outputId, ref dataCollector, ignoreLocalvar);
                m_inputPorts[0].GeneratePortInstructions(ref dataCollector);
                string texTransform = string.Empty;

                if (m_inputPorts[0].IsConnected)
                {
                    texTransform = m_inputPorts[0].GeneratePortInstructions(ref dataCollector) + "_ST";
                }
                else if (m_referenceNode != null)
                {
                    m_referenceNode.BaseGenerateShaderForOutput(outputId, ref dataCollector, ignoreLocalvar);
                    texTransform = m_referenceNode.PropertyName + "_ST";
                }
                else
                {
                    texTransform = "_ST";
                    UIUtils.ShowMessage(UniqueId, "Please specify a texture sample on the Texture Transform Size node", MessageSeverity.Warning);
                }

                //bool excludeUniformKeyword = UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader || UIUtils.CurrentWindow.OutsideGraph.IsSRP;
                //string uniformRegister = UIUtils.GenerateUniformName( excludeUniformKeyword, WirePortDataType.FLOAT4, texTransform );
                //dataCollector.AddToUniforms( UniqueId, uniformRegister, true );
                if (m_texCoordsHelper == null)
                {
                    m_texCoordsHelper = CreateInstance <Vector4Node>();
                    m_texCoordsHelper.ContainerGraph = ContainerGraph;
                    m_texCoordsHelper.SetBaseUniqueId(UniqueId, true);
                    m_texCoordsHelper.RegisterPropertyOnInstancing = false;
                    m_texCoordsHelper.AddGlobalToSRPBatcher        = true;
                }

                if (m_instanced)
                {
                    m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty;
                }
                else
                {
                    m_texCoordsHelper.CurrentParameterType = PropertyType.Global;
                }
                m_texCoordsHelper.ResetOutputLocals();
                m_texCoordsHelper.SetRawPropertyName(texTransform);
                texTransform = m_texCoordsHelper.GenerateShaderForOutput(0, ref dataCollector, false);

                m_outputPorts[0].SetLocalValue(texTransform, dataCollector.PortCategory);
            }

            switch (outputId)
            {
            case 0: return(m_outputPorts[0].LocalValue(dataCollector.PortCategory) + ".xy");

            case 1: return(m_outputPorts[0].LocalValue(dataCollector.PortCategory) + ".zw");
            }

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

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

            string tiling = string.Empty;
            string offset = string.Empty;

            string portProperty = string.Empty;

            if (m_texPort.IsConnected)
            {
                portProperty = m_texPort.GeneratePortInstructions(ref dataCollector);
            }
            else 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(dataCollector.PortCategory))
                {
                    return(GetOutputVectorItem(0, outputId, m_outputPorts[0].LocalValue(dataCollector.PortCategory)));
                }

                string uvName   = string.Empty;
                string result   = string.Empty;
                string indexStr = m_textureCoordChannel > 0 ? (m_textureCoordChannel + 1).ToString() : "";
                string sizeDif  = string.Empty;
                if (m_texcoordSize == 3)
                {
                    sizeDif = "3";
                }
                else if (m_texcoordSize == 4)
                {
                    sizeDif = "4";
                }

                if (dataCollector.TemplateDataCollectorInstance.GetCustomInterpolatedData(TemplateHelperFunctions.IntToUVChannelInfo[m_textureCoordChannel], m_outputPorts[0].DataType, PrecisionType.Float, ref result, false, dataCollector.PortCategory))
                {
                    uvName = result;
                }
                else if (dataCollector.TemplateDataCollectorInstance.HasUV(m_textureCoordChannel))
                {
                    uvName = dataCollector.TemplateDataCollectorInstance.GetUVName(m_textureCoordChannel, m_outputPorts[0].DataType);
                }
                else
                {
                    uvName = dataCollector.TemplateDataCollectorInstance.RegisterUV(m_textureCoordChannel, m_outputPorts[0].DataType);
                }
                string currPropertyName = GetValidPropertyName();
                if (!string.IsNullOrEmpty(portProperty) && portProperty != "0.0")
                {
                    currPropertyName = portProperty;
                }
                if (!string.IsNullOrEmpty(currPropertyName))
                {
                    string finalTexCoordName      = "uv" + indexStr + (m_texcoordSize > 2 ? "s" + sizeDif : "") + currPropertyName;
                    string dummyPropertyTexcoords = currPropertyName + "_ST";

                    if (m_texCoordsHelper == null)
                    {
                        m_texCoordsHelper = CreateInstance <Vector4Node>();
                        m_texCoordsHelper.ContainerGraph = ContainerGraph;
                        m_texCoordsHelper.SetBaseUniqueId(UniqueId, true);
                        m_texCoordsHelper.RegisterPropertyOnInstancing = false;
                        m_texCoordsHelper.AddGlobalToSRPBatcher        = true;
                    }

                    if (UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader)
                    {
                        m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty;
                    }
                    else
                    {
                        m_texCoordsHelper.CurrentParameterType = PropertyType.Global;
                    }
                    m_texCoordsHelper.ResetOutputLocals();
                    m_texCoordsHelper.SetRawPropertyName(dummyPropertyTexcoords);
                    dummyPropertyTexcoords = m_texCoordsHelper.GenerateShaderForOutput(0, ref dataCollector, false);

                    if (m_texcoordSize > 2)
                    {
                        dataCollector.AddLocalVariable(UniqueId, 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, dataCollector.PortCategory);
                    }
                    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 = "texCoord" + OutputId;
                    tiling = m_tilingPort.GeneratePortInstructions(ref dataCollector);
                    offset = m_offsetPort.GeneratePortInstructions(ref dataCollector);

                    if (m_texcoordSize > 2)
                    {
                        dataCollector.AddLocalVariable(UniqueId, 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, dataCollector.PortCategory);
                    }
                    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(dataCollector.PortCategory)));
            }

            //SURFACE
            string propertyName = GetValidPropertyName();

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

            if (m_outputPorts[0].IsLocalValue(dataCollector.PortCategory))
            {
                return(GetOutputVectorItem(0, outputId, m_outputPorts[0].LocalValue(dataCollector.PortCategory)));
            }

            if (!m_tilingPort.IsConnected && m_tilingPort.Vector2InternalData == Vector2.one)
            {
                tiling = null;
            }
            else
            {
                tiling = m_tilingPort.GeneratePortInstructions(ref dataCollector);
            }

            if (!m_offsetPort.IsConnected && m_offsetPort.Vector2InternalData == Vector2.zero)
            {
                offset = null;
            }
            else
            {
                offset = m_offsetPort.GeneratePortInstructions(ref dataCollector);
            }

            if (!string.IsNullOrEmpty(propertyName) /*m_referenceArrayId > -1*/)
            {
                m_surfaceTexcoordName = GeneratorUtils.GenerateAutoUVs(ref dataCollector, UniqueId, m_textureCoordChannel, propertyName, m_outputPorts[0].DataType, tiling, offset, OutputId);
            }
            else
            {
                m_surfaceTexcoordName = GeneratorUtils.GenerateAutoUVs(ref dataCollector, UniqueId, m_textureCoordChannel, null, m_outputPorts[0].DataType, tiling, offset, OutputId);
            }

            m_outputPorts[0].SetLocalValue(m_surfaceTexcoordName, dataCollector.PortCategory);
            return(GetOutputVectorItem(0, outputId, m_outputPorts[0].LocalValue(dataCollector.PortCategory)));
        }
        public override string GenerateShaderForOutput(int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar)
        {
            if (!m_texPort.IsConnected)
            {
                UIUtils.ShowMessage(UniqueId, "Parallax Occlusion Mapping node only works if a Texture Object is connected to its Tex (R) port");
                return("0");
            }
            base.GenerateShaderForOutput(outputId, ref dataCollector, ignoreLocalvar);
            WirePortDataType texType = (m_pomTexType == POMTexTypes.Texture3D)?WirePortDataType.SAMPLER3D: WirePortDataType.SAMPLER2D;

            GeneratePOMfunction();
            string arrayIndex = m_arrayIndexPort.Visible?m_arrayIndexPort.GeneratePortInstructions(ref dataCollector):"0";
            string textcoords = m_uvPort.GeneratePortInstructions(ref dataCollector);

            if (m_pomTexType == POMTexTypes.Texture3D)
            {
                string texName = "pomTexCoord" + OutputId;
                dataCollector.AddLocalVariable(UniqueId, CurrentPrecisionType, WirePortDataType.FLOAT3, texName, string.Format("float3({0},{1})", textcoords, arrayIndex));
                textcoords = texName;
            }

            string texture = m_texPort.GenerateShaderForOutput(ref dataCollector, texType, false, true);
            string scale   = m_defaultScale.ToString();

            if (m_scalePort.IsConnected)
            {
                scale = m_scalePort.GeneratePortInstructions(ref dataCollector);
            }

            string viewDirTan = "";

            if (!m_viewdirTanPort.IsConnected)
            {
                if (!dataCollector.DirtyNormal)
                {
                    dataCollector.ForceNormal = true;
                }


                if (dataCollector.IsTemplate)
                {
                    viewDirTan = dataCollector.TemplateDataCollectorInstance.GetTangentViewDir(CurrentPrecisionType);
                }
                else
                {
                    viewDirTan = GeneratorUtils.GenerateViewDirection(ref dataCollector, UniqueId, ViewSpace.Tangent);
                    //dataCollector.AddToInput( UniqueId, SurfaceInputs.VIEW_DIR, m_currentPrecisionType );
                    //viewDirTan = Constants.InputVarStr + "." + UIUtils.GetInputValueFromType( SurfaceInputs.VIEW_DIR );
                }
            }
            else
            {
                viewDirTan = m_viewdirTanPort.GeneratePortInstructions(ref dataCollector);
            }

            //generate world normal
            string normalWorld = string.Empty;

            if (dataCollector.IsTemplate)
            {
                normalWorld = dataCollector.TemplateDataCollectorInstance.GetWorldNormal(CurrentPrecisionType);
            }
            else
            {
                dataCollector.AddToInput(UniqueId, SurfaceInputs.WORLD_NORMAL, CurrentPrecisionType);
                dataCollector.AddToInput(UniqueId, SurfaceInputs.INTERNALDATA, addSemiColon: false);
                normalWorld = GeneratorUtils.GenerateWorldNormal(ref dataCollector, UniqueId);
            }

            //string normalWorld = "WorldNormalVector( " + Constants.InputVarStr + ", float3( 0, 0, 1 ) )";

            //generate viewDir in world space

            //string worldPos = string.Empty;
            //if( dataCollector.IsTemplate )
            //{
            //	worldPos = dataCollector.TemplateDataCollectorInstance.GetWorldPos();
            //}
            //else
            //{
            //	dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS );
            //	worldPos = Constants.InputVarStr + ".worldPos";
            //}

            //if( !dataCollector.IsTemplate )
            //	dataCollector.AddToInput( UniqueId, SurfaceInputs.WORLD_POS );

            string worldViewDir = GeneratorUtils.GenerateViewDirection(ref dataCollector, UniqueId, ViewSpace.World);
            //dataCollector.AddToLocalVariables( UniqueId, m_currentPrecisionType, WirePortDataType.FLOAT3, WorldDirVarStr, TemplateHelperFunctions.WorldSpaceViewDir( dataCollector, worldPos, true ) );
            string dx = "ddx(" + textcoords + ")";
            string dy = "ddy(" + textcoords + ")";

            string refPlane = m_defaultRefPlane.ToString();

            if (m_refPlanePort.IsConnected)
            {
                refPlane = m_refPlanePort.GeneratePortInstructions(ref dataCollector);
            }


            string curvature = "float2(" + m_CurvatureVector.x + "," + m_CurvatureVector.y + ")";

            if (m_useCurvature)
            {
                dataCollector.AddToProperties(UniqueId, "[Header(Parallax Occlusion Mapping)]", 300);
                dataCollector.AddToProperties(UniqueId, "_CurvFix(\"Curvature Bias\", Range( 0 , 1)) = 1", 301);
                dataCollector.AddToUniforms(UniqueId, "uniform float _CurvFix;");

                if (m_curvaturePort.IsConnected)
                {
                    curvature = m_curvaturePort.GeneratePortInstructions(ref dataCollector);
                }
            }


            string localVarName = "OffsetPOM" + OutputId;
            string textCoordsST = string.Empty;

            //string textureSTType = dataCollector.IsSRP ? "float4 " : "uniform float4 ";
            //dataCollector.AddToUniforms( UniqueId, textureSTType + texture +"_ST;");
            if (m_texCoordsHelper == null)
            {
                m_texCoordsHelper = CreateInstance <Vector4Node>();
                m_texCoordsHelper.ContainerGraph = ContainerGraph;
                m_texCoordsHelper.SetBaseUniqueId(UniqueId, true);
                m_texCoordsHelper.RegisterPropertyOnInstancing = false;
                m_texCoordsHelper.AddGlobalToSRPBatcher        = true;
            }

            if (UIUtils.CurrentWindow.OutsideGraph.IsInstancedShader)
            {
                m_texCoordsHelper.CurrentParameterType = PropertyType.InstancedProperty;
            }
            else
            {
                m_texCoordsHelper.CurrentParameterType = PropertyType.Global;
            }
            m_texCoordsHelper.ResetOutputLocals();
            m_texCoordsHelper.SetRawPropertyName(texture + "_ST");
            textCoordsST = m_texCoordsHelper.GenerateShaderForOutput(0, ref dataCollector, false);
            //////

            if (m_pomTexType == POMTexTypes.TextureArray)
            {
                dataCollector.UsingArrayDerivatives = true;
            }
            string textureArgs = string.Empty;

            if (m_pomTexType == POMTexTypes.TextureArray)
            {
                if (UIUtils.CurrentWindow.OutsideGraph.IsSRP)
                {
                    textureArgs = "TEXTURE2D_ARRAY_PARAM(" + texture + " , " + "sampler##" + texture + ")";
                }
                else
                {
                    textureArgs = "UNITY_PASS_TEX2DARRAY(" + texture + ")";
                }
            }
            else
            {
                bool sampleThroughMacros = UIUtils.CurrentWindow.OutsideGraph.SamplingThroughMacros;
                if (sampleThroughMacros)
                {
                    dataCollector.AddToUniforms(UniqueId, string.Format(Constants.SamplerDeclarationSRPMacros[TextureType.Texture2D], texture));
                    textureArgs = string.Format("{0},sampler{0}", texture);
                }
                else
                {
                    textureArgs = texture;
                }
            }
            //string functionResult = dataCollector.AddFunctions( m_functionHeader, m_functionBody, ( (m_pomTexType == POMTexTypes.TextureArray) ? "UNITY_PASS_TEX2DARRAY(" + texture + ")": texture), textcoords, dx, dy, normalWorld, worldViewDir, viewDirTan, m_minSamples, m_maxSamples, scale, refPlane, texture+"_ST.xy", curvature, arrayIndex );
            string functionResult = dataCollector.AddFunctions(m_functionHeader, m_functionBody, textureArgs, textcoords, dx, dy, normalWorld, worldViewDir, viewDirTan, m_inlineMinSamples.GetValueOrProperty(false), m_inlineMinSamples.GetValueOrProperty(false), scale, refPlane, textCoordsST + ".xy", curvature, arrayIndex);

            dataCollector.AddLocalVariable(UniqueId, CurrentPrecisionType, m_pomUVPort.DataType, localVarName, functionResult);

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