private void JoinParameters() { var uniformsByName = Script.Nodes.Where(_ => NodeTypes.IsParameter(_.Type) || _.Type != NodeTypes.VertexData && NodeTypes.IsAttribute(_.Type)) .ToLookup(_ => _.Name); foreach (var uniformGroup in uniformsByName) { JoinUniforms(uniformGroup); } }
private bool CanBeInPixelShader(NodeHelper scriptNode) { if (NodeTypes.IsConstant(scriptNode.Type) || NodeTypes.IsParameter(scriptNode.Type) || NodeTypes.IsUniform(scriptNode.Type)) { return(true); } if (scriptNode.Type == NodeTypes.ObjectData) { return(true); } if (scriptNode.Type == NodeTypes.Special.Default) { return(true); } return(false); }
public ShaderGeneratorContext(ScriptHelper <TranslatedMaterialGraph.NodeInfo> graph, string name, Connection previewPin = null) { Name = name; Parameters = graph.Nodes.Where(_ => NodeTypes.IsParameter(_.Type)).ToList(); Samplers = graph.Nodes.Where(_ => NodeTypes.IsSampler(_.Type)).ToList(); TranslatedMaterialGraph.Preprocess(graph, previewPin); var finalColorByPass = graph.Nodes.Where(_ => NodeTypes.IsFinalColor(_.Type)).ToLookup(_ => _.Value); foreach (var pass in finalColorByPass) { var passGraph = graph.Clone(); passGraph.Nodes.RemoveWhere(_ => NodeTypes.IsFinalColor(_.Type) && _.Value != pass.Key); Passes.Add(new Pass { Key = pass.Key, Graph = TranslatedMaterialGraph.Translate(passGraph) }); } }
private void FillCollections() { Discards = new List <NodeHelper>(); RenderTargets = new List <NodeHelper>(); VertexShaderVaryings = new List <NodeHelper>(); PixelShaderVaryings = new List <NodeHelper>(); VertexShaderUniforms = new List <NodeHelper>(); PixelShaderUniforms = new List <NodeHelper>(); VertexShaderAttributes = new List <NodeHelper>(); Samplers = new List <NodeHelper>(); foreach (var node in Script.Nodes) { if (NodeTypes.IsAttribute(node.Type)) { VertexShaderAttributes.Add(node); continue; } if (NodeTypes.IsParameter(node.Type) || NodeTypes.IsUniform(node.Type)) { //if (node.Extra.UsedInPixelShader && node.Extra.UsedInVertexShader) //{ // throw new MaterialCompilationException("This node should be split during transformation", node.Id); //} if (node.Extra.RequiredInPixelShader) { PixelShaderUniforms.Add(new NodeHelper { Name = "c" + node.Name, Type = node.OutputPins.First().Type }); } else //if (node.Extra.UsedInPixelShader) { VertexShaderUniforms.Add(new NodeHelper { Name = "c" + node.Name, Type = node.OutputPins.First().Type }); } continue; } switch (node.Type) { case NodeTypes.Special.ShadowMapOutput: case NodeTypes.Special.FinalColor: case NodeTypes.Special.FragData0: case NodeTypes.Special.FragData1: case NodeTypes.Special.FragData2: case NodeTypes.Special.FragData3: RenderTargets.Add(node); break; case NodeTypes.Discard: Discards.Add(node); break; case NodeTypes.AmbientColor: AmbientColor = node; break; case NodeTypes.Opacity: Opacity = node; break; case NodeTypes.LightColor: LightColor = node; break; case NodeTypes.Special.SetVarying: VertexShaderVaryings.Add(node); break; case NodeTypes.Special.GetVarying: PixelShaderVaryings.Add(node); break; case NodeTypes.LightData: case NodeTypes.CameraData: case NodeTypes.ZoneData: case NodeTypes.ObjectData: { throw new MaterialCompilationException("This node should be split during transformation", node.Id); } //} //if (node.Extra.Attribution == NodeAttribution.PixelShader) // PixelShaderUniforms.Add(new NodeHelper // { // Name = "c" + node.OutputPins.First().Id, // Type = node.OutputPins.First().Type // }); //else // VertexShaderUniforms.Add(new NodeHelper // { // Name = "c" + node.OutputPins.First().Id, // Type = node.OutputPins.First().Type // }); //break; case NodeTypes.Sampler2D: case NodeTypes.Sampler3D: case NodeTypes.SamplerCube: Samplers.Add(node); break; } } }
public string GenerateCode(NodeHelper <TranslatedMaterialGraph.NodeInfo> node) { if (node.Type == NodeTypes.Special.Variable) { return(GenerateVarCode(node)); } if (node.Extra.Define.IsIfDef) { return(GenerateIfDef(node)); } //if (node.Type == NodeTypes.Texture2DSampler2DVec2 // || node.Type == NodeTypes.Texture2DSampler2DVec2Float // || node.Type == NodeTypes.TextureCubeSamplerCubeVec3 // || node.Type == NodeTypes.TextureCubeSamplerCubeVec3Float // ) //{ // if (node.InputPins["sampler"].Links.Count == 0) // { // return "vec4(0.0,0.0,0.0,0.0)"; // } //} var args = node.InputPins.Select(_ => GenerateCode(_)).ToList(); if (NodeTypes.IsConnectorType(node.Type)) { return(args[0]); } if (NodeTypes.IsIfDefType(node.Type)) { throw new InvalidOperationException("ifdef should be handeled at var code path"); } if (node.Type == NodeTypes.VertexData) { return("i" + node.OutputPins[0].Id); } if (NodeTypes.IsAttribute(node.Type)) { if (node.Name == "BlendIndices") { return("ivec4(i" + node.Name + ")"); } return("i" + node.Name); } if (NodeTypes.IsUniform(node.Type)) { return("c" + node.Name); } if (NodeTypes.IsParameter(node.Type)) { return("c" + node.Name); } string constType; if (NodeTypes._constants.TryGetValue(node.Type, out constType)) { return(GetConstantValue(node.Value, constType)); } switch (node.Type) { case NodeTypes.Function: return(node.Name + "(" + string.Join(",", args) + ")"); case NodeTypes.Special.Default: return(GenerateDefaultValue(node.OutputPins[0].Type)); case NodeTypes.Special.ShadowMapOutput: _writer.WriteLine(null, " #ifdef VSM_SHADOW"); _writer.WriteLine(null, " float depth = " + args[0] + ".x / " + args[0] + ".y * 0.5 + 0.5;"); _writer.WriteLine(null, " gl_FragColor = vec4(depth, depth * depth, 1.0, 1.0);"); _writer.WriteLine(null, " #else"); _writer.WriteLine(null, " gl_FragColor = vec4(1.0);"); _writer.WriteLine(null, " #endif"); return(null); case NodeTypes.Special.FinalColor: _writer.WriteLine(null, "gl_FragColor = " + args[0] + ";"); return(null); case NodeTypes.Special.FragData0: _writer.WriteLine(null, "gl_FragData[0] = " + args[0] + ";"); return(null); case NodeTypes.Special.FragData1: _writer.WriteLine(null, "gl_FragData[1] = " + args[0] + ";"); return(null); case NodeTypes.Special.FragData2: _writer.WriteLine(null, "gl_FragData[2] = " + args[0] + ";"); return(null); case NodeTypes.Special.FragData3: _writer.WriteLine(null, "gl_FragData[3] = " + args[0] + ";"); return(null); case NodeTypes.FragCoord: return("gl_FragCoord"); case NodeTypes.FrontFacing: return("gl_FrontFacing"); case NodeTypes.LightColor: case NodeTypes.Opacity: case NodeTypes.AmbientColor: case NodeTypes.RefractionColor: case NodeTypes.PerPixelFloat: case NodeTypes.PerPixelVec2: case NodeTypes.PerPixelVec3: case NodeTypes.PerPixelVec4: return(args[0]); case NodeTypes.ObjectData: case NodeTypes.LightData: case NodeTypes.CameraData: case NodeTypes.ZoneData: throw new InvalidOperationException( "This code shouldn't be executed. All uniforms must be split into individual nodes on preprocessing."); case NodeTypes.Special.SetVarying: { var arg = args[0]; var actualType = GetType(node.InputPins[0].Type); var varyingType = GetVaryingType(node.InputPins[0].Type); if (actualType != varyingType) { arg = varyingType + "(" + arg + ")"; } var connectedNode = node.InputPins[0].ConnectedPins.FirstOrDefault()?.Node; if (connectedNode != null && addComments) { _writer.WriteLine(null, "// based on node " + connectedNode.Name + " " + connectedNode.Value + " (type:" + connectedNode.Type + ", id:" + connectedNode.Id + "), cost estimation: " + connectedNode.Extra.EstimatedCost); } _writer.WriteLine(node.Extra.Define.Expression, "v" + node.Value + " = " + arg + ";"); } return(null); case NodeTypes.Discard: _writer.WriteLine(null, "if (" + args[0] + ") discard;"); return(null); case NodeTypes.Special.GetVarying: { var arg = "v" + node.Value; var actualType = GetType(node.OutputPins[0].Type); var varyingType = GetVaryingType(node.OutputPins[0].Type); if (actualType != varyingType) { arg = actualType + "(" + arg + ")"; } return(arg); } case NodeTypes.Sampler2D: case NodeTypes.Sampler3D: case NodeTypes.SamplerCube: return(GetSamplerName(node)); //_writer.WriteLine("uniform "+node.OutputPins.First().Type+" s" + GetSamplerName(node) + ";"); case NodeTypes.BreakVec4ToVec3AndFloat: case NodeTypes.BreakVec3ToVec2AndFloat: case NodeTypes.BreakVec4ToVec2AndVec2: case NodeTypes.BreakVec4ToVec2AndFloats: case NodeTypes.BreakVec2: case NodeTypes.BreakVec3: case NodeTypes.BreakVec4: if (node.OutputPins.Count != 1) { throw new InvalidOperationException(node + " expected to have a single output."); } return(args[0] + "." + node.OutputPins[0].Id.ToLower()); case NodeTypes.MultiplyFloatFloat: case NodeTypes.MultiplyVec2Float: case NodeTypes.MultiplyVec3Float: case NodeTypes.MultiplyVec4Float: case NodeTypes.MultiplyVec2Vec2: case NodeTypes.MultiplyVec3Vec3: case NodeTypes.MultiplyVec4Vec4: case NodeTypes.MultiplyVec4Mat4: case NodeTypes.MultiplyVec3Mat3: case NodeTypes.MultiplyMat3Vec3: case NodeTypes.MultiplyMat4x3Float: case NodeTypes.MultiplyMat4Float: return(GenBinaryOperator("*", args)); case NodeTypes.MultiplyVec4Mat4x3: return("(" + GenBinaryOperator("*", args) + ").xyz"); //case NodeTypes.MultiplyVec3Mat4: //case NodeTypes.MultiplyVec3Mat4x3: // return GenBinaryOperator("*", new []{ "vec4("+args[0]+", 1.0)", args[1] }); case NodeTypes.AddFloatFloat: case NodeTypes.AddVec2Vec2: case NodeTypes.AddVec3Vec3: case NodeTypes.AddVec4Vec4: case NodeTypes.AddMat4Mat4: case NodeTypes.AddMat4x3Mat4x3: return(GenBinaryOperator("+", args)); case NodeTypes.SubtractFloatFloat: case NodeTypes.SubtractVec2Vec2: case NodeTypes.SubtractVec3Vec3: case NodeTypes.SubtractVec4Vec4: return(GenBinaryOperator("-", args)); case NodeTypes.MinusFloat: case NodeTypes.MinusVec2: case NodeTypes.MinusVec3: case NodeTypes.MinusVec4: return(GenUnaryOperator("-", args)); case NodeTypes.SaturateFloat: return("clamp(" + args[0] + ", 0.0, 1.0)"); case NodeTypes.SaturateVec2: return("clamp(" + args[0] + ", vec2(0.0, 0.0), vec2(1.0, 1.0))"); case NodeTypes.SaturateVec3: return("clamp(" + args[0] + ", vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0))"); case NodeTypes.SaturateVec4: return("clamp(" + args[0] + ", vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0))"); case NodeTypes.DivideFloatFloat: case NodeTypes.DivideVec2Float: case NodeTypes.DivideVec3Float: case NodeTypes.DivideVec4Float: case NodeTypes.DivideVec2Vec2: case NodeTypes.DivideVec3Vec3: case NodeTypes.DivideVec4Vec4: return(GenBinaryOperator("/", args)); case NodeTypes.TernaryFloat: case NodeTypes.TernaryVec2: case NodeTypes.TernaryVec3: case NodeTypes.TernaryVec4: return("((" + args[0] + ")?(" + args[1] + "):(" + args[2] + "))"); case NodeTypes.MakeVec4FromVec3: return(node.OutputPins[0].Type + "(" + string.Join(", ", args) + ", 1.0)"); case NodeTypes.MakeMat4x3FromVec4Vec4Vec4: return("mat4(" + string.Join(", ", args) + ", vec4(0.0, 0.0, 0.0, 1.0))"); case NodeTypes.MakeVec4FromVec3AndFloat: case NodeTypes.MakeVec4FromVec2AndVec2: case NodeTypes.MakeVec3FromVec2AndFloat: case NodeTypes.MakeVec2: case NodeTypes.MakeVec3: case NodeTypes.MakeVec4: case NodeTypes.MakeMat3FromVec3Vec3Vec3: return(node.OutputPins[0].Type + "(" + string.Join(", ", args) + ")"); case NodeTypes.MakeMat3FromMat4: case NodeTypes.MakeMat3FromMat4x3: return("GetNormalMatrix(" + string.Join(", ", args) + ")"); case NodeTypes.SampleVSMShadow: return("texture2D(" + string.Join(", ", args) + ").rg"); case NodeTypes.SkinMatrixIndex: return("mat4(" + args[0] + "[" + args[1] + "*3], " + args[0] + "[" + args[1] + "*3+1]," + args[0] + "[" + args[1] + "*3+2], vec4(0.0, 0.0, 0.0, 1.0))"); case NodeTypes.LightMatricesIndex: case NodeTypes.VertexLightsIndex: return(args[0] + "[" + args[1] + "]"); case NodeTypes.PositionOutput: return(args[0]); case NodeTypes.LessThanFloatFloat: return(GenBinaryOperator("<", args)); case NodeTypes.NotBool: return("!(" + args[0] + ")"); case NodeTypes.EqualFloatFloat: return(GenBinaryOperator("==", args)); case NodeTypes.NotEqualFloatFloat: return(GenBinaryOperator("!=", args)); case NodeTypes.GreaterThanFloatFloat: return(GenBinaryOperator(">", args)); case NodeTypes.LessThanEqualFloatFloat: return(GenBinaryOperator("<=", args)); case NodeTypes.GreaterThanEqualFloatFloat: return(GenBinaryOperator(">=", args)); case NodeTypes.AndAlso: return(GenBinaryOperator("&&", args)); case NodeTypes.OrElse: return(GenBinaryOperator("||", args)); default: var bracketIndex = node.Type.IndexOf("("); if (bracketIndex > 0) { return(node.Type.Substring(0, bracketIndex) + "(" + string.Join(", ", args) + ")"); } throw new MaterialCompilationException("Node " + node.Type + " isn't implemented yet.", node.Id); } }
private void FillCollections() { Discards = new List <NodeHelper>(); RenderTargets = new List <NodeHelper>(); VertexShaderVaryings = new List <NodeHelper>(); PixelShaderVaryings = new List <NodeHelper>(); VertexShaderUniforms = new List <NodeHelper>(); PixelShaderUniforms = new List <NodeHelper>(); VertexShaderAttributes = new List <NodeHelper>(); Samplers = new List <NodeHelper>(); foreach (var node in Script.Nodes) { if (NodeTypes.IsAttribute(node.Type)) { VertexShaderAttributes.Add(node); continue; } if (NodeTypes.IsParameter(node.Type) || NodeTypes.IsUniform(node.Type)) { if (node.Extra.Attribution == NodeAttribution.PixelShader) { PixelShaderUniforms.Add(new NodeHelper { Name = "c" + node.Name, Type = node.OutputPins.First().Type }); } else { VertexShaderUniforms.Add(new NodeHelper { Name = "c" + node.Name, Type = node.OutputPins.First().Type }); } continue; } switch (node.Type) { case NodeTypes.Special.ShadowMapOutput: case NodeTypes.Special.FinalColor: case NodeTypes.Special.FinalData0: case NodeTypes.Special.FinalData1: case NodeTypes.Special.FinalData2: case NodeTypes.Special.FinalData3: RenderTargets.Add(node); break; case NodeTypes.Discard: Discards.Add(node); break; case NodeTypes.AmbientColor: AmbientColor = node; break; case NodeTypes.Opacity: Opacity = node; break; case NodeTypes.LightColor: LightColor = node; break; case NodeTypes.Special.SetVarying: VertexShaderVaryings.Add(node); break; case NodeTypes.Special.GetVarying: PixelShaderVaryings.Add(node); break; case NodeTypes.LightData: case NodeTypes.CameraData: case NodeTypes.ZoneData: case NodeTypes.ObjectData: if (node.Extra.Attribution == NodeAttribution.PixelShader) { PixelShaderUniforms.Add(new NodeHelper { Name = "c" + node.OutputPins.First().Id, Type = node.OutputPins.First().Type }); } else { VertexShaderUniforms.Add(new NodeHelper { Name = "c" + node.OutputPins.First().Id, Type = node.OutputPins.First().Type }); } break; case NodeTypes.Sampler2D: case NodeTypes.Sampler3D: case NodeTypes.SamplerCube: Samplers.Add(node); break; } } }