示例#1
0
 public void WritePerMaterialCBuffer(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
     if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
     {
         sb.AppendLine(terrainBlendCBuffer.text);
     }
 }
        public override MicroSplatShaderGUI.MicroSplatCompiler.AuxShader GetAuxShader()
        {
            var aux = new MicroSplatShaderGUI.MicroSplatCompiler.AuxShader("_TERRAINBLENDING", "_TerrainObjectBlend");

            aux.customEditor = "MicroSplatBlendableMaterialEditor";
            return(aux);
        }
 public void WriteProperties(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
     sb.AppendLine(properties.text);
 }
 public void WriteShaderFooter(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader, string baseName)
 {
     sb.AppendLine("      }");
     if (auxShader != null && !string.IsNullOrEmpty(auxShader.customEditor))
     {
         sb.AppendLine("      CustomEditor \"" + auxShader.customEditor + "\"");
     }
     else if (auxShader != null)
     {
     }
     else if (baseName != null)
     {
         if (features.Contains("_MICROTERRAIN"))
         {
             sb.AppendLine("   Dependency \"BaseMapShader\" = \"" + baseName + "\"");
         }
         sb.AppendLine("   CustomEditor \"MicroSplatShaderGUI\"");
     }
     sb.AppendLine("   Fallback \"Nature/Terrain/Diffuse\"");
     sb.Append("}");
 }
 public void WritePerMaterialCBuffer(string[] functions, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
        public StringBuilder WriteShader(string[] features,
                                         MicroSplatShaderGUI.MicroSplatCompiler compiler,
                                         MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader,
                                         string name,
                                         string baseName)
        {
            StringBuilder defines = new StringBuilder();
            var           blocks  = gen.GetShaderBlocks(features, compiler, auxShader);

            var shader = BuildTemplate(blocks, baseName);

            defines.AppendLine(blocks.defines);
            defines.AppendLine("\n   #define _STANDARD 1");


            string shaderTarget = "3.0";

            if (features.Contains("_TESSDISTANCE") || features.Contains("_FORCEMODEL46"))
            {
                shaderTarget = "4.6";
            }
            else if (features.Contains("_FORCEMODEL50"))
            {
                shaderTarget = "5.0";
            }

            if (features.Contains("_TESSDISTANCE"))
            {
                defines.AppendLine("\n      #define _TESSELLATION_ON 1");
                shader = shader.Replace("%TESSELLATION%", templateTess.text);
                shader = shader.Replace("%PRAGMAS%", "   #pragma hull Hull\n   #pragma domain Domain\n   #pragma vertex TessVert\n   #pragma fragment Frag\n   #pragma require tesshw\n");
            }
            else
            {
                shader = shader.Replace("%PRAGMAS%", "   #pragma vertex Vert\n   #pragma fragment Frag");
                shader = shader.Replace("%TESSELLATION%", "");
            }



            shader = shader.Replace("%SHADERTARGET%", shaderTarget);
            if (features.Contains("_USESPECULARWORKFLOW"))
            {
                defines.AppendLine("\n#define _USESPECULAR 1");
                defines.AppendLine("#define _MATERIAL_FEATURE_SPECULAR_COLOR 1");
            }

            defines.AppendLine();
            defines.AppendLine(templateCommonHLSL.text);

            string shaderDesk = templateShaderDesc.text;

            shaderDesk += templateChain.text;
            shader      = shader.Replace("%SHADERDESC%", shaderDesk);
            shader      = shader.Replace("%SHADERNAME%", name);
            shader      = shader.Replace("%PROPERTIES%", blocks.properties);
            shader      = shader.Replace("%CODE%", blocks.code);
            shader      = shader.Replace("%DEFINES%", defines.ToString());
            shader      = shader.Replace("%CBUFFER%", blocks.cbuffer);
            string codeNoComments = blocks.code.StripComments();

            shader = Strip(codeNoComments, shader);

            return(shader);
        }
示例#7
0
        public void WritePassHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
        {
            sb.AppendLine("      #pragma exclude_renderers d3d9");

            sb.AppendLine("      #include \"UnityCG.cginc\"");
            sb.AppendLine("      #include \"AutoLight.cginc\"");
            sb.AppendLine("      #include \"Lighting.cginc\"");
            if (features.Contains <string>("_BDRFNOSPECMIN"))
            {
                sb.AppendLine("      #include \"Assets/MicroSplat/Core/Scripts/MicroSplatPBSLighting.cginc\"");
            }
            else
            {
                sb.AppendLine("      #include \"UnityPBSLighting.cginc\"");
            }


            sb.AppendLine("      #include \"UnityStandardBRDF.cginc\"");
            sb.AppendLine();

            string pragma = "";

            if (auxShader != null && auxShader.trigger == "_MESHOVERLAYSPLATS")
            {
                pragma = declareMeshBlend;
            }
            else if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                pragma = declareBlend;
            }
            else if (!features.Contains <string>("_TESSDISTANCE"))
            {
                if (MicroSplatShaderGUI.MicroSplatCompiler.HasDebugFeature(features))
                {
                    pragma = declareTerrainDebug;
                    if (features.Contains("_ALPHAHOLE") || features.Contains("_ALPHABELOWHEIGHT"))
                    {
                        // generate a shadow pass so we clip that too..
                        pragma += (" addshadow");
                    }
                }
                else
                {
                    pragma = declareTerrain;
                }
            }
            else
            {
                pragma = declareTerrainTess;
            }

            if (!MicroSplatShaderGUI.MicroSplatCompiler.HasDebugFeature(features) && features.Contains("_BDRFLAMBERT"))
            {
                pragma = pragma.Replace("Standard", "Lambert");
            }
            else if (features.Contains("_USESPECULARWORKFLOW") || features.Contains("_SPECULARFROMMETALLIC"))
            {
                pragma = pragma.Replace("Standard", "StandardSpecular");
            }

            sb.Append(pragma);

            if (features.Contains <string>("_BDRF1") || features.Contains <string>("_BDRF2") || features.Contains <string>("_BDRF3"))
            {
                sb.Append(" exclude_path:deferred");
            }

            // don't remove
            sb.AppendLine();
            sb.AppendLine();
            sb.AppendLine();
            // for 2018..
#if UNITY_2018_3_OR_NEWER
            sb.AppendLine("     #pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap forwardadd");
#endif

            sb.AppendLine("      #pragma target " + compiler.GetShaderModel(features));
            // 2019.3 holes
            sb.AppendLine("      #pragma multi_compile_local __ _ALPHATEST_ON");
        }
 public void WriteVertexFunction(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
        public void WriteShaderHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
        {
            sb.AppendLine("   SubShader {");


            sb.Append("      Tags{\"RenderPipeline\"=\"HDRenderPipeline\" \"RenderType\" = \"HDLitShader\" \"Queue\" = \"Geometry+100\" ");


            if (features.Contains("_MAX4TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"4\"");
            }
            else if (features.Contains("_MAX8TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"8\"");
            }
            else if (features.Contains("_MAX12TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"12\"");
            }
            else if (features.Contains("_MAX20TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"20\"");
            }
            else if (features.Contains("_MAX24TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"24\"");
            }
            else if (features.Contains("_MAX28TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"28\"");
            }
            else if (features.Contains("_MAX32TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"32\"");
            }
            else
            {
                sb.Append("\"SplatCount\" = \"16\"");
            }
            sb.AppendLine("}");
        }
示例#10
0
        public void WriteShaderHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
        {
            sb.AppendLine();
            sb.AppendLine("   CGINCLUDE");

            if (!features.Contains <string>("_DEBUG_USE_TOPOLOGY") && (features.Contains <string>("_BDRF1") || features.Contains <string>("_BDRF2") || features.Contains <string>("_BDRF3")))
            {
                if (features.Contains <string>("_BDRF1"))
                {
                    sb.AppendLine("      #define UNITY_BRDF_PBS BRDF1_Unity_PBS");
                }
                else if (features.Contains <string>("_BDRF2"))
                {
                    sb.AppendLine("      #define UNITY_BRDF_PBS BRDF2_Unity_PBS");
                }
                else if (features.Contains <string>("_BDRF3"))
                {
                    sb.AppendLine("      #define UNITY_BRDF_PBS BRDF3_Unity_PBS");
                }
            }
            sb.AppendLine("   ENDCG");
            sb.AppendLine();

            sb.AppendLine("   SubShader {");

            sb.Append("      Tags{ \"RenderType\" = \"Opaque\"  \"Queue\" = \"Geometry+100\" ");
            // on 2018+, this removes the multipass..
            if (features.Contains("_MAX4TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"4\"");
            }
            else if (features.Contains("_MAX8TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"8\"");
            }
            else if (features.Contains("_MAX12TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"12\"");
            }
            else if (features.Contains("_MAX20TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"20\"");
            }
            else if (features.Contains("_MAX24TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"24\"");
            }
            else if (features.Contains("_MAX28TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"28\"");
            }
            else if (features.Contains("_MAX32TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"32\"");
            }
            else
            {
                sb.Append("\"SplatCount\" = \"16\"");
            }
            sb.AppendLine("}");
            sb.AppendLine("      Cull Back");
            sb.AppendLine("      ZTest LEqual");
            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                sb.AppendLine("      BLEND ONE ONE");
            }

            sb.AppendLine("      UsePass \"Hidden/Nature/Terrain/Utilities/PICKING\"");
            sb.AppendLine("      UsePass \"Hidden/Nature/Terrain/Utilities/SELECTION\"");

            sb.AppendLine("      CGPROGRAM");
        }
