DCS/ruiyiweiUX/Assets/Scripts/Components/MaterialRenderModeHelper.cs

112 lines
4.8 KiB
C#
Raw Normal View History

2026-06-09 13:59:11 +08:00
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);
}
}
}