Пример #1
0
        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("}");
        }
Пример #2
0
 public void WriteShaderFooter(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader, string baseName)
 {
     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("}");
 }
Пример #3
0
    static Material SetupMaterial(Material mat, MicroSplatBaseFeatures.DebugOutput debugOutput)
    {
        MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();
        List <string> keywords = new List <string>(mat.shaderKeywords);

        RemoveKeyword(keywords, "_SNOW");
        RemoveKeyword(keywords, "_TESSDISTANCE");
        RemoveKeyword(keywords, "_WINDPARTICULATE");
        RemoveKeyword(keywords, "_SNOWPARTICULATE");
        RemoveKeyword(keywords, "_GLITTER");
        RemoveKeyword(keywords, "_SNOWGLITTER");

        keywords.Add(FeatureFromOutput(debugOutput).ToString());

        string   shader    = comp.Compile(keywords.ToArray(), "RenderBake_" + debugOutput.ToString());
        Shader   s         = ShaderUtil.CreateShaderAsset(shader);
        Material renderMat = new Material(mat);

        renderMat.shader = s;
        return(renderMat);
    }
        public void WriteShaderHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, bool blend)
        {
            sb.AppendLine();
            sb.AppendLine("   CGINCLUDE");

            if (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.AppendLine("      Tags{ \"RenderType\" = \"Opaque\"  \"Queue\" = \"Geometry+100\" }");
            sb.AppendLine("      Cull Back");
            sb.AppendLine("      ZTest LEqual");
            if (blend)
            {
                sb.AppendLine("      BLEND ONE ONE");
            }
#if UNITY_2018_3_OR_NEWER
            sb.AppendLine("      UsePass \"Hidden/Nature/Terrain/Utilities/PICKING\"");
            sb.AppendLine("      UsePass \"Hidden/Nature/Terrain/Utilities/SELECTION\"");
#endif
            sb.AppendLine("      CGPROGRAM");
        }
Пример #5
0
        public void WriteShaderFooter(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, bool blend, string baseName)
        {
            if (blend)
            {
                sb.AppendLine("   CustomEditor \"MicroSplatBlendableMaterialEditor\"");
            }
            else if (baseName != null)
            {
                sb.AppendLine("   Dependency \"AddPassShader\" = \"Hidden/MicroSplat/AddPass\"");
                // for 2018 basemap gen
                string depName = baseName;
                if (depName.Contains("Hidden/MicroSplat"))
                {
                    depName = depName.Substring(depName.IndexOf("Hidden/MicroSplat") + 17);
                }

                sb.AppendLine("   Dependency \"BaseMapGenShader\" = \"" + depName + "\"");
                sb.AppendLine("   Dependency \"BaseMapShader\" = \"" + baseName + "\"");
                sb.AppendLine("   CustomEditor \"MicroSplatShaderGUI\"");
            }
            sb.AppendLine("   Fallback \"Nature/Terrain/Diffuse\"");
            sb.Append("}");
        }
Пример #6
0
    static Material SetupMaterial(MicroSplatKeywords kwds, Material mat, MicroSplatBaseFeatures.DebugOutput debugOutput, bool useDebugTopo)
    {
        MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();

        List <string> keywords = new List <string>(kwds.keywords);

        RemoveKeyword(keywords, "_SNOW");
        RemoveKeyword(keywords, "_TESSDISTANCE");
        RemoveKeyword(keywords, "_WINDPARTICULATE");
        RemoveKeyword(keywords, "_SNOWPARTICULATE");
        RemoveKeyword(keywords, "_GLITTER");
        RemoveKeyword(keywords, "_SNOWGLITTER");
        RemoveKeyword(keywords, "_SPECULARFROMMETALLIC");
        RemoveKeyword(keywords, "_USESPECULARWORKFLOW");
        RemoveKeyword(keywords, "_BDRFLAMBERT");
        RemoveKeyword(keywords, "_BDRF1");
        RemoveKeyword(keywords, "_BDRF2");
        RemoveKeyword(keywords, "_BDRF3");

        keywords.Add(FeatureFromOutput(debugOutput).ToString());
        if (useDebugTopo)
        {
            keywords.Add("_DEBUG_USE_TOPOLOGY");
        }

        keywords.Add("_RENDERBAKE");

        string   shader    = comp.Compile(keywords.ToArray(), "RenderBake_" + debugOutput.ToString());
        Shader   s         = ShaderUtil.CreateShaderAsset(shader);
        Material renderMat = new Material(mat);

        renderMat.shader = s;
        renderMat.CopyPropertiesFromMaterial(mat); // because the constructor doesn't do it right in URP
        renderMat.enableInstancing = false;        // for some reason instance drawing breaks in URP
        return(renderMat);
    }
Пример #7
0
 public void WritePassHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
Пример #8
0
        public void WriteShaderHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, bool blend)
        {
            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("_MAX16TEXTURES"))
            {
                sb.Append("\"SplatCount\" = \"16\"");
            }
            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\"");
            }
            sb.AppendLine("}");
            sb.AppendLine("      Cull Back");
            sb.AppendLine("      ZTest LEqual");
            if (blend)
            {
                sb.AppendLine("      BLEND ONE ONE");
            }