示例#11
0
 public void WriteProperties(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
示例#12
0
 public void WriteTerrainBody(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
     sb.AppendLine(terrainBody.text);
 }
示例#13
0
 public void WriteSharedCode(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
     sb.AppendLine(sharedInc.text);
 }
示例#14
0
 public void PostProcessShader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
示例#15
0
        public void WriteFragmentFunction(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
        {
            sb.AppendLine(fragmentFunc.text);
            if (auxShader != null)
            {
                if (auxShader.trigger == "_MESHOVERLAYSPLATS" && meshBlendBody != null)
                {
                    sb.AppendLine(meshBlendBody.text);
                }
                else if (auxShader.trigger == "_TERRAINBLENDING" && terrainBlendBody != null)
                {
                    sb.AppendLine(terrainBlendBody.text);
                }
            }

            sb.AppendLine("ENDCG\n\n   }");
        }
示例#16
0
        public void PostProcessShader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
        {
            StringBuilder temp = new StringBuilder();

            compiler.WriteFeatures(features, temp);
            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                temp.AppendLine("      #define _SRPTERRAINBLEND 1");
            }

            StringBuilder cbuffer = new StringBuilder();

            compiler.WritePerMaterialCBuffer(features, cbuffer);
            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                cbuffer.AppendLine(terrainBlendCBuffer.text);
            }

            sb = sb.Replace("//MS_DEFINES", temp.ToString());

            sb = sb.Replace("//MS_ADAPTER", adapter.ToString());
            sb = sb.Replace("//MS_SHARED_INC", sharedInc.text);
            sb = sb.Replace("//MS_SHARED_HD", sharedHD.text);
            sb = sb.Replace("//MS_TERRAIN_BODY", terrainBody.text);
            sb = sb.Replace("//MS_VERTEXMOD", vertex.text);
            sb = sb.Replace("//MS_MAINFUNC", mainFunc.text);
            sb = sb.Replace("//MS_CBUFFER", cbuffer.ToString());
            sb = sb.Replace("//MS_PASS_DEPTHONLY", vertMesh.text + "\n" + pass_depthonly.text);
            sb = sb.Replace("//MS_PASS_GBUFFER", vertMesh.text + "\n" + pass_gbuffer.text);
            sb = sb.Replace("//MS_PASS_FORWARD", vertMesh.text + "\n" + pass_forward.text);
            sb = sb.Replace("//MS_PASS_LIGHTTRANSPORT", vertMesh.text + "\n" + pass_lighttransport.text);
            sb = sb.Replace("//MS_PASS_DECAL", vertMesh.text + "\n" + pass_decal.text);

            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                sb = sb.Replace("//MS_BLENDABLE", terrainBlendBody.text);
                sb = sb.Replace("Blend [_SrcBlend] [_DstBlend], [_AlphaSrcBlend] [_AlphaDstBlend]", "Blend SrcAlpha OneMinusSrcAlpha");
            }

            // extentions
            StringBuilder ext = new StringBuilder();

            compiler.WriteExtensions(features, ext);

            sb = sb.Replace("//MS_EXTENSIONS", ext.ToString());

            ext = new StringBuilder();
            foreach (var e in compiler.extensions)
            {
                e.WriteAfterVetrexFunctions(ext);
            }

            sb = sb.Replace("//MS_AFTERVERTEX", ext.ToString());

            // HD fixup
            sb = sb.Replace("fixed", "half");
            sb = sb.Replace("unity_ObjectToWorld", "GetObjectToWorldMatrix()");
            sb = sb.Replace("unity_WorldToObject", "GetWorldToObjectMatrix()");
            sb = sb.Replace("_ObjectToWorld", "GetObjectToWorldMatrix()");
            sb = sb.Replace("_WorldToObject", "GetWorldToObjectMatrix()");

            sb = sb.Replace("UNITY_MATRIX_M", "GetObjectToWorldMatrix()");
            sb = sb.Replace("UNITY_MATRIX_I_M", "GetWorldToObjectMatrix()");
            sb = sb.Replace("UNITY_MATRIX_VP", "GetWorldToHClipMatrix()");
            sb = sb.Replace("UNITY_MATRIX_V", "GetWorldToViewMatrix()");
            sb = sb.Replace("UNITY_MATRIX_P", "GetViewToHClipMatrix()");

            if (features.Contains("_USESPECULARWORKFLOW"))
            {
                sb = sb.Replace("// #define _MATERIAL_FEATURE_SPECULAR_COLOR 1", "#define _MATERIAL_FEATURE_SPECULAR_COLOR 1");
            }

            if (features.Contains("_TESSDISTANCE"))
            {
                sb = sb.Replace("#pragma vertex Vert", "#pragma hull hull\n#pragma domain domain\n#pragma vertex tessvert\n#pragma require tessellation tessHW\n");
            }
        }
