• 用于精确控制像素丢弃的逐片元操作,通过模板缓冲区(8位整数/像素)实现复杂遮罩效果。
  • 支持8种比较函数和6种缓冲操作‌
  • 当前模版操作,只能在Shader文件中书写操作,ShaderGraph中无法直接使用模版指令。

【从UnityURP开始探索游戏渲染】专栏-直达

核心配置预览

  • 核心配置所有配置列出(非全必要):
Stencil {
Ref 2 // 必要模版数值
ReadMask 255
WriteMask 255
Comp Greater // 必要比较操作符
Pass Replace // 必要通过后的操作
Fail Keep
ZFail DecrSat
}

1. 核心配置命令

  • Ref:设置参考值(0-255整数),用于与模板缓冲区比较
  • ReadMask:读取掩码(0-255),按位与操作后比较(默认255)
  • WriteMask:写入掩码(0-255),控制可修改的缓冲区位(默认255)

2. 比较函数命令

Comp支持以下枚举值:

  • Always/Never:始终通过/拒绝
  • Less/Greater:小于/大于时通过
  • Equal/NotEqual:等于/不等于时通过
  • LessEqual/GreaterEqual:小于等于/大于等于时通过

3. 操作命令

Pass/Fail/ZFail支持的操作:

  • Keep:保持原值
  • Zero:置零
  • Replace:用Ref值替换
  • IncrSat/DecrSat:饱和增减(0/255边界)
  • IncrWrap/DecrWrap:循环增减
  • Invert:按位取反

模板测试具体过程‌

  1. 缓冲区初始化

    • 清除模板缓冲:GL.Clear(ClearBufferMask.StencilBufferBit)
    • 设置初始值:GL.StencilMask(0xFF)(默认全255)
  2. 测试阶段-逐片元

    plaintext
    if (片元模板值 [比较函数] 参考值) {
    执行通过操作(如保留像素)
    } else {
    执行失败操作(如丢弃像素)
    }
  3. 缓冲更新

    • 根据测试结果修改模板缓冲值(可选)

‌比较函数(StencilFunc)‌

函数 含义 OpenGL常量
Never 永远不通过 GL_NEVER
Always 永远通过 GL_ALWAYS
Less 模板值 < 参考值 GL_LESS
LEqual 模板值 ≤ 参考值 GL_LEQUAL
Greater 模板值 > 参考值 GL_GREATER
GEqual 模板值 ≥ 参考值 GL_GEQUAL
Equal 模板值 == 参考值 GL_EQUAL
NotEqual 模板值 != 参考值 GL_NOTEQUAL

‌缓冲操作(StencilOp)‌

操作组合 含义
Keep 保持当前模板值不变(默认)
Zero 将模板值设为0
Replace 用参考值替换模板值
Incr/IncrWrap 模板值+1(超过255时,前者截断后者循环)
Decr/DecrWrap 模板值-1(低于0时,前者截断后者循环)
Invert 按位取反(~操作)

示例1

  • 遮罩区域shader
Shader "Custom/StencilMask" {
SubShader {
Tags { "Queue"="Geometry-1" } // 优先渲染
ColorMask 0 // 不写入颜色
ZWrite Off Stencil {
Ref 1
Comp Always
Pass Replace // 将模板值设为1
}
Pass {} // 空Pass仅用于写入模板
}
}
  • 物体模版测试shader,该Shader仅在模板值为1的区域内渲染物体。
Shader "Custom/StencilObject" {
SubShader {
Stencil {
Ref 1
Comp Equal // 仅渲染模板值=1的区域
Pass Keep
}
Pass {
// 正常着色代码...
}
}
}

示例2 外轮廓描边

Shader "Custom/StencilOutline" {
Properties {
_MainTex ("Base Texture", 2D) = "white" {}
_OutlineColor ("Outline Color", Color) = (1,0,0,1)
_OutlineWidth ("Outline Width", Range(0, 0.1)) = 0.05
} SubShader {
Tags {
"RenderPipeline"="UniversalRenderPipeline"
"RenderType"="Opaque"
} // Pass 1: 正常渲染角色并写入模板
Pass {
Name "Character"
Tags
{
"LightMode" = "UniversalForward"
}
Stencil {
Ref 1
Comp Always
Pass Replace
ZFail Keep
} HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes {
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
}; struct Varyings {
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
}; TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex); Varyings vert(Attributes IN) {
Varyings OUT;
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = IN.uv;
return OUT;
} half4 frag(Varyings IN) : SV_Target {
return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
}
ENDHLSL
} // Pass 2: 渲染轮廓
Pass {
Name "Outline"
Cull Front
Stencil {
Ref 1
Comp NotEqual
Pass Keep
} HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" struct Attributes {
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
}; struct Varyings {
float4 positionCS : SV_POSITION;
}; CBUFFER_START(UnityPerMaterial)
float4 _OutlineColor;
float _OutlineWidth;
CBUFFER_END Varyings vert(Attributes IN) {
Varyings OUT;
float3 posWS = TransformObjectToWorld(IN.positionOS.xyz * (1 + _OutlineWidth));
float3 normalWS = TransformObjectToWorldNormal(IN.normalOS);
// posWS += normalWS * _OutlineWidth; // 沿法线方向扩展
OUT.positionCS = TransformWorldToHClip(posWS);
return OUT;
} half4 frag(Varyings IN) : SV_Target {
return _OutlineColor;
}
ENDHLSL
}
}
}

【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,)