#if UNITY_2018_3_OR_NEWER
            sb.AppendLine("      UsePass \"Hidden/Nature/Terrain/Utilities/PICKING\"");
            sb.AppendLine("      UsePass \"Hidden/Nature/Terrain/Utilities/SELECTION\"");
#endif
            sb.AppendLine("      CGPROGRAM");
        }
Пример #9
0
 public void WriteSharedCode(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, bool blend)
 {
     sb.AppendLine(sharedInc.text);
 }
Пример #10
0
        public void WritePassHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, bool blend)
        {
            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 (blend)
            {
                if (features.Contains("_MESHOVERLAYSPLATS"))
                {
                    pragma = declareMeshBlend;
                }
                else
                {
                    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 (!features.Contains("_DEBUG_USE_TOPOLOGY") && features.Contains("_BDRFLAMBERT"))
            {
                pragma = pragma.Replace("Standard", "Lambert");
            }
            else if (features.Contains("_USESPECULARWORKFLOW"))
            {
                pragma = pragma.Replace("Standard", "StandardSpecular");
            }

            sb.Append(pragma);

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

            // allow for custom functions in lighting when this keyword is enabled
            if (!blend && features.Contains("_MSCUSTOMLIGHTING"))
            {
                sb.Replace("surf Standard", "customLightingSurf CustomLighting");
            }


            // 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");
        }
Пример #11
0
    bool DoConvertGUI(MicroSplatTerrain t)
    {
        if (t.templateMaterial == null)
        {
            InitConvertConfigs();
            using (new GUILayout.VerticalScope(GUI.skin.box))
            {
                EditorGUILayout.LabelField("Select a Template:");

                EditorGUILayout.BeginHorizontal();
                for (int i = 0; i < convertConfigs.Count; ++i)
                {
                    var c = convertConfigs [i];
                    if (DrawConvertButton(c, i == selectedConvertConfig))
                    {
                        selectedConvertConfig = i;
                    }
                }
                EditorGUILayout.EndHorizontal();

                var selectedConfig = convertConfigs [selectedConvertConfig];
                if (selectedConfig.missingModules.Count > 0)
                {
                    EditorGUILayout.HelpBox("You are missing some MicroSplat modules needed by this template. The preset may still be used but some features will not be enabled. Missing modules are listed below:", MessageType.Warning);
                    for (int i = 0; i < selectedConfig.missingModules.Count; ++i)
                    {
                        var m = selectedConfig.missingModules [i];
                        DrawMissingModule(m);
                    }
                }

                EditorGUILayout.LabelField("Select any integrations you want to add:");
                // integrations
                for (int i = 0; i < integrationConfigs.Count; ++i)
                {
                    var ic = integrationConfigs [i];
                    if (!ic.assetInstalled)
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField(ic.name, GUILayout.Width(120));
                        EditorGUILayout.LabelField("Not Installed", GUILayout.Width(120));
                        if (GUILayout.Button("Link", GUILayout.Width(120)))
                        {
                            Application.OpenURL(ic.assetLink);
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    else
                    {
                        EditorGUILayout.BeginHorizontal();
                        ic.include = EditorGUILayout.Toggle(ic.include, GUILayout.Width(20));
                        EditorGUILayout.LabelField(ic.name);
                        EditorGUILayout.EndHorizontal();
                        if (ic.include && ic.missingModules.Count > 0)
                        {
                            using (new GUILayout.VerticalScope(GUI.skin.box))
                            {
                                EditorGUILayout.HelpBox("Some MicroSplat modules requested by this module are not installed. Some or all features of the integration will not be active.", MessageType.Warning);
                                for (int j = 0; j < ic.missingModules.Count; ++j)
                                {
                                    var m = ic.missingModules [j];
                                    DrawMissingModule(m);
                                }
                            }
                        }
                    }
                }

                if (GUILayout.Button("Convert to MicroSplat"))
                {
                    // get all terrains in selection, not just this one, and treat as one giant terrain
                    var            objs     = Selection.gameObjects;
                    List <Terrain> terrains = new List <Terrain> ();
                    for (int i = 0; i < objs.Length; ++i)
                    {
                        Terrain ter = objs [i].GetComponent <Terrain> ();
                        if (ter != null)
                        {
                            terrains.Add(ter);
                        }
                        Terrain [] trs = objs [i].GetComponentsInChildren <Terrain> ();
                        for (int x = 0; x < trs.Length; ++x)
                        {
                            if (!terrains.Contains(trs [x]))
                            {
                                terrains.Add(trs [x]);
                            }
                        }
                    }

                    Terrain terrain  = t.GetComponent <Terrain> ();
                    int     texcount = 16;
#if UNITY_2018_3_OR_NEWER
                    texcount = terrain.terrainData.terrainLayers.Length;
#else
                    texcount = terrain.terrainData.splatPrototypes.Length;
#endif
                    List <string> keywords = new List <string> (selectedConfig.keywords);
                    if (texcount <= 4)
                    {
                        keywords.Add("_MAX4TEXTURES");
                    }
                    else if (texcount <= 8)
                    {
                        keywords.Add("_MAX8TEXTURES");
                    }
                    else if (texcount <= 12)
                    {
                        keywords.Add("_MAX12TEXTURES");
                    }
                    else if (texcount <= 20)
                    {
                        keywords.Add("_MAX20TEXTURES");
                    }
                    else if (texcount <= 24)
                    {
                        keywords.Add("_MAX24TEXTURES");
                    }
                    else if (texcount <= 28)
                    {
                        keywords.Add("_MAX28TEXTURES");
                    }
                    else if (texcount > 28)
                    {
                        keywords.Add("_MAX32TEXTURES");
                    }

                    for (int i = 0; i < integrationConfigs.Count; ++i)
                    {
                        var ic = integrationConfigs [i];
                        if (ic.include)
                        {
                            keywords.AddRange(ic.keywords);
                        }
                    }

                    // setup this terrain
                    t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain, keywords.ToArray());

                    var config = TextureArrayConfigEditor.CreateConfig(terrain);
                    t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray);
                    t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray);

                    t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial);
#if UNITY_2018_3_OR_NEWER
                    if (terrain.terrainData.terrainLayers.Length > 0)
                    {
                        var uvScale  = terrain.terrainData.terrainLayers[0].tileSize;
                        var uvOffset = terrain.terrainData.terrainLayers[0].tileOffset;

                        uvScale    = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain);
                        uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x;
                        uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y;
                        Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y);
                        t.templateMaterial.SetVector("_UVScale", scaleOffset);
                    }
#else
                    if (terrain.terrainData.splatPrototypes.Length > 0)
                    {
                        var uvScale  = terrain.terrainData.splatPrototypes [0].tileSize;
                        var uvOffset = terrain.terrainData.splatPrototypes [0].tileOffset;

                        uvScale    = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain);
                        uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x;
                        uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y;
                        Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y);
                        t.templateMaterial.SetVector("_UVScale", scaleOffset);
                    }