示例#17
0
 public void WriteSharedCode(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
     if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
     {
         sb.AppendLine(templateDecal.text);
     }
     else
     {
         sb.AppendLine(template.text);
     }
 }
示例#18
0
 /// <summary>
 /// Called after the shader is generated, for search/replace operations
 /// </summary>
 /// <param name="sb"></param>
 /// <param name="features"></param>
 /// <param name="name"></param>
 /// <param name="baseName"></param>
 /// <param name="auxShader"></param>
 public virtual void OnPostGeneration(ref StringBuilder sb, string[] features, string name, string baseName = null, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader = null)
 {
 }
示例#19
0
 public void WritePassHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
示例#20
0
        public Blocks GetShaderBlocks(string[] features,
                                      MicroSplatShaderGUI.MicroSplatCompiler compiler,
                                      MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
        {
            StringBuilder defines = new StringBuilder();

            compiler.WriteDefines(features, defines);
            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                defines.AppendLine("      #define _SRPTERRAINBLEND 1");
            }

            if (features.Contains("_USESPECULARWORKFLOW"))
            {
                defines.AppendLine("      #define _SPECULAR_SETUP");
            }
            if (features.Contains("_MICROTERRAIN") && !features.Contains("_TERRAINBLENDABLESHADER")) // digger? mesh terrain?
            {
                defines.AppendLine("#pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap forwardadd");
            }
            StringBuilder cbuffer = new StringBuilder();

            compiler.WritePerMaterialCBuffer(features, cbuffer);
            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                cbuffer.AppendLine(terrainBlendCBuffer.text);
            }

            StringBuilder options = new StringBuilder();

            WriteOptions(features, options, compiler, auxShader, null);
            StringBuilder properties = new StringBuilder();

            compiler.WriteProperties(features, properties, auxShader);

            StringBuilder ext = new StringBuilder();

            compiler.WriteExtensions(features, ext);

            StringBuilder afterVertex = new StringBuilder();

            foreach (var e in compiler.extensions)
            {
                e.WriteAfterVetrexFunctions(afterVertex);
            }

            StringBuilder code = new StringBuilder(100000);

            code.AppendLine(adapter.text);
            code.AppendLine(sharedInc.text);
            code.AppendLine(StripVertexWorkflow(features));
            code.AppendLine((StripMegaSplat(features)));
            if (features.Contains("_PLANETVECTORS") && planetData != null)
            {
                code.AppendLine(planetData.text);
            }
            code.AppendLine(sharedHD.text);
            code.AppendLine(ext.ToString());
            code.AppendLine(terrainBody.text);
            code.AppendLine(vertex.text);
            if (auxShader != null && auxShader.trigger == "_TERRAINBLENDING")
            {
                code.AppendLine(terrainBlendBody.text);
            }
            code.AppendLine(mainFunc.text);
            code.AppendLine(afterVertex.ToString());

            Blocks b = new Blocks();

            b.code       = code.ToString();
            b.cbuffer    = cbuffer.ToString();
            b.properties = properties.ToString();
            b.defines    = defines.ToString();
            b.options    = options.ToString();

            return(b);
        }
        public StringBuilder WriteShader(string[] features,
                                         MicroSplatShaderGUI.MicroSplatCompiler compiler,
                                         MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader,
                                         string name,
                                         string baseName)
        {
            StringBuilder defines = new StringBuilder();
            var           blocks  = gen.GetShaderBlocks(features, compiler, auxShader);

            var shader = BuildTemplate(blocks, baseName);

            defines.AppendLine(blocks.defines);
            defines.AppendLine("\n   #define _HDRP 1");


            string shaderTarget = "4.6";

            if (features.Contains("_FORCEMODEL50"))
            {
                shaderTarget = "5.0";
            }

            if (features.Contains("_TESSDISTANCE"))
            {
                defines.AppendLine("\n      #define _TESSELLATION_ON 1");
                shader = shader.Replace("%TESSELLATION%", templateTess.text);
                shader = shader.Replace("%PRAGMAS%", "   #pragma hull Hull\n   #pragma domain Domain\n   #pragma vertex TessVert\n   #pragma fragment Frag\n   #pragma require tesshw\n");
            }
            else
            {
                shader = shader.Replace("%PRAGMAS%", "   #pragma vertex Vert\n   #pragma fragment Frag");
                shader = shader.Replace("%TESSELLATION%", "");
            }
            shader = shader.Replace("%SHADERTARGET%", shaderTarget);
            if (features.Contains("_USESPECULARWORKFLOW"))
            {
                defines.AppendLine("\n#define _USESPECULAR 1");
                defines.AppendLine("#define _MATERIAL_FEATURE_SPECULAR_COLOR 1");
            }

            defines.AppendLine();

            shader = shader.Replace("%SHADERNAME%", name);
            shader = shader.Replace("%PROPERTIES%", blocks.properties);
            shader = shader.Replace("%CODE%", blocks.code);
            shader = shader.Replace("%DEFINES%", defines.ToString());
            shader = shader.Replace("%CBUFFER%", blocks.cbuffer);
            string codeNoComments = blocks.code.StripComments();

            shader = SurfaceShaderRenderLoopAdapter.Strip(codeNoComments, shader);

            // standard pipeline stuff
            shader = shader.Replace("fixed", "half");
            shader = shader.Replace("unity_ObjectToWorld", "GetObjectToWorldMatrix()");
            shader = shader.Replace("unity_WorldToObject", "GetWorldToObjectMatrix()");

            //shader = shader.Replace("UNITY_MATRIX_M", "GetObjectToWorldMatrix()");
            //shader = shader.Replace("UNITY_MATRIX_I_M", "GetWorldToObjectMatrix()");
            //shader = shader.Replace("UNITY_MATRIX_VP", "GetWorldToHClipMatrix()");
            //shader = shader.Replace("UNITY_MATRIX_V", "GetWorldToViewMatrix()");
            //shader = shader.Replace("UNITY_MATRIX_P", "GetViewToHClipMatrix()");

            return(shader);
        }
