112 lines
4.8 KiB
C#
112 lines
4.8 KiB
C#
using UnityEngine;
|
||
|
||
/// <summary>
|
||
/// 材质渲染模式助手类
|
||
/// 用于设置材质的正确渲染模式以支持透明度
|
||
/// </summary>
|
||
public static class MaterialRenderModeHelper
|
||
{
|
||
public enum BlendMode
|
||
{
|
||
Opaque,
|
||
Cutout,
|
||
Fade, // Traditional transparency (ZWrite OFF)
|
||
Transparent, // Physically based transparency (ZWrite OFF)
|
||
AlphaBlendWithDepth // Alpha blend with depth write (ZWrite ON) - 解决Body显示问题
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置材质的渲染模式
|
||
/// </summary>
|
||
/// <param name="material">要设置的材质</param>
|
||
/// <param name="blendMode">渲染模式</param>
|
||
public static void SetMaterialRenderMode(Material material, BlendMode blendMode)
|
||
{
|
||
switch (blendMode)
|
||
{
|
||
case BlendMode.Opaque:
|
||
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.renderQueue = -1;
|
||
break;
|
||
case BlendMode.Cutout:
|
||
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.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
|
||
break;
|
||
case BlendMode.Fade:
|
||
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.EnableKeyword("_ALPHABLEND_ON");
|
||
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
|
||
break;
|
||
case BlendMode.Transparent:
|
||
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.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
|
||
break;
|
||
case BlendMode.AlphaBlendWithDepth:
|
||
// 关键修复:保持深度写入的透明混合模式
|
||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||
material.SetInt("_ZWrite", 1); // 保持深度写入,这样Body即使单独存在也能正确显示
|
||
material.DisableKeyword("_ALPHATEST_ON");
|
||
material.EnableKeyword("_ALPHABLEND_ON");
|
||
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||
// 使用较早的渲染队列,确保在其他透明物体之前渲染
|
||
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry + 450;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 自动检测并设置合适的渲染模式
|
||
/// </summary>
|
||
/// <param name="material">材质</param>
|
||
/// <param name="alpha">透明度值</param>
|
||
public static void AutoSetRenderMode(Material material, float alpha)
|
||
{
|
||
if (alpha >= 1.0f)
|
||
{
|
||
SetMaterialRenderMode(material, BlendMode.Opaque);
|
||
}
|
||
else
|
||
{
|
||
SetMaterialRenderMode(material, BlendMode.AlphaBlendWithDepth);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 专门为Body设置渲染模式
|
||
/// 确保Body在单独显示时也能正确显示
|
||
/// </summary>
|
||
/// <param name="material">Body材质</param>
|
||
/// <param name="alpha">透明度值</param>
|
||
public static void SetBodyRenderMode(Material material, float alpha)
|
||
{
|
||
if (alpha >= 1.0f)
|
||
{
|
||
SetMaterialRenderMode(material, BlendMode.Opaque);
|
||
}
|
||
else
|
||
{
|
||
// 对于Body,始终使用保持深度写入的透明模式
|
||
SetMaterialRenderMode(material, BlendMode.AlphaBlendWithDepth);
|
||
}
|
||
}
|
||
} |