#endif
                    // we need to set a few things on the material if certain features are enabled.
                    // Test for property existence as module might not be installed and feature was culled.
                    if (System.Array.Exists(selectedConfig.keywords, x => x == "_TRIPLANAR"))
                    {
                        if (t.templateMaterial.HasProperty("_TriplanarUVScale"))
                        {
                            t.templateMaterial.SetVector("_TriplanarUVScale", new Vector4(0.25f, 0.25f, 0, 0));
                        }
                    }

                    if (System.Array.Exists(selectedConfig.keywords, x => x == "_NORMALNOISE"))
                    {
                        if (t.templateMaterial.HasProperty("_NormalNoise"))
                        {
                            t.templateMaterial.SetTexture("_NormalNoise", MicroSplatUtilities.GetAutoTexture("microsplat_def_detail_normal_01"));
                        }
                    }

                    // now make sure others all have the same settings as well.
                    for (int i = 0; i < terrains.Count; ++i)
                    {
                        var nt  = terrains [i];
                        var mgr = nt.GetComponent <MicroSplatTerrain> ();
                        if (mgr == null)
                        {
                            mgr = nt.gameObject.AddComponent <MicroSplatTerrain> ();
                        }
                        mgr.templateMaterial = t.templateMaterial;

                        if (mgr.propData == null)
                        {
                            mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial);
                        }
                    }


                    Selection.SetActiveObjectWithContext(config, config);
                    t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial);

                    t.keywordSO.keywords.Clear();
                    t.keywordSO.keywords = new List <string> (keywords);

                    // force recompile, so that basemap shader name gets reset correctly..
                    MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();
                    comp.Compile(t.templateMaterial);

                    MicroSplatTerrain.SyncAll();

                    // trun on draw instanced if enabled and tessellation is disabled, unless render loop is LWRP/URP in which case it does work..
