模版缓冲(stencil buffer)或印模缓冲,是在OpenGL三维绘图等计算机图像硬件中常见的除颜色缓冲、像素缓冲、深度缓冲之外另一种数据缓冲。词源模版(stencil)是指一种印刷技术,通常以蜡纸或者钢板印刷文字或图形;区别于模板(template),用木板为外形修剪的依据来复制形状;模版(stencil)是指印模,而模板(template)主要是指形模。模版缓冲是以像素为单位的,整数数值的缓冲,通常给每个像素分配一个字节长度的数值。深度缓冲与模版缓冲经常在图形硬件的随机存取内存(RAM)中分享相同的区域。
模板缓冲所在的是整个流水线的最后一个阶段,这个阶段的流水线如下
最简单的情况,模版缓冲被用于限制渲染的区域。更多高级应用会利用深度缓冲与模版缓冲的在图形渲染流水线中的强关联关系。例如,模版的数值可以按每个像素是否通过深度测试来自动增加或减少。
简单组合使用深度测试与模版修饰符可以使得大量的本来需要多次渲染过程的效果(例如阴影、外形的绘制或复合几何图元(Geometric primitive)的交叉部分的高光处理)可以简单实现,因此减轻了图形硬件的负担。
最典型的应用是给三维图像加阴影。也用于平面反射。
其它渲染的技术,例如,视口渲染(portal rendering),利用模版缓冲作其它用途。例如,它可以被用于查找被视口遮蔽的屏幕区域然后重新正确渲染这些像素点。
模版缓冲与其修饰符可以通过OpenGL或Direct3D的应用程序编程接口(API)来访问。
Greater | Only render pixels whose reference value is greater than the value in the buffer. |
GEqual | Only render pixels whose reference value is greater than or equal to the value in the buffer. |
Less | Only render pixels whose reference value is less than the value in the buffer. |
LEqual | Only render pixels whose reference value is less than or equal to the value in the buffer. |
Equal | Only render pixels whose reference value equals the value in the buffer. |
NotEqual | Only render pixels whose reference value differs from the value in the buffer. |
Always | Make the stencil test always pass. |
Never | Make the stencil test always fail. |
Keep | Keep the current contents of the buffer. |
Zero | Write 0 into the buffer. |
Replace | Write the reference value into the buffer. |
IncrSat | Increment the current value in the buffer. If the value is 255 already, it stays at 255. |
DecrSat | Decrement the current value in the buffer. If the value is 0 already, it stays at 0. |
Invert | Negate all the bits. |
IncrWrap | Increment the current value in the buffer. If the value is 255 already, it becomes 0. |
DecrWrap | Decrement the current value in the buffer. If the value is 0 already, it becomes 255. |
Shader "Custom/RedStencil" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry"} Pass { Stencil { Ref 2 Comp always Pass replace ZFail decrWrap } CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; } half4 frag(v2f i) : SV_Target { return half4(1,0,0,1); } ENDCG } } }
Shader "Custom/GreenStencil" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Geometry+1"} Pass { Stencil { Ref 2 Comp equal Pass keep Fail decrWrap ZFail IncrSat } CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; } half4 frag(v2f i) : SV_Target { return half4(0,1,0,1); } ENDCG } } FallBack "Diffuse" }
Shader "Custom/BlueStencil" { SubShader { Tags { "RenderType"="Opaque" "Queue"="Overlay"} Pass { Stencil { Ref 3 Comp Equal } CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert(appdata v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); return o; } half4 frag(v2f i) : SV_Target { return half4(0,0,1,1); } ENDCG } } }
原文地址:http://blog.csdn.net/silangquan/article/details/46608915