UnityShader入门精要学习笔记(十):透明效果-上部分
2017-07-08 13:09
966 查看
1.Unity渲染顺序
2.透明度测试
片元着色器中的剪裁函数clip
函数:void clip(float x) 、void clip(float2 x)、void clip(float3 x)、void clip(float4 x)
参数:剪裁时使用的标量或者矢量
描述:如果给定的参数中有任何一个分量为负数就会舍弃当前像素输出的颜色
代码实践
效果图:
3.透明度混合
(1)关闭深度写入的透明度混合
效果图:
可以看出当模型网格具有交叉结构时往往会得到错误的半透明效果。
这是由于我们关闭了深度写入造成的,因为这样我们就无法对模型进行像素级别的深度排序。
(2)开启深度写入的半透明效果
效果图:
明显看出右边的双通道的shader有了正确的深度效果。
2.透明度测试
片元着色器中的剪裁函数clip
函数:void clip(float x) 、void clip(float2 x)、void clip(float3 x)、void clip(float4 x)
参数:剪裁时使用的标量或者矢量
描述:如果给定的参数中有任何一个分量为负数就会舍弃当前像素输出的颜色
代码实践
Shader "Custom/Edu/AlphaTest" { Properties { _Color ("ColorTint", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Cutoff("CutOff",Range(0,1)) = 0.2 } SubShader { Tags { //这一句作用于这个SubShader的所有Pass //注意这里不需要用逗号或者分号做分割 "RenderType"="TransparentCutOut" "Queue" = "AlphaTest" "LightMode" = "ForwardBase" } Pass { //这句是单独作用于该Pass的 Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; float _Cutoff; fixed4 _Color; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; float2 texcoord:TEXCOORD0; }; struct v2f { float4 pos:SV_POSITION; float3 worldNormal:TEXCOORD0; //之前写成了float4 //float4 worldPos:TEXCOORD1; float3 worldPos:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); //两种写法 //o.worldNormal = mul(v.normal,(float3x3)_World2Object); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(_Object2World,v.vertex).xyz; o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } fixed4 frag(v2f i):SV_Target { fixed4 texColor = tex2D(_MainTex,i.uv); clip(texColor.a - _Cutoff); fixed3 albedo = texColor.rgb * _Color.rgb; float3 worldNormal = normalize(i.worldNormal); float3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); fixed3 diffuse = _LightColor0.rgb * albedo.rgb * saturate(dot(worldNormal,worldLightDir)); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; return fixed4(ambient + diffuse ,1.0); } ENDCG } } FallBack "Diffuse" }
效果图:
3.透明度混合
(1)关闭深度写入的透明度混合
Shader "Custom/Edu/ZOffTransparent" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _AlphaScale("AlphaScale",Range(0,1)) = 0.5 } SubShader { Tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProject" = "true"} Pass { Tags{"LightMode" = "ForwardBase"} ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; float _AlphaScale; struct a2v { float4 vertex:PO 4000 SITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; }; struct v2f { float4 pos:SV_POSITION; float3 worldPos:TEXCOORD0; float3 worldNormal:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(_Object2World,v.vertex).xyz; o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } fixed4 frag(v2f i):SV_Target { float3 worldLightDir = normalize( UnityWorldSpaceLightDir(i.worldPos) ); float3 worldNormal = normalize( i.worldNormal ); fixed4 texColor = tex2D(_MainTex,i.uv); fixed3 albedo = texColor.rgb * _Color.rgb; fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal,worldLightDir)); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; return fixed4(ambient + diffuse, texColor.a * _AlphaScale); } ENDCG } } FallBack "Diffuse" }
效果图:
可以看出当模型网格具有交叉结构时往往会得到错误的半透明效果。
这是由于我们关闭了深度写入造成的,因为这样我们就无法对模型进行像素级别的深度排序。
(2)开启深度写入的半透明效果
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' Shader "Custom/Edu/ZOnTransparent" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _AlphaScale("AlphaScale",Range(0,1)) = 0.5 } SubShader { Tags{"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProject" = "true"} //第一个Pass只是写入深度缓存 Pass { Zwrite On //这一句用来设置颜色通道的写入掩码(write mask) //它的语义如下: //ColorMask RGB|A|0|其它任何R、G、B、A的组合 //ColorMask 0 表示不写入任何颜色! ColorMask 0 } Pass { Tags{"LightMode" = "ForwardBase"} ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; float _AlphaScale; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; float4 texcoord:TEXCOORD0; }; struct v2f { float4 pos:SV_POSITION; float3 worldPos:TEXCOORD0; float3 worldNormal:TEXCOORD1; float2 uv:TEXCOORD2; }; v2f vert(a2v v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz; o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } fixed4 frag(v2f i):SV_Target { float3 worldLightDir = normalize( UnityWorldSpaceLightDir(i.worldPos) ); float3 worldNormal = normalize( i.worldNormal ); fixed4 texColor = tex2D(_MainTex,i.uv); fixed3 albedo = texColor.rgb * _Color.rgb; fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(worldNormal,worldLightDir)); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo; return fixed4(ambient + diffuse, texColor.a * _AlphaScale); } ENDCG } } FallBack "Diffuse" }
效果图:
明显看出右边的双通道的shader有了正确的深度效果。
相关文章推荐
- UnityShader入门精要学习笔记(十一):透明效果-下部分
- Unity Shader入门精要学习笔记 - 第8章 透明效果
- Unity Shader入门精要学习笔记 - 第8章 透明效果
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
- UnityShader入门精要学习笔记(二):数学知识
- UnityShader入门精要学习笔记(九):基础纹理之渐变纹理与遮罩纹理
- Unity Shader入门精要学习笔记 - 第5章 开始 Unity Shader 学习之旅
- Unity Shader入门精要学习笔记 - 第2章 渲染流水线
- Unity Shader入门精要学习笔记 - 第5章 开始 Unity Shader 学习之旅
- UnityShader入门精要学习笔记(二十):运动模糊
- Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础
- UnityShader入门精要学习笔记(十七):顶点动画
- Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照
- UnityShader入门精要学习笔记(十三):光照衰减与Unity阴影
- UnityShader入门精要学习笔记(二十一):深度和法线纹理
- Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照
- Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术
- UnityShader入门精要学习笔记(十二):渲染路径与光源类型
- Unity Shader入门精要学习笔记 - 第11章 让画面动起来
- 凹凸映射 Bump mapping(unityshader入门精要学习笔记)