#if UNITY_2018_3_OR_NEWER
                    if (t.keywordSO != null && (!t.keywordSO.IsKeywordEnabled("_TESSDISTANCE") || t.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD")))
                    {
                        for (int i = 0; i < terrains.Count; ++i)
                        {
                            var nt  = terrains [i];
                            var mgr = nt.GetComponent <MicroSplatTerrain> ();
                            if (mgr != null && mgr.keywordSO != null && !mgr.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD"))
                            {
                                nt.drawInstanced = true;
                            }
                        }
                    }
#endif
                    return(true);
                }
            }
        }
        return(false);
    }
        /// <summary>
        /// Attempt to recompile MicroSplat shader, ensuring the name matches the landscape name
        /// USAGE:
        /// bool isSuccessful = MicroSplatCompileShader(landscape, customTerrainMaterial, true);
        /// </summary>
        /// <param name="landscape"></param>
        /// <param name="terrainMat"></param>
        /// <param name="showErrors"></param>
        /// <returns></returns>
        public static bool MicroSplatCompileShader(LBLandscape landscape, Material terrainMat, bool showErrors)
        {
            bool   isSuccessful = false;
            string methodName   = "LBEditorIntegration.MicroSplatCompileShader";

            //System.Type MicroSplatShaderGUIType = null;

            try
            {
                if (landscape == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " landscape is null. Please Report");
                    }
                }
                else if (terrainMat == null)
                {
                    if (showErrors)
                    {
                        Debug.LogWarning("ERROR: " + methodName + " terrainMat is null. Please Report");
                    }
                }
                else
                {
                    Shader shader = terrainMat.shader;

                    if (shader == null)
                    {
                        if (showErrors)
                        {
                            Debug.LogWarning(methodName + " - could not find MicroSplat shader. Please Report.");
                        }
                    }
                    else if (!shader.name.Contains("MicroSplat"))
                    {
                        if (showErrors)
                        {
                            Debug.LogWarning(methodName + " - terrain material is not using a MicroSplat shader. [" + shader.name + "]. Please Report");
                        }
                    }
                    else
                    {
                        // Create a new instance of the compiler class
                        MicroSplatShaderGUI.MicroSplatCompiler microSplatCompiler = new MicroSplatShaderGUI.MicroSplatCompiler();
                        string shaderPath     = AssetDatabase.GetAssetPath(shader);
                        string shaderBasePath = shaderPath.Replace(".shader", "_Base.shader");

                        if (microSplatCompiler == null)
                        {
                            if (showErrors)
                            {
                                Debug.LogWarning(methodName + " - could not create MicroSplatCompiler instance. Please Report.");
                            }
                        }
                        else
                        {
                            microSplatCompiler.Init();
                            string[] shaderFeatures = terrainMat.shaderKeywords;

                            // Ensure shader names match the landscape name
                            string baseName = "Hidden/MicroSplat/" + landscape.name + "_Base";

                            string baseShaderOutput    = microSplatCompiler.Compile(shaderFeatures, baseName);
                            string regularShaderOutput = microSplatCompiler.Compile(shaderFeatures, "MicroSplat/" + landscape.name, baseName);

                            //Debug.Log("[DEBUG] regularShaderOutput: " + regularShaderOutput);

                            // Copy the output back to the shader files in the project folder.
                            System.IO.File.WriteAllText(shaderPath, regularShaderOutput);
                            System.IO.File.WriteAllText(shaderBasePath, baseShaderOutput);

                            // Currently we don't use this but we "might" in the future
                            if (shaderFeatures.Contains("_MESHOVERLAYSPLATS"))
                            {
                                string meshOverlayShader = microSplatCompiler.Compile(shaderFeatures, "MicroSplat/" + landscape.name, null, true);
                                System.IO.File.WriteAllText(shaderPath.Replace(".shader", "_MeshOverlay.shader"), meshOverlayShader);
                            }
                            AssetDatabase.Refresh();

                            isSuccessful = !string.IsNullOrEmpty(baseShaderOutput) && !string.IsNullOrEmpty(regularShaderOutput);
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                if (showErrors)
                {
                    Debug.LogWarning("LBIntegration.MegaSplatCompileShader something has gone wrong. Please report. " + ex.Message);
                }
            }

            return(isSuccessful);
        }
Пример #13
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\"");
        }
