OpenGL逐片元操作:像素所有权测试,裁剪测试,透明度测试,模板测试,深度测试,深度写入,混合
使用模板缓冲区, 每帧开始时所有像素对应的缓冲区的value 为 0。
使用模板测试做效果,一般三部分组成,
mask(用平面在Stencil缓冲写入), 外框(可有可无,默认的Stencil设置),模板测试模型(只有与之前写入的Stencil value 相同 才能显示)。
Stencil {
Ref [ _StencilRefValue ] / 0 / 1 …
ReadMask
WriteMask
Comp Always 总是通过
/ Never 都不通过抛弃片元/ Greater/ GEqual / Less/ LEqual / Equal / NotEqual
Pass Keep
/ Zero/ Replace 使用ref值填充/ Invert 按位取反
/ Incrsat 自加上限255/ Decrsat 自减下限0
/ IncrWrap 自加255+1->0 / DecrWarp 自减 0-1->255
Fail
Zfail
}
Shader "may/stencil write"
{
Properties
{
_StencilRefValue ("Stencil Ref Value", Int) = 1
}
SubShader
{
Tags { "Queue" = "Geometry + 1" "RenderType"="Opaque" }
LOD 100
Pass
{
Tags {"LightMode" = "ForwardBase"}
ColorMask 0
ZWrite Off
stencil
{
Ref [_StencilRefValue]
Comp Always
Pass Replace
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 vert (float4 vertex :POSITION):SV_POSITION
{
return UnityObjectToClipPos(vertex);
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(1, 1, 1, 1);
}
ENDCG
}
}
}
Shader "may/Stencil Model"
{
Properties
{
[Header(Stencil)]
_StencilRefValue ("Stencil Ref Value", Int) = 1
[Enum(UnityEngine.Rendering.CompareFunction)]_StencilCompFunc ("Stencil Compare Function", Float) = 8
[Header(Diffuse)]
_BaseColor ("Base Color", 2D) = "white" {}
_ColorTint("Color Tint", Color) = (1,1,1,1)
}
SubShader
{
Tags {"Queue" = "Geometry + 2" "RenderType"="Opaque" }
LOD 100
pass
{
Name "UseStencil"
Tags { "LightMode" = "ForwardBase" }
Stencil
{
Ref [_StencilRefValue]
Comp [_StencilCompFunc]
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
sampler2D _BaseColor;
float4 _BaseColor_ST;
fixed4 _ColorTint;
struct a2v
{
float4 vertex :POSITION;
float2 uv :TEXCOORD0;
fixed3 normalMS :NORMAL;
};
struct v2f
{
float4 pos :SV_POSITION;
float2 uv :TEXCOORD0;
float4 posWS :TEXCOORD3;
SHADOW_COORDS(1)
half3 normalWS :TEXCOORD2;
};
v2f vert (a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.posWS = mul(unity_ObjectToWorld, v.vertex);
o.normalWS = UnityObjectToWorldNormal(v.normalMS);
o.uv = TRANSFORM_TEX(v.uv, _BaseColor);
UNITY_TRANSFER_FOG(o,o.vertex);
TRANSFER_SHADOW(o);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 normalWS= normalize(i.normalWS);
fixed3 lightDirWS = normalize( UnityWorldSpaceLightDir(i.posWS) );
fixed3 viewDirWS = normalize( UnityWorldSpaceViewDir(i.posWS) );
// diffuse
fixed4 albedo = _ColorTint * tex2D(_BaseColor, i.uv);
fixed Lambert = max(0, dot(lightDirWS, normalWS));
fixed3 diffuseColor = albedo * _LightColor0.rgb * Lambert;
UNITY_LIGHT_ATTENUATION(atten, i, i.posWS)
return fixed4(diffuseColor * atten, 1);
}
ENDCG
}
}
}
Stencil Model Material