千家信息网

怎么利用Stencil来优化局部后处理特效

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章将为大家详细讲解有关怎么利用Stencil来优化局部后处理特效,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。只是例子就不要再和我说什么十字片,
千家信息网最后更新 2026年11月04日怎么利用Stencil来优化局部后处理特效

这篇文章将为大家详细讲解有关怎么利用Stencil来优化局部后处理特效,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

只是例子就不要再和我说什么十字片,广告牌叠加了。这个效果的实现就是用纯色在RT上重绘原模型给一次高斯模糊后叠回原图。

加了Stencil后计算量下降了一半(为方便对比,我砍掉了后处理流程最后的原图Blit流程和人物绘制部分,仅显示了downsample和高斯模糊的量)

原理:

Stencil和ZTest就如同两兄弟,非常相似,但前者却常常被忽略。大家都知道,在拥有Early-Z(准确的说是Early-ZS,也就是Z+Stencil)机制的当代GPU里,我们可以通过由前向后绘制,通过ZTest让被遮挡的物体免于绘制,这是一个最基本的fillrate优化手段。

Stencil本身是一个比较+改写特定Buff的技术,和ZTest的比较深度+改写深度其实是一样的机制,只是拥有更多的变化。所以它也可以通过先改写Buff,然后让后面的物体在读取这个Buff的时候检测不通过,从而直接跳过像素计算阶段。

局部物体使用后处理特效很不合算,就是因为即使只有局部需要计算,GPU也必须计算整个屏幕。如果先用Stencil在屏幕上绘制一个标记区域,就可以将后面的计算限定在小范围内。

用的是一个简单的法线延伸OutLine,扩大了棒子的体积。并在绘制过的地方标记Stencil为1

Pass{        CULL OFF        ZTest OFF        COLORMASK 0        Stencil        {                Ref 1                Comp NotEqual                Pass Replace                ReadMask 1                WriteMask 1        }        CGPROGRAM        #pragma vertex vert        #pragma fragment frag                                #include "UnityCG.cginc"        struct appdata        {                float4 vertex : POSITION;                float3 normal : NORMAL;        };        struct v2f        {                float4 vertex : SV_POSITION;        };        float _Outline;        v2f vert (appdata v)        {                v2f o;                o.vertex = UnityObjectToClipPos(v.vertex);                float3 norm = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);                  float2 offset = TransformViewToProjection(norm.xy);                  o.vertex.xy += normalize(offset) * o.vertex.z * _Outline;                  UNITY_TRANSFER_FOG(o,o.vertex);                return o;        }        fixed4 frag (v2f i) : SV_Target        {                return 1;        }        ENDCG}

然后再在之后的后处理流程里,给需要的Pass加上

Stencil{        Ref 1        Comp Equal        Pass Keep        ReadMask 1        WriteMask 1}

即可。

不过……

1. Stencil只能通过绘制实体来写入,不能在多张Buff间复制。所以一旦经过downsample就会丢失,而downsample是后处理中非常常见的。

2. 由于这个原因,RT绘制的顺序也非常重要,只有作为绘制目标的RT才有获得Stencil检测的机会。

3.Stencil在其他RT中的利用,只能通过Graphics.SetRenderTarget(source.colorBuffer, stencil.depthBuffer)来完成,指向一张RT的颜色Buffer,却同时指向另一张RT的depthBuff,且这两张RT的分辨率必须完全一样。

具体代码(普通的Blit是没法用的,会强制切换RenderTarget):

private void DepthBlit(RenderTexture source, RenderTexture destination, Material mat, int pass, RenderTexture depth){            if (depth == null)            {                Graphics.Blit(source, destination, mat, pass);                return;            }            Graphics.SetRenderTarget(destination.colorBuffer, depth.depthBuffer);            GL.PushMatrix();            GL.LoadOrtho();            mat.mainTexture = source;            mat.SetPass(pass);            GL.Begin(GL.QUADS);            GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);            GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);            GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);            GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);            GL.End();            GL.PopMatrix();}

纹理大小限制是最麻烦的,其它都还好。实际用法就是,保留保存着Stencil的那张RT,然后在需要的时候挂接在目标RT上。

绘制标记是有代价的,但也可以在绘制正常画面时顺带绘制,这样代价就小很多。

在可以用到的时候记得使用即可。

好吧,我知道你们可能会问Bloom本身具体是怎么做的。Bloom本身Unity内置后处理有一个,但是是全屏的。想做到局部,确实只能单开一张RT来绘制要泛光的物体。

但这就涉及到保留深度缓冲的问题,否则那个物体就必须显示在最前面而无法被障碍物遮挡。因为同时还要切换RT绘制,唯一的办法就是刚才的Graphics.SetRenderTarget(source.colorBuffer, stencil.depthBuffer),绘制新RT,同时使用以前的深度缓冲区。

我为了图简单,是直接在后处理阶段里切换RenderTarget,然后用Graphics.DrawMeshNow来绘制要泛光的物体的,这会导致Mesh无法Batch。想要Batch,必须让摄像机来绘制这些物体,应该是必须用到CommandBuffer这些东西。

关于怎么利用Stencil来优化局部后处理特效就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

处理 物体 局部 就是 深度 特效 同时 时候 更多 标记 流程 切换 代价 内容 原图 只是 只有 可以通过 屏幕 指向 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技名片 广州为想互联网科技有限公司 中国互联网科技工作委员会毛军 互联网科技社 互联网最新的科技有限公司 互联网科技的英文 深圳天众互联网科技公司 四川狮子座互联网科技 国外互联网科技网站 互联网科技股午盘股票涨跌 安控科技rtu产品工业互联网 深圳前海聚择互联网科技有限公司 浙江互联网科技研学营 华夏互联网科技业 南京一网一红互联网科技有限公司 陕西九四连强互联网科技有限公司 北京天晋互联网科技有限公司 科技和互联网行业的特点 华人运通互联网科技公司 科技互联网专业务虚会材料 互联网加科技 互联网和科技创新 盈实互联网科技 互联网科技的发展 中国航天科技大学国际工业互联网 中国科技创新与世界互联网大会 允成互联网科技有限公司融资 徐州市互联网科技有限公司 梅州GM互联网络科技有限公司 郑州欣桑互联网科技有限公司
0