ShaderForge-遮罩效果
发表于2018-07-11
下面跟大家介绍的是遮罩效果的实现,在介绍之前,首先来了解下遮罩效果的实现原理。
遮罩效果
原理
最简单的方法就是制作一张带有预期的透明度值的遮罩图,我们依据遮罩图的透明度值来设置原图的透明度,就得到了遮罩效果。
透明度实现方式
在unity中实现透明度效果有两种方案,一种是透明度测试,一种是透明度混合。
- 透明度测试实现方式:既是片元的透明度和透明度阈值进行比较,小于这个透明度阈值的片元会直接被舍弃掉,不会做任何处理,相当于该片元透明。而大于这个透明度阈值的则会按照不透明的方式进行处理。
- 透明度混合实现方式:既是片元的透明度作为混合因子,片元的深度和深度缓冲区中的深度做比较,小于深度缓冲区中的深度时,片元的透明度不会与颜色缓冲区中的颜色进行混合,否则就会进行混合,最终片元的颜色会替换到颜色缓冲区中的颜色。
制作遮罩图
ShaderForge实现
手写unity shader实现
透明度测试
Shader "Custom/mask_u" { Properties { _MainTex ("Texture", 2D) = "white" {} _MaskTex("Mask Texture", 2D) = "white" {} } SubShader { // 所有Pass中渲染队列使用透明度测试队列,渲染类型选择透明度测试类型,并且渲染过程中不受投影器的影响 Tags{ "Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout" } LOD 100 Pass { Tags{ "LightModel" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _MaskTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); fixed4 mask_col = tex2D(_MaskTex, i.uv); // 进行透明度测试,小于透明度阈值的片元将会被舍弃,等价于 if ((mask_col.a - 0.5)) < 0.0) discard; 0.5是默认的透明度阈值 clip(mask_col.a - 0.5); return col; } ENDCG } } }
透明度混合
Shader "Custom/mask_u" { Properties { _MainTex ("Texture", 2D) = "white" {} _MaskTex("Mask Texture", 2D) = "white" {} } SubShader { // 所有Pass中渲染队列使用透明度混合队列,渲染类型选择透明度混合类型,并且渲染过程中不受投影器的影响 Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } LOD 100 Pass { Tags{ "LightModel" = "ForwardBase" } // 关闭深度写入,避免深度变化造成半透明异常 ZWrite Off // 开启透明度混合,并设置片元颜色的乘积因子以及颜色缓冲区中颜色的乘积因子 Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _MaskTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); // 乘以遮罩图的透明度 fixed4 mask_col = tex2D(_MaskTex, i.uv); col.a = col.a * mask_col.a; return col; } ENDCG } } }
来自:https://blog.csdn.net/v_xchen_v/article/details/78473782