Пример #14
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);
        }
Пример #15
0
 public void PostProcessShader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
Пример #16
0
 public void WriteVertexFunction(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, MicroSplatShaderGUI.MicroSplatCompiler.AuxShader auxShader)
 {
 }
Пример #17
0
    bool DoConvertGUI(MicroSplatTerrain t)
    {
        if (t.templateMaterial == null)
        {
            InitConvertConfigs();
            using (new GUILayout.VerticalScope(GUI.skin.box))
            {
                EditorGUILayout.LabelField("Select any integrations you want to add:");
                // integrations
                for (int i = 0; i < integrationConfigs.Count; ++i)
                {
                    var ic = integrationConfigs [i];
                    if (!ic.assetInstalled)
                    {
                        EditorGUILayout.BeginHorizontal();
                        EditorGUILayout.LabelField(ic.name, GUILayout.Width(120));
                        EditorGUILayout.LabelField("Not Installed", GUILayout.Width(120));
                        if (GUILayout.Button("Link", GUILayout.Width(120)))
                        {
                            Application.OpenURL(ic.assetLink);
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                    else
                    {
                        EditorGUILayout.BeginHorizontal();
                        ic.include = EditorGUILayout.Toggle(ic.include, GUILayout.Width(20));
                        EditorGUILayout.LabelField(ic.name);
                        EditorGUILayout.EndHorizontal();
                        if (ic.include && ic.missingModules.Count > 0)
                        {
                            using (new GUILayout.VerticalScope(GUI.skin.box))
                            {
                                EditorGUILayout.HelpBox("Some MicroSplat modules requested by this module are not installed. Some or all features of the integration will not be active.", MessageType.Warning);
                                for (int j = 0; j < ic.missingModules.Count; ++j)
                                {
                                    var m = ic.missingModules [j];
                                    DrawMissingModule(m);
                                }
                            }
                        }
                    }
                }

                if (GUILayout.Button("Convert to MicroSplat"))
                {
                    // get all terrains in selection, not just this one, and treat as one giant terrain
                    var            objs     = Selection.gameObjects;
                    List <Terrain> terrains = new List <Terrain> ();
                    for (int i = 0; i < objs.Length; ++i)
                    {
                        Terrain ter = objs [i].GetComponent <Terrain> ();
                        if (ter != null)
                        {
                            terrains.Add(ter);
                        }
                        Terrain [] trs = objs [i].GetComponentsInChildren <Terrain> ();
                        for (int x = 0; x < trs.Length; ++x)
                        {
                            if (!terrains.Contains(trs [x]))
                            {
                                terrains.Add(trs [x]);
                            }
                        }
                    }


                    Terrain       terrain  = t.GetComponent <Terrain> ();
                    int           texcount = terrain.terrainData.terrainLayers.Length;
                    List <string> keywords = new List <string> (defaultKeywords);
                    // set initial render pipleine
                    var pipeline = MicroSplatUtilities.DetectPipeline();
                    if (pipeline == MicroSplatUtilities.PipelineType.HDPipeline)
                    {
                        keywords.Add("_MSRENDERLOOP_UNITYHD");
                    }
                    else if (pipeline == MicroSplatUtilities.PipelineType.UniversalPipeline)
                    {
                        keywords.Add("_MSRENDERLOOP_UNITYLD");
                    }


                    // Because new users won't read the manual or read settings before they act, we don't clamp the texture count
                    // down for maximum performance. Way to many support requests complaining of black terrain after adding textures because
                    // they didn't realize they needed to up the max texture count. So now, 16 minimum. This is why we can't have nice things.

                    /*
                     * if (texcount <= 4)
                     * {
                     * keywords.Add ("_MAX4TEXTURES");
                     * }
                     * else if (texcount <= 8)
                     * {
                     * keywords.Add ("_MAX8TEXTURES");
                     * }
                     * else if (texcount <= 12)
                     * {
                     * keywords.Add ("_MAX12TEXTURES");
                     * }
                     */
                    if (texcount > 16 && texcount <= 20)
                    {
                        keywords.Add("_MAX20TEXTURES");
                    }
                    else if (texcount <= 24)
                    {
                        keywords.Add("_MAX24TEXTURES");
                    }
                    else if (texcount <= 28)
                    {
                        keywords.Add("_MAX28TEXTURES");
                    }
                    else if (texcount > 28)
                    {
                        keywords.Add("_MAX32TEXTURES");
                    }


                    for (int i = 0; i < integrationConfigs.Count; ++i)
                    {
                        var ic = integrationConfigs [i];
                        if (ic.include)
                        {
                            keywords.AddRange(ic.keywords);
                        }
                    }

                    // setup this terrain
                    t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain, keywords.ToArray());

                    var config = TextureArrayConfigEditor.CreateConfig(terrain);
                    t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray);
                    t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray);

                    t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial);
                    EditorUtility.SetDirty(t);
                    if (terrain.terrainData.terrainLayers != null)
                    {
                        if (terrain.terrainData.terrainLayers.Length > 0)
                        {
                            Vector2 min = new Vector2(99999, 99999);
                            Vector2 max = Vector2.zero;


                            for (int x = 0; x < terrain.terrainData.terrainLayers.Length; ++x)
                            {
                                var uv = terrain.terrainData.terrainLayers [x].tileSize;
                                if (min.x > uv.x)
                                {
                                    min.x = uv.x;
                                }
                                if (min.y > uv.y)
                                {
                                    min.y = uv.y;
                                }
                                if (max.x < uv.x)
                                {
                                    max.x = uv.x;
                                }
                                if (max.y < uv.y)
                                {
                                    max.y = uv.y;
                                }
                            }
                            Vector2 average = Vector2.Lerp(min, max, 0.5f);
                            // use per texture UVs instead..
                            float diff = Vector2.Distance(min, max);
                            if (diff > 0.1)
                            {
                                keywords.Add("_PERTEXUVSCALEOFFSET");

                                // if the user has widely different UVs, use the LOD sampler. This is because the gradient mode blends between mip levels,
                                // which looks bad with hugely different UVs. I still don't understand why people do this kind of crap though, ideally
                                // your UVs should not differ per texture, and if so, not by much..
                                if (diff > 10)
                                {
                                    Debug.LogWarning("Terrain has wildly varing UV scales, it's best to keep consistent texture resolution. ");
                                }
                                if (!keywords.Contains("_USEGRADMIP"))
                                {
                                    keywords.Add("_USEGRADMIP");
                                }
                                Vector4 scaleOffset = new Vector4(1, 1, 0, 0);
                                t.templateMaterial.SetVector("_UVScale", scaleOffset);
                                var propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial);

                                for (int x = 0; x < terrain.terrainData.terrainLayers.Length; ++x)
                                {
                                    var uvScale  = terrain.terrainData.terrainLayers [x].tileSize;
                                    var uvOffset = terrain.terrainData.terrainLayers [x].tileOffset;
                                    uvScale   = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain);
                                    uvScale.x = Mathf.RoundToInt(uvScale.x);
                                    uvScale.y = Mathf.RoundToInt(uvScale.y);
                                    propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVScale, uvScale);
                                    propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVOffset, Vector2.zero);
                                }
                                for (int x = terrain.terrainData.terrainLayers.Length; x < 32; ++x)
                                {
                                    propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVScale, average);
                                    propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVOffset, Vector2.zero);
                                }
                                // must init the data, or the editor will write over it.

                                propData.SetValue(0, 15, Color.white);
                                EditorUtility.SetDirty(propData);

                                t.templateMaterial.SetVector("_TriplanarUVScale",
                                                             new Vector4(
                                                                 10.0f / t.terrain.terrainData.size.x,
                                                                 10.0f / t.terrain.terrainData.size.x, 0, 0));
                            }
                            else
                            {
                                var uvScale  = terrain.terrainData.terrainLayers [0].tileSize;
                                var uvOffset = terrain.terrainData.terrainLayers [0].tileOffset;

                                uvScale    = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain);
                                uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x;
                                uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y;
                                Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y);
                                t.templateMaterial.SetVector("_UVScale", scaleOffset);
                                t.templateMaterial.SetVector("_TriplanarUVScale",
                                                             new Vector4(
                                                                 10.0f / t.terrain.terrainData.size.x,
                                                                 10.0f / t.terrain.terrainData.size.x, 0, 0));
                            }
                        }
                    }


                    // now make sure others all have the same settings as well.
                    for (int i = 0; i < terrains.Count; ++i)
                    {
                        var nt  = terrains [i];
                        var mgr = nt.GetComponent <MicroSplatTerrain> ();
                        if (mgr == null)
                        {
                            mgr = nt.gameObject.AddComponent <MicroSplatTerrain> ();
                        }
                        mgr.templateMaterial = t.templateMaterial;

                        if (mgr.propData == null)
                        {
                            mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial);
                        }
                    }


                    Selection.SetActiveObjectWithContext(config, config);
                    t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial);

                    t.keywordSO.keywords.Clear();
                    t.keywordSO.keywords = new List <string> (keywords);



                    // force recompile, so that basemap shader name gets reset correctly..
                    MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();
                    comp.Compile(t.templateMaterial);
                    // for some reason, often when  people create terrains with Gaia but this is unconfirmed,
                    // if instancing is set, the terrain will not draw until a shader feature is toggled.
                    // So for now, turn off instancing when doing conversion.
                    for (int i = 0; i < terrains.Count; ++i)
                    {
                        var nt = terrains [i];
                        nt.drawInstanced = false;
                    }


                    MicroSplatTerrain.SyncAll();

                    /*
                     * // turn on draw instanced if enabled and tessellation is disabled, unless render loop is LWRP/URP in which case it does work..
                     * if (t.keywordSO != null && (!t.keywordSO.IsKeywordEnabled("_TESSDISTANCE") || t.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD")))
                     * {
                     * for (int i = 0; i < terrains.Count; ++i)
                     * {
                     *    var nt = terrains [i];
                     *    var mgr = nt.GetComponent<MicroSplatTerrain> ();
                     *    if (mgr != null && mgr.keywordSO != null && !mgr.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD"))
                     *    {
                     *       nt.drawInstanced = true;
                     *    }
                     * }
                     * }
                     */
                    return(true);
                }
            }
        }
        return(false);
    }
        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);
        }
