예제 #1
0
        public ShaderBuilder(string name, ShapesBlendMode blendMode, RenderPipeline rp)
        {
            this.blendMode  = blendMode;
            this.shaderName = name;

            using (Scope($"Shader \"Shapes/{name} {blendMode.ToString()}\"")) {
                using (Scope("Properties")) {
                    AppendLine("[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest (\"Z Test\", int) = 4");
                    AppendLine("_ZOffsetFactor (\"Z Offset Factor\", Float ) = 0");
                    AppendLine("_ZOffsetUnits (\"Z Offset Units\", int ) = 0");

                    AppendLine("[Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp (\"Stencil Comparison\", int) = 8");
                    AppendLine("[Enum(UnityEngine.Rendering.StencilOp)] _StencilOpPass (\"Stencil Operation Pass\", int) = 0");
                    AppendLine("_StencilID (\"Stencil ID\", int) = 0");
                    AppendLine("_StencilReadMask (\"Stencil Read Mask\", int) = 255");
                    AppendLine("_StencilWriteMask (\"Stencil Write Mask\", int) = 255");
                }

                using (Scope("SubShader")) {
                    using (Scope("Tags")) {                        // subshader tags
                        AppendLines(rp.GetSubshaderTags());
                        AppendLines(blendMode.GetSubshaderTags());
                    }

                    AppendPass(ShaderPassType.Render, rp);
                    if (rp != RenderPipeline.Legacy)
                    {
                        AppendPass(ShaderPassType.DepthOnly, rp);
                    }
                    AppendPass(ShaderPassType.Picking, rp);
                    AppendPass(ShaderPassType.Selection, rp);
                }
            }
        }
예제 #2
0
        public ShaderBuilder(string name, ShapesBlendMode blendMode)
        {
            this.blendMode  = blendMode;
            this.shaderName = name;

            using (Scope($"Shader \"Shapes/{name} {blendMode.ToString()}\"")) {
                using (Scope("SubShader")) {
                    using (Scope("Tags"))                        // sub shader tags
                        AppendLines(blendMode.GetSubshaderTags());

                    using (Scope("Pass")) {                        // render pass
                        AppendLines(blendMode.GetPassRenderStates());
                        AppendCGPROGRAM(ShaderPassType.Render);
                    }

                    using (Scope("Pass")) {                        // picking pass
                        AppendLine("Name \"Picking\"");
                        AppendLine("Tags { \"LightMode\" = \"Picking\" }");
                        AppendLine("Cull Off");
                        AppendCGPROGRAM(ShaderPassType.Picking);
                    }

                    using (Scope("Pass")) {                        // selection pass
                        AppendLine("Name \"Selection\"");
                        AppendLine("Tags { \"LightMode\" = \"SceneSelectionPass\" }");
                        AppendLine("Cull Off");
                        AppendCGPROGRAM(ShaderPassType.Selection);
                    }
                }
            }
        }
 public static string BlendShaderDefine(this ShapesBlendMode blendMode) => blendMode.ToString().ToUpper();
예제 #4
0
        public static void GenerateShadersAndMaterials()
        {
            int                     blendModeCount = System.Enum.GetNames(typeof(ShapesBlendMode)).Length;
            const string            CORE_SUFFIX    = " Core";
            IEnumerable <TextAsset> shaderCores    = ShapesIO.LoadAllAssets <TextAsset>(ShapesIO.CoreShaderFolder);
            IEnumerable <string>    shaderNames    = shaderCores.Select(x => x.name.Substring(0, x.name.Length - CORE_SUFFIX.Length));

            // generate all shaders
            foreach (string name in shaderNames)
            {
                for (int i = 0; i < blendModeCount; i++)
                {
                    ShapesBlendMode blendMode      = (ShapesBlendMode)i;
                    string          path           = $"{ShapesIO.GeneratedShadersFolder}/{name} {blendMode}.shader";
                    string          shaderContents = new ShaderBuilder(name, blendMode).shader;
                    File.WriteAllText(path, shaderContents);
                }
            }

            // reimport all assets to load newly generated shaders
            AssetDatabase.Refresh(ImportAssetOptions.Default);

            // generate all materials
            foreach (string name in shaderNames)
            {
                for (int i = 0; i < blendModeCount; i++)
                {
                    ShapesBlendMode blendMode         = (ShapesBlendMode)i;
                    string          nameWithBlendMode = ShapesMaterials.GetMaterialName(name, blendMode.ToString());
                    Shader          shader            = Shader.Find($"Shapes/{nameWithBlendMode}");
                    if (shader == null)
                    {
                        Debug.LogError("missing shader " + $"Shapes/{nameWithBlendMode}");
                        continue;
                    }


                    if (ShaderBuilder.shaderKeywords.ContainsKey(name))
                    {
                        // create all permutations
                        MultiCompile[] multis = ShaderBuilder.shaderKeywords[name];
                        List <string>  keywordPermutations = new List <string>();
                        foreach (IEnumerable <string> perm in GetPermutations(multis.Select(m => m.Enumerate())))
                        {
                            IEnumerable <string> validKeywords = perm.Where(p => string.IsNullOrEmpty(p) == false);
                            string kws = $" [{string.Join( "][", validKeywords )}]";
                            if (kws.Contains("[]"))                                // this means it has no permutations
                            {
                                kws = "";
                            }
                            TryCreateMaterial(nameWithBlendMode + kws, validKeywords);
                        }
                    }
                    else
                    {
                        TryCreateMaterial(nameWithBlendMode);
                    }

                    Material TryCreateMaterial(string fullMaterialName, IEnumerable <string> keywords = null)
                    {
                        string   savePath = $"{ShapesIO.GeneratedMaterialsFolder}/{fullMaterialName}.mat";
                        Material mat      = AssetDatabase.LoadAssetAtPath <Material>(savePath);

                        void TrySetKeywords()
                        {
                            if (keywords != null)
                            {
                                foreach (string keyword in keywords)
                                {
                                    mat.EnableKeyword(keyword);
                                }
                            }
                        }

                        if (mat != null)
                        {
                            EditorUtility.SetDirty(mat);
                            mat.hideFlags = HideFlags.HideInInspector;
                            TrySetKeywords();
                        }
                        else
                        {
                            Debug.Log("creating material " + savePath);
                            mat = new Material(shader)
                            {
                                enableInstancing = true, hideFlags = HideFlags.HideInInspector
                            };
                            TrySetKeywords();
                            AssetDatabase.CreateAsset(mat, savePath);
                        }

                        return(mat);
                    }
                }
            }

            AssetDatabase.Refresh(ImportAssetOptions.Default);
        }