【渲染流水线】[逐片元阶段]-[模版测试]以UnityURP为例的更多相关文章

  1. Shader 入门笔记(二) CPU和GPU之间的通信,渲染流水线

    渲染流水线 1)应用阶段(CPU处理) 首先,准备好场景数据(摄像机位置,视锥体,模型和光源等) 接着,做粗粒度剔除工作. 最后,设置好每个模型的渲染状态(使用的材质,纹理,shader等) 这一阶段 ...

  2. Unity Shader 之 渲染流水线

    Unity Shader 之渲染流水线 什么是渲染流水线 一个渲染流程分成3个步骤: 应用阶段(Application stage) 几何阶段(Geometry stage) 光栅化阶段(Raster ...

  3. GPU渲染流水线的简单概括

    GPU流水线 主要分为两个阶段:几何阶段和光栅化阶段   几何阶段      顶点着色器 --> 曲面细分着色器(可选)----->几何着色器(可选)----->裁剪-->屏幕 ...

  4. 《UnityShader入门精要》学习笔记之渲染流水线

    第一种分类方式: 图形管道(如下7步): 顶点数据 : 由3D模型传递的三角形网格 顶点着色 : 编写CG程序对各个顶点进行着色 生成几何图元 : 连接特定的顶点生成几何图元,例如连接三个顶点生成一个 ...

  5. Unity Shader入门精要学习笔记 - 第2章 渲染流水线

    来源作者:candycat   http://blog.csdn.net/candycat1992/article/ 2.1 综述 渲染流水线的最终目的在于生成或者说是渲染一张二维纹理,即我们在电脑屏 ...

  6. Unity 渲染流水线 :CPU与GPU合作创造的艺术wfd

    前言 对于Unity渲染流程的理解可以帮助我们更好对Unity场景进行性能消耗的分析,进而更好的提升场景渲染的效率,最后提升游戏整体的性能表现 Unity的游戏画面的最终的呈现是由CPU与GPU相互配 ...

  7. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第五章:渲染流水线

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第五章:渲染流水线 学习目标 了解几个用以表达真实场景的标志和2D图像 ...

  8. Unity3D Shader Stencil模版测试学习

    官方文档地址: https://docs.unity3d.com/Manual/SL-Stencil.html 参考博客: http://blog.csdn.net/onafioo/article/d ...

  9. [Unity Shader] 逐顶点光照和逐片元漫反射光照

    书中的6.4节讲的是漫反射的逐顶点光照和逐片元光照. 前一种算法是根据漫反射公式计算顶点颜色(顶点着色器),对颜色插值(光栅化过程)返回每个像素的颜色值(片元着色器). 第二种算法是获得顶点的法线(顶 ...

  10. 移动端 像素渲染流水线与GPU Hack

    什么是 像素渲染流水线 web页面你所写的页面代码是如何被转换成屏幕上显示的像素的.这个转换过程可以归纳为这样的一个流水线,包含五个关键步骤: 1.JavaScript:一般来说,我们会使用JavaS ...

随机推荐

  1. 【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit(5)

    1.问题描述: 集成华为一键登录的LoginWithHuaweiIDButton, 但是Button默认名字叫 "华为账号一键登录",太长无法显示,能否简写成"一键登录& ...

  2. Vue 学习笔记 [Part 1]

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 最近项目上需要用到Vue,又重新学习了一遍.期望10天左右完全掌握并能用于生产吧. 好记性不如烂笔头 目录 一. 邂逅Vuejs 1.1. 认识Vu ...

  3. Mysql 一些函数的使用

    Mysql 一些函数的使用 if函数 SELECT IF(500<1000, "YES", "NO"); SELECT IF(500<1000,1, ...

  4. 开源DeepWiki 企业老项目救星:自动生成文档+AI问答,告别遗留代码维护噩梦

    企业痛点一击即中 你是否还在为这些问题头疼: 核心业务系统缺乏文档,新人上手困难 老员工离职带走关键代码知识 系统升级维护成本居高不下 业务逻辑复杂,代码理解困难 OpenDeepWiki最新版本专为 ...

  5. 层次分析法的Python实现--数学建模学习日志

    数学建模比赛即将到来,大家应该都投身于学习当中了,b站上比较热门的一个课程是 b站数学建模学习视频 在这里讲解了数学建模常见的方法和写论文的要点,同时up主贴心地有所有方法的源码实现,但是全部都是ma ...

  6. C# 遍历Enum( 枚举)

    Type enumType = typeof(Domain.Models.Entitys.PermissionEntity.PermissionTypeEnum);                   ...

  7. 一款开源免费、通用的 WPF 主题控件包

    前言 今天大姚给大家分享一款开源免费(MIT License).通用的 WPF 主题控件包:Rubyer WPF. WPF介绍 WPF是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 Wind ...

  8. Spring AI 对话记忆大揭秘:服务器重启,聊天记录不再丢失!

    还在为 Spring AI 应用重启后对话上下文丢失而烦恼吗?本文将带你深入 Spring AI 的对话记忆机制,并手把手教你实现一个基于文件的持久化方案,让你的 AI 应用拥有 "过目不忘 ...

  9. qt 显示中文

    参考链接 CSDN Tips 直接使用第三种方法 也可以使用 QString::fromLocal8Bit("打开文档文件") 这种方式

  10. iga 入门之 总体合成

    简介 摘自 流体力学数值方法 概括地说,总体合成就是将所有单元的\(A_{ij}^{(e)}.f_i^{(e)}\)进行累加,最终形成\(A_{nm}.f_n\),从而产生总体有限元方程 \[A_{n ...