Пример #19
0
 public void WriteVertexFunction(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, bool blend)
 {
     sb.AppendLine(vertexFunc.text);
 }
        void CompressTerrainSplats(MicroSplatTerrain t)
        {
            int splatCount = t.terrain.terrainData.alphamapTextureCount;

            // write out
            for (int i = 0; i < splatCount; ++i)
            {
                var tex  = t.terrain.terrainData.GetAlphamapTexture(i);
                var path = MicroSplatUtilities.RelativePathFromAsset(t);
                path += "/" + t.name + "_splat" + i + ".tga";
                System.IO.File.WriteAllBytes(path, tex.EncodeToTGA());
            }

            AssetDatabase.Refresh();
            // load and adjust importer
            for (int i = 0; i < splatCount; ++i)
            {
                var path = MicroSplatUtilities.RelativePathFromAsset(t);
                path += "/" + t.name + "_splat" + i + ".tga";

                var tex = CompressTexture(path, false);

                if (i == 0)
                {
                    t.customControl0 = tex;
                }
                else if (i == 1)
                {
                    t.customControl1 = tex;
                }
                else if (i == 2)
                {
                    t.customControl2 = tex;
                }
                else if (i == 3)
                {
                    t.customControl3 = tex;
                }
                else if (i == 4)
                {
                    t.customControl4 = tex;
                }
                else if (i == 5)
                {
                    t.customControl5 = tex;
                }
                else if (i == 6)
                {
                    t.customControl6 = tex;
                }
                else if (i == 7)
                {
                    t.customControl7 = tex;
                }
            }
            EditorUtility.SetDirty(t);

            MicroSplatKeywords keywords = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial);

            if (!keywords.IsKeywordEnabled("_CUSTOMSPLATTEXTURES"))
            {
                keywords.EnableKeyword("_CUSTOMSPLATTEXTURES");
                MicroSplatShaderGUI.MicroSplatCompiler compiler = new MicroSplatShaderGUI.MicroSplatCompiler();
                compiler.Compile(t.templateMaterial);
                MicroSplatTerrain.SyncAll();
            }

            // destructive operation
            t.terrain.terrainData.alphamapResolution = 16;
        }