示例#22
0
        void WriteOptions(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader, string baseName)
        {
            if (features.Contains("_TESSDISTANCE"))
            {
                sb.AppendLine("Tessellation \"Distance\"");
            }

            sb.Append("      Tags {\"RenderType\" = \"Opaque\" \"Queue\" = \"Geometry+100\" \"IgnoreProjector\" = \"False\" ");


            if (features.Contains("_MAX4TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"4\"");
            }
            else if (features.Contains("_MAX8TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"8\"");
            }
            else if (features.Contains("_MAX12TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"12\"");
            }
            else if (features.Contains("_MAX20TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"20\"");
            }
            else if (features.Contains("_MAX24TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"24\"");
            }
            else if (features.Contains("_MAX28TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"28\"");
            }
            else if (features.Contains("_MAX32TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"32\"");
            }
            else
            {
                sb.Append("\"SplatCount\" = \"16\"");
            }
            sb.AppendLine("}");

            if (features.Contains("_MESHOVERLAYSPLATS"))
            {
                sb.AppendLine("   Alpha \"Blend\"");
            }
            if (auxShader != null && !string.IsNullOrEmpty(auxShader.customEditor))
            {
                sb.AppendLine("      CustomEditor \"" + auxShader.customEditor + "\"");
            }
            if (auxShader != null && !string.IsNullOrEmpty(auxShader.options))
            {
                sb.AppendLine(auxShader.options);
            }
            else if (auxShader != null)
            {
                sb.AppendLine("   CustomEditor \"MicroSplatShaderGUI\"");
            }
            else if (baseName == null)
            {
                sb.AppendLine("   CustomEditor \"MicroSplatShaderGUI\"");
            }
            else if (baseName != null)
            {
                if (features.Contains("_MICROTERRAIN") && !features.Contains("_TERRAINBLENDABLESHADER"))
                {
                    sb.AppendLine("   Dependency {\"BaseMapShader\" = \"" + baseName + "\"}");
                }
                sb.AppendLine("   CustomEditor \"MicroSplatShaderGUI\"");
            }
            sb.AppendLine("   Fallback \"Nature/Terrain/Diffuse\"");
        }