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

如何让模板缓冲仅在网格绘制区域生成遮罩?

问题描述

我尝试用模板缓冲(Stencil Buffer)给Sprite添加遮罩,未开启透明效果时功能正常,但添加透明后,遮罩会作用于整个纹理——我希望它仅在Quad网格的绘制区域生效。

(注:黑色Sprite是需要被遮罩的对象,能看到作为遮罩的Quad没有对纹理的透明区域进行遮罩,我只把Unity默认Quad网格传入了Mesh Filter。)

请问这是正常行为吗?有没有办法让遮罩仅在Quad的绘制区域生效?

遮罩Shader原代码

Tags { "RenderType" = "Transparent" }
    
Pass
{
    Stencil
    {
        Ref 1
        Comp Always
        Pass Replace
    }

    ColorMask 0 // Don't write to any colour channels
    ZWrite Off // Don't write to the Depth buffer
}

遮罩交互Shader原代码

Tags
{
    "RenderType" = "Transparent"
    "Queue" = "Transparent"
}

Pass
{
    Name "Sprite Lit"
    Tags
    {
        "LightMode" = "Universal2D"
    }

// Render State
Stencil
{
    Ref 1
    Comp Equal
}

Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
Cull Off
ZTest LEqual
ZWrite Off
}
解决方案

这是正常现象——你的遮罩Shader没有过滤透明像素,导致Quad的整个矩形区域都写入了模板缓冲,包括透明部分,所以Sprite的透明区域也会被遮罩规则影响。要让遮罩只作用于Quad的实际绘制区域,需要给遮罩Shader加上Alpha过滤逻辑。

修改后的遮罩Shader(Alpha测试版本)

Tags { "RenderType" = "TransparentCutout" }

Pass
{
    Stencil
    {
        Ref 1
        Comp Always
        Pass Replace
    }

    ColorMask 0 // 不写入任何颜色通道
    ZWrite Off // 不写入深度缓冲
    AlphaTest Greater 0.5 // 只保留Alpha值大于0.5的像素,透明部分不会写入模板缓冲
}

关键改动说明

  • 把RenderType改成TransparentCutout,对应带Alpha裁剪的渲染类型,让管线正确处理透明过滤
  • 添加AlphaTest Greater 0.5指令:只有Alpha值超过阈值的像素才会执行模板缓冲的写入,Quad的透明区域就不会在模板缓冲中留下标记

如果用的是URP 2D管线,也可以用更现代的AlphaToMask替代AlphaTest,效果一致:

Tags { "RenderType" = "TransparentCutout" }

Pass
{
    Stencil
    {
        Ref 1
        Comp Always
        Pass Replace
    }

    ColorMask 0
    ZWrite Off
    AlphaToMask On // 启用Alpha转遮罩,自动过滤透明像素
}

修改后,遮罩就只会在Quad的非透明绘制区域生效,Sprite的透明部分不会再被错误遮罩。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:18:27