You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity3D运行时如何更改Cut-Out Shader的Alpha遮罩

解决Unity运行时Cut-Out Shader漫反射Alpha修改问题

核心思路

Unity默认Cut-Out Shader通过_MainTex的Alpha通道结合_Cutoff阈值实现像素裁剪。要实现衣物遮挡区域的皮肤隐藏,核心是在运行时为身体材质的漫反射纹理替换对应遮罩的Alpha通道,或使用自定义Shader单独传入Alpha遮罩。


方案一:修改原漫反射纹理的Alpha通道(适配内置Standard Cutout Shader)

步骤1:准备遮罩资源

  • 为每件衣物制作对应身体部位的Alpha遮罩贴图:尺寸与身体原漫反射纹理一致,需要隐藏的区域Alpha设为0,显示区域设为1。
  • 贴图导入设置:Texture Type设为Default,Alpha Source选择From Texture(若遮罩是灰度图则选From Gray Scale),确保Alpha通道生效。

步骤2:运行时代码实现

using UnityEngine;

public class BodyMaskController : MonoBehaviour
{
    private SkinnedMeshRenderer _bodyRenderer;

    void Awake()
    {
        _bodyRenderer = GetComponent<SkinnedMeshRenderer>();
    }

    // 切换衣物时调用此方法,传入对应遮罩贴图路径
    public void ApplyBodyMask(string maskPath)
    {
        // 销毁旧材质实例,避免内存泄漏
        if (_bodyRenderer.material != null)
        {
            Destroy(_bodyRenderer.material);
        }

        // 实例化材质副本(不修改共享材质,避免影响其他对象)
        Material bodyMat = new Material(_bodyRenderer.material);
        _bodyRenderer.material = bodyMat;

        // 加载遮罩贴图
        Texture2D alphaMask = Resources.Load<Texture2D>(maskPath);
        if (alphaMask == null)
        {
            Debug.LogError("遮罩贴图加载失败:" + maskPath);
            return;
        }

        // 获取原漫反射纹理
        Texture2D originalMainTex = bodyMat.GetTexture("_MainTex") as Texture2D;
        if (originalMainTex == null)
        {
            Debug.LogError("未找到漫反射纹理_MainTex");
            return;
        }

        // 合并原纹理RGB与遮罩Alpha
        Texture2D newMainTex = new Texture2D(originalMainTex.width, originalMainTex.height);
        Color[] originalColors = originalMainTex.GetPixels();
        Color[] maskColors = alphaMask.GetPixels();

        for (int i = 0; i < originalColors.Length; i++)
        {
            // 若遮罩是灰度图,用R通道作为Alpha;若带Alpha则直接用maskColors[i].a
            originalColors[i].a = maskColors[i].r;
        }

        newMainTex.SetPixels(originalColors);
        newMainTex.Apply();

        // 赋值给材质并设置裁剪阈值
        bodyMat.SetTexture("_MainTex", newMainTex);
        bodyMat.SetFloat("_Cutoff", 0.5f); // 低于此值的Alpha像素会被裁剪
    }
}

方案二:自定义Cutout Shader(更高效,无需修改原纹理)

如果不想每次合并纹理,可自定义支持单独Alpha遮罩的Shader,直接传入遮罩贴图控制裁剪:

自定义Shader示例(内置渲染管线)

Shader "Custom/BodyCutoutWithMask"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _AlphaMask ("Alpha Mask", 2D) = "white" {}
        _Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
    }

    SubShader
    {
        Tags { "RenderType"="TransparentCutout" "Queue"="AlphaTest" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard alphatest:_Cutoff

        sampler2D _MainTex;
        sampler2D _AlphaMask;
        half _Metallic;
        half _Glossiness;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_AlphaMask;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            fixed maskAlpha = tex2D(_AlphaMask, IN.uv_AlphaMask).r;
            
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = maskAlpha; // 用遮罩控制Alpha裁剪
        }
        ENDCG
    }
    FallBack "Standard"
}

运行时代码简化版

public void ApplyBodyMask(string maskPath)
{
    if (_bodyRenderer.material != null)
    {
        Destroy(_bodyRenderer.material);
    }

    Material bodyMat = new Material(_bodyRenderer.material);
    _bodyRenderer.material = bodyMat;

    Texture2D alphaMask = Resources.Load<Texture2D>(maskPath);
    if (alphaMask == null)
    {
        Debug.LogError("遮罩贴图加载失败:" + maskPath);
        return;
    }

    bodyMat.SetTexture("_AlphaMask", alphaMask);
    bodyMat.SetFloat("_Cutoff", 0.5f);
}

注意事项

  • 材质实例化:必须创建材质副本,直接修改共享材质会影响所有使用该材质的对象。
  • 内存管理:切换遮罩时销毁旧材质实例,避免内存泄漏。
  • UV匹配:遮罩贴图的UV需与原漫反射纹理完全一致,否则遮罩会错位。
  • URP/HDRP适配:若使用SRP,只需替换对应的基础Shader模板,参数逻辑保持一致。

内容的提问来源于stack exchange,提问作者Owen Alexander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:22:40