这是一篇年前:2021.1.28 些的日志
主要是备忘用
帮美术同学修改完 shader 后
发现烘焙后 alpha test 的 shader 都没有了投影镂空的效果
导致树叶之间的投影 乌黑一大片,然后搜索了一下
还好的是,发现 taecg 老师也在某乎上写过这个问题的处理分享
看了这篇文章就知道:unity黑箱 + 文档不说明有多 e xin:
关于AlphaTest阴影烘焙后消失的问题
处理要点:
- 主纹理名称必须是”_MainTex”,只有这个名称才会被内部识别到,就像后处理Shader中也需要用到这个名称是一样的道理。
- Shader中的Queue排序在2450-3999之间,也就是”Queue” = “AlphaTest”或者”Queue” = “Transparent”.
- RenderType设置为”RenderType” = “Transparent”或者”RenderType” = “TransparentCutout”.
记住要处理:Forwardbase 和 ShadowCaster 两个 shader 的 tag, queue 等
如果我们要重写 ShaderGUI 那么注意处理这两点即可,如下:
References
// jave.lin 2022/08/27 为 SanGuo_PBR_MRA_SSS shader 材质的编辑器重写
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
public enum JAVELIN_RenderType
{
Opaque,
AlphaTest,
TransparentWithoutPMA,
TransparentWithPMA,
Additive,
Subtractive,
}
public enum JAVELIN_ShowFaceType
{
Front,
Back,
DoubleSide,
}
public class SanGuo_PBR_MRA_SSS_MAT_GUI : ShaderGUI
{
static MaterialProperty FindAndRemoveProperty(string propertyName, List<MaterialProperty> propertyList)
{
return FindAndRemoveProperty(propertyName, propertyList, true);
}
static MaterialProperty FindAndRemoveProperty(string propertyName, List<MaterialProperty> propertyList, bool propertyIsMandatory)
{
for (var i = 0; i < propertyList.Count; i++)
if (propertyList[i] != null && propertyList[i].name == propertyName)
{
var property = propertyList[i];
propertyList.RemoveAt(i);
return property;
}
// We assume all required properties can be found, otherwise something is broken
if (propertyIsMandatory)
throw new ArgumentException("Could not find MaterialProperty: '" + propertyName + "', Num properties: " + propertyList.Count);
return null;
}
private static bool IsEnabledKW(string kw, Material target)
{
return target.IsKeywordEnabled(kw);
}
// jave.lin : 参考:2020.3.37f1 builtin shader StandardParticlesShaderGUI.cs 的 SetupMaterialWithBlendMode 函数
public static void SettingMatBlendMode(Material material, JAVELIN_RenderType blendMode)
{
switch (blendMode)
{
case JAVELIN_RenderType.Opaque:
material.SetOverrideTag("RenderType", "Geometry");
material.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
//material.DisableKeyword("_ALPHAMODULATE_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
break;
case JAVELIN_RenderType.AlphaTest:
material.SetOverrideTag("RenderType", "TransparentCutout");
material.SetOverrideTag("Queue", "AlphaTest");
material.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.EnableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
//material.DisableKeyword("_ALPHAMODULATE_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
break;
case JAVELIN_RenderType.TransparentWithoutPMA:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
//material.DisableKeyword("_ALPHAMODULATE_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
break;
case JAVELIN_RenderType.TransparentWithPMA:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
//material.DisableKeyword("_ALPHAMODULATE_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
break;
case JAVELIN_RenderType.Additive:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.Add);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
//material.DisableKeyword("_ALPHAMODULATE_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
break;
case JAVELIN_RenderType.Subtractive:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_BlendOp", (int)UnityEngine.Rendering.BlendOp.ReverseSubtract);
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
//material.DisableKeyword("_ALPHAMODULATE_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
break;
}
}
public static void SettingMatShowFaceType(Material material, JAVELIN_ShowFaceType showFaceType)
{
switch (showFaceType)
{
case JAVELIN_ShowFaceType.Front:
material.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Back);
break;
case JAVELIN_ShowFaceType.Back:
material.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Front);
break;
case JAVELIN_ShowFaceType.DoubleSide:
material.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
break;
}
}
private MaterialProperty renderTypeProp;
private MaterialProperty showFaceTypeProp;
public void FindProperties(MaterialProperty[] props)
{
renderTypeProp = FindProperty("_JL_RenderType", props, false);
showFaceTypeProp = FindProperty("_JL_ShowFaceType", props, false);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
FindProperties(properties);
Material targetMat = materialEditor.target as Material;
List<MaterialProperty> propertyList = new List<MaterialProperty>(properties);
FindAndRemoveProperty("_Parallax", propertyList, false);
FindAndRemoveProperty("_ParallaxMap", propertyList, false);
FindAndRemoveProperty("_DetailMask", propertyList, false);
FindAndRemoveProperty("_DetailAlbedoMap", propertyList, false);
FindAndRemoveProperty("_DetailNormalMapScale", propertyList, false);
FindAndRemoveProperty("_DetailNormalMap", propertyList, false);
FindAndRemoveProperty("_UVSec", propertyList, false);
FindAndRemoveProperty("_SpecularHighlights", propertyList, false);
FindAndRemoveProperty("_GlossyReflections", propertyList, false);
FindAndRemoveProperty("_ALPHATEST", propertyList, false);
FindAndRemoveProperty("_ALPHABLEND", propertyList, false);
FindAndRemoveProperty("_JL_RenderType", propertyList, false);
FindAndRemoveProperty("_JL_ShowFaceType", propertyList, false);
FindAndRemoveProperty("_Cull", propertyList, false);
FindAndRemoveProperty("_ZWrite", propertyList, false);
FindAndRemoveProperty("_SrcBlend", propertyList, false);
FindAndRemoveProperty("_DstBlend", propertyList, false);
// jave.lin : 根据变体开关来控制 材质属性的显示隐藏
var alphatest_on = IsEnabledKW("_ALPHATEST_ON", targetMat);
var emission_on = IsEnabledKW("_EMISSION", targetMat);
//var sss_on = IsEnabledKW("_SSS_ON", targetMat);
if (!alphatest_on)
{
FindAndRemoveProperty("_Cutoff", propertyList, false);
}
if (!emission_on)
{
FindAndRemoveProperty("_EmissionColor", propertyList, false);
FindAndRemoveProperty("_EmissionMap", propertyList, false);
}
//if (!sss_on)
//{
// FindAndRemoveProperty("_TranslucentDistortion", propertyList, false);
// FindAndRemoveProperty("_TranslucentPower", propertyList, false);
// FindAndRemoveProperty("_TranslucentScale", propertyList, false);
// FindAndRemoveProperty("_TranslucentAmbientScale", propertyList, false);
//}
//var srcRenderType = renderTypeProp.floatValue;
//materialEditor.ShaderProperty(renderTypeProp, "RenderType");
//var newRenderType = renderTypeProp.floatValue;
//if (srcRenderType != newRenderType)
//{
// renderTypeProp.floatValue = (int)newRenderType;
// materialEditor.RegisterPropertyChangeUndo("renderType");
// materialEditor.PropertiesChanged();
//}
// jave.lin : render type
{
var src_val = (JAVELIN_RenderType)((int)renderTypeProp.floatValue);
var new_val = (JAVELIN_RenderType)EditorGUILayout.EnumPopup("RenderType", src_val, GUILayout.ExpandWidth(true));
if (src_val != new_val)
{
renderTypeProp.floatValue = (int)new_val;
SettingMatBlendMode(targetMat, new_val);
}
}
// jave.lin : show face type
{
var src_val = (JAVELIN_ShowFaceType)((int)showFaceTypeProp.floatValue);
var new_val = (JAVELIN_ShowFaceType)EditorGUILayout.EnumPopup("ShowFaceType", src_val, GUILayout.ExpandWidth(true));
if (src_val != new_val)
{
showFaceTypeProp.floatValue = (int)new_val;
SettingMatShowFaceType(targetMat, new_val);
}
}
if (propertyList.Count > 0)
{
for (int i = 0; i < propertyList.Count; i++)
{
materialEditor.ShaderProperty(propertyList[i], propertyList[i].displayName);
}
}
materialEditor.RenderQueueField();
}
}
注意
版权声明:本文为linjf520原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。