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); } } }
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();
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); }