Пример #21
0
 public void PostProcessShader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, bool blend)
 {
 }
        public void WritePassHeader(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, bool blend)
        {
            sb.AppendLine("      #pragma exclude_renderers d3d9");

            sb.AppendLine("      #include \"UnityCG.cginc\"");
            sb.AppendLine("      #include \"AutoLight.cginc\"");
            sb.AppendLine("      #include \"Lighting.cginc\"");
            sb.AppendLine("      #include \"UnityPBSLighting.cginc\"");
            sb.AppendLine("      #include \"UnityStandardBRDF.cginc\"");

            string pragma = "";

            if (blend)
            {
                if (features.Contains("_MESHOVERLAYSPLATS"))
                {
                    pragma = declareMeshBlend;
                }
                else
                {
                    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 (features.Contains("_BDRFLAMBERT"))
            {
                pragma = pragma.Replace("Standard", "Lambert");
            }
            sb.Append(pragma);

            if (!blend)
            {
                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("      #pragma target " + compiler.GetShaderModel(features));
        }
Пример #23
0
 public void WriteTerrainBody(string[] features, StringBuilder sb, MicroSplatShaderGUI.MicroSplatCompiler compiler, int pass, bool blend)
 {
     sb.AppendLine(terrainBody.text);
 }
Пример #24
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");
            }
        }
        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);
        }
        void DrawScatterGUI()
        {
            if (MicroSplatUtilities.DrawRollup("Brush Settings"))
            {
                brushSize    = EditorGUILayout.Slider("Brush Size", brushSize, 0.01f, 30.0f);
                brushFlow    = EditorGUILayout.Slider("Brush Flow", brushFlow, 0.1f, 128.0f);
                brushFalloff = EditorGUILayout.Slider("Brush Falloff", brushFalloff, 0.1f, 3.5f);


                Material tempMat = null;
                for (int i = 0; i < rawTerrains.Count; ++i)
                {
                    Terrain           t   = rawTerrains [i];
                    MicroSplatTerrain mst = t.GetComponent <MicroSplatTerrain> ();
                    if (mst != null)
                    {
                        if (mst.templateMaterial != null && mst.templateMaterial.HasProperty("_ScatterDiffuse"))
                        {
                            Texture2DArray diff = mst.templateMaterial.GetTexture("_ScatterDiffuse") as Texture2DArray;
                            scatterIndex = MicroSplatUtilities.DrawTextureSelector(scatterIndex, diff, false);
                            tempMat      = mst.templateMaterial;
                        }
                        else
                        {
                            scatterIndex = EditorGUILayout.IntField("Scatter Index", scatterIndex);
                        }
                    }
                    else
                    {
                        scatterIndex = EditorGUILayout.IntField("Scatter Index", scatterIndex);
                    }
                }


                //EditorGUILayout.MinMaxSlider (CSlopeRange, ref slopeRange.x, ref slopeRange.y, 0.0f, 1.0f);

                paintValue = EditorGUILayout.Slider("Target Opacity", paintValue, 0.0f, 1.0f);



#if __MICROSPLAT_SCATTER__
                if (tempMat != null)
                {
                    scatterLayer = (ScatterLayer)EditorGUILayout.EnumPopup(CScatterLayer, scatterLayer);
                    EditorGUILayout.Separator();

                    using (new GUILayout.VerticalScope(GUI.skin.box))
                    {
                        EditorGUI.BeginChangeCheck();
                        EditorGUILayout.LabelField("Per Texture Properties");
                        bool changed = MicroSplatScatter.DrawPerTexExternal(tempMat, scatterIndex);
                        EditorGUILayout.Separator();
                        // sync compile changes
                        if (changed)
                        {
                            MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler();
                            comp.Init();
                            comp.Compile(tempMat);
                        }
                        // sync property changes
                        if (EditorGUI.EndChangeCheck())
                        {
                            MicroSplatObject.SyncAll();
                        }
                    }
                }
#endif
                GUILayout.Box("", new GUILayoutOption [] { GUILayout.ExpandWidth(true), GUILayout.Height(1) });
                EditorGUILayout.Separator();
            }
            DrawFillGUI();
        }