按照方向消失或重現效果
我們再來看一個用模型空間坐標作為采樣的uv的栗子,也是一種比較好玩的效果。比如我們需要一個模型身體按照一定的方向逐漸消失,直至全部消失掉的一個效果。下面說一下思路,與世界空間采樣的流光效果一樣,我們在vertex階段記錄一下vertex坐標,傳遞給fragment階段,在fragment階段用這個值和一個設定好的閾值進行比較,不滿足條件的像素點直接discard,逐漸調整閾值,就可以得到讓模型按照某個方向消失的效果了。紋理流動 shader,代碼如下:
- ??
- ??
- ?
- Shader?"SelfShader/DissolveEffectX"???
- {??
- ????Properties??
- ????{??
- ????????_MainTex("MainTex(RGB)",?2D)?=?"white"?{}??
- ????????_DissolveVector("DissolveVector",?Vector)?=?(0,0,0,0)??
- ????}??
- ??????
- ????CGINCLUDE??
- ????#include?"Lighting.cginc"??
- ????uniform?sampler2D?_MainTex;??
- ????uniform?float4?_MainTex_ST;??
- ????uniform?float4?_DissolveVector;??
- ??
- ????struct?v2f???
- ????{??
- ????????float4?pos?:?SV_POSITION;??
- ????????float3?worldNormal?:?NORMAL;??
- ????????float2?uv?:?TEXCOORD0;??
- ????????float3?worldLight?:?TEXCOORD1;??
- ????????float4?objPos?:?TEXCOORD2;??
- ????};??
- ??
- ????v2f?vert(appdata_base?v)??
- ????{??
- ????????v2f?o;??
- ????????o.pos?=?mul(UNITY_MATRIX_MVP,?v.vertex);??
- ????????o.uv?=?TRANSFORM_TEX(v.texcoord,?_MainTex);??
- ??????????
- ????????o.objPos?=?v.vertex;??
- ????????o.worldNormal?=?UnityObjectToWorldNormal(v.normal);??
- ????????o.worldLight?=?UnityObjectToWorldDir(_WorldSpaceLightPos0.xyz);??
- ????????return?o;??
- ????}??
- ??????????????
- ????fixed4?frag(v2f?i)?:?SV_Target??
- ????{??
- ????????half3?normal?=?normalize(i.worldNormal);??
- ????????half3?light?=?normalize(i.worldLight);??
- ????????fixed?diff?=?max(0,?dot(normal,?light));??
- ????????fixed4?albedo?=?tex2D(_MainTex,?i.uv);??
- ??????????
- ????????clip(i.objPos.xyz?-?_DissolveVector.xyz);??
- ????????fixed4?c;??
- ????????c.rgb?=?diff?*?albedo;??
- ????????c.a?=?1;??
- ????????return?c;??
- ????}??
- ????ENDCG??
- ??
- ????SubShader??
- ????{??
- ??????????
- ????????Pass??
- ????????{??
- ????????????Tags{?"RenderType"?=?"Opaque"?}??
- ??????????????
- ????????????CGPROGRAM??
- ????????????#pragma?vertex?vert??
- ????????????#pragma?fragment?frag??
- ????????????ENDCG?????
- ????????}??
- ????}??
- ????FallBack?"Diffuse"??
- }??
還有一個小問題,其實上圖中的例子里面,模型從上到下,理想情況應該是調整Y軸,不過例子里面調整的確實X軸,原因應該與Unity導入之后會繞著X軸旋轉90度有關,也就是原本在max里面的Y軸變成Unity里面的X軸。
下面,我們再看一下增加了邊緣高亮的消失效果,為了讓模消失的型邊緣高亮,我們通過將用于clip的factor值與另一個高亮閾值值進行比較,如果factor小于高亮閾值,則返回一個高亮的顏色值,否則正常渲染。這樣模型就總共有三種顯示狀態:clip狀態,高亮狀態,正常狀態。代碼如下:
- ??
-
- ?
- ??
- Shader?"SelfShader/DissolveEffectX"??
- {??
- ????Properties{??
- ????????_Diffuse("Diffuse",?Color)?=?(1,1,1,1)??
- ????????_DissolveColor("Dissolve?Color",?Color)?=?(0,0,0,0)??
- ????????_MainTex("Base?2D",?2D)?=?"white"{}??
- ????????_ColorFactor("ColorFactor",?Range(0,1))?=?0.7??
- ????????_DissolveThreshold("DissolveThreshold",?Float)?=?0????
- ????}??
- ??????
- ????CGINCLUDE??
- ????#include?"Lighting.cginc"??
- ????uniform?fixed4?_Diffuse;??
- ????uniform?fixed4?_DissolveColor;??
- ????uniform?sampler2D?_MainTex;??
- ????uniform?float4?_MainTex_ST;??
- ????uniform?float?_ColorFactor;??
- ????uniform?float?_DissolveThreshold;????
- ??????
- ????struct?v2f??
- ????{??
- ????????float4?pos?:?SV_POSITION;??
- ????????float3?worldNormal?:?TEXCOORD0;??
- ????????float2?uv?:?TEXCOORD1;??
- ????????float4?objPos?:?TEXCOORD2;???
- ????};??
- ??????
- ????v2f?vert(appdata_base?v)??
- ????{??
- ????????v2f?o;??
- ????????o.pos?=?mul(UNITY_MATRIX_MVP,?v.vertex);??
- ????????o.uv?=?TRANSFORM_TEX(v.texcoord,?_MainTex);??
- ????????o.worldNormal?=?mul(v.normal,?(float3x3)unity_WorldToObject);??
- ????????o.objPos?=?v.vertex;????
- ????????return?o;??
- ????}??
- ??????
- ????fixed4?frag(v2f?i)?:?SV_Target??
- ????{??
- ????????float?factor?=?i.objPos.x?-?_DissolveThreshold;??
- ????????clip(factor);???
- ??????????
- ????????fixed3?worldNormal?=?normalize(i.worldNormal);??
- ????????fixed3?worldLightDir?=?normalize(_WorldSpaceLightPos0.xyz);??
- ????????fixed3?lambert?=?saturate(dot(worldNormal,?worldLightDir));??
- ????????fixed3?albedo?=?lambert?*?_Diffuse.xyz?*?_LightColor0.xyz?+?UNITY_LIGHTMODEL_AMBIENT.xyz;??
- ????????fixed3?color?=?tex2D(_MainTex,?i.uv).rgb?*?albedo;??
- ??????????
- ????????fixed?lerpFactor?=?saturate(sign(_ColorFactor?-?factor));??
- ????????return?lerpFactor?*?_DissolveColor?+?(1?-?lerpFactor)?*?fixed4(color,?1);??
- ?????????
- ?
- ?
- ?
- ?
- ??
- ????}??
- ????ENDCG??
- ??????
- ????SubShader??
- ????{??
- ????????Tags{?"RenderType"?=?"Opaque"?}??
- ????????Pass??
- ????????{??
- ??????????????
- ????????????Cull?Off??
- ????????????CGPROGRAM??
- ????????????#pragma?vertex?vert??
- ????????????#pragma?fragment?frag?????
- ????????????ENDCG??
- ????????}??
- ????}??
- ????FallBack?"Diffuse"??
- }??
溶解效果進階版
之前的文章里,我們研究過溶解效果,不過這個效果是基于全身的,我們來嘗試一下,把上面按照方向消失的效果與溶解效果結合起來,做成一個按照某個方向逐漸溶解的效果。要得到隨機的溶解效果,我們需要采樣一張噪聲圖,然后在原本會直接clip掉的部分根據采樣的噪聲圖進行clip,就能得到按照方向的溶解效果啦。
- ??
-
-
- ??
- Shader?"SelfShader/DissolveEffectX"??
- {??
- ????Properties{??
- ????????_Diffuse("Diffuse",?Color)?=?(1,1,1,1)??
- ????????_DissolveColor("Dissolve?Color",?Color)?=?(1,1,1,1)??
- ????????_MainTex("Base?2D",?2D)?=?"white"{}??
- ????????_DissolveMap("DissolveMap",?2D)?=?"white"{}??
- ????????_DissolveThreshold("DissolveThreshold",?Range(0,1))?=?0??
- ????????_DissolveSpeedFactor("DissolveSpeed",?Range(0,5))?=?2??
- ????????_DissolveControl("ColorFactorB",?Float)?=?0??
- ????}??
- ??????
- ????CGINCLUDE??
- ????#include?"Lighting.cginc"??
- ????uniform?fixed4?_Diffuse;??
- ????uniform?fixed4?_DissolveColor;??
- ????uniform?sampler2D?_MainTex;??
- ????uniform?float4?_MainTex_ST;??
- ????uniform?sampler2D?_DissolveMap;??
- ????uniform?float?_DissolveThreshold;??
- ????uniform?float?_DissolveSpeedFactor;??
- ????uniform?float?_DissolveControl;???
- ??????
- ????struct?v2f??
- ????{??
- ????????float4?pos?:?SV_POSITION;??
- ????????float3?worldNormal?:?TEXCOORD0;??
- ????????float2?uv?:?TEXCOORD1;??
- ????????float4?objPos?:?TEXCOORD2;???
- ????};??
- ??????
- ????v2f?vert(appdata_base?v)??
- ????{??
- ????????v2f?o;??
- ????????o.pos?=?mul(UNITY_MATRIX_MVP,?v.vertex);??
- ????????o.uv?=?TRANSFORM_TEX(v.texcoord,?_MainTex);??
- ????????o.worldNormal?=?mul(v.normal,?(float3x3)unity_WorldToObject);??
- ????????o.objPos?=?v.vertex;????
- ????????return?o;??
- ????}??
- ??????
- ????fixed4?frag(v2f?i)?:?SV_Target??
- ????{??
- ????????fixed4?dissolve?=?tex2D(_DissolveMap,?i.uv);??
- ??????????
- ????????fixed3?worldNormal?=?normalize(i.worldNormal);??
- ????????fixed3?worldLightDir?=?normalize(_WorldSpaceLightPos0.xyz);??
- ????????fixed3?lambert?=?saturate(dot(worldNormal,?worldLightDir));??
- ????????fixed3?albedo?=?lambert?*?_Diffuse.xyz?*?_LightColor0.xyz?+?UNITY_LIGHTMODEL_AMBIENT.xyz;??
- ????????fixed3?color?=?tex2D(_MainTex,?i.uv).rgb?*?albedo;??
- ????????float?factor?=?i.objPos.x?-?_DissolveControl;??
- ????????if(factor?<?0)??
- ????????{??
- ????????????clip(_DissolveThreshold?-?dissolve.r?*?abs(factor)?*?_DissolveSpeedFactor);??
- ????????}??
- ????????return?fixed4(color,?1);??
- ????}??
- ????ENDCG??
- ??????
- ????SubShader??
- ????{??
- ????????Tags{?"RenderType"?=?"Opaque"?}??
- ????????Pass??
- ????????{??
- ????????????Cull?Off??
- ????????????CGPROGRAM??
- ????????????#pragma?vertex?vert??
- ????????????#pragma?fragment?frag?????
- ????????????ENDCG??
- ????????}??
- ????}??
- ????FallBack?"Diffuse"??
- }??
Shader "SelfShader/Dissolve"
{Properties{_MainColor("MainColor",COLOR)=(1,1,1,1)_MainTex ("Texture", 2D) = "white" {}_Noise("Noise",2D)="white"{}_Dissolve("Dissolve",Vector)=(0.2,0.5,0.8)_DissolveThread("DissolveThread",float)=0.2_DissolveColor("DissolveColor",COLOR)=(1,1,1,1)_DissolveColFactor("_DissolveColFactor",float)=2_FlyFactor("FlyFactor",float)=3}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"struct a2v{float4 vertex : POSITION;float2 uv : TEXCOORD0;fixed3 normal:NORMAL;};struct v2f{float2 uv : TEXCOORD0;float4 pos : SV_POSITION;fixed3 worldNormal:TEXCOORD1;fixed3 worldPos:TEXCOORD2;fixed3 objPos:TEXCOORD3;};sampler2D _Noise;sampler2D _MainTex;float4 _MainTex_ST;fixed4 _MainColor;fixed4 _Dissolve;float _DissolveThread;fixed4 _DissolveColor;float _DissolveColFactor;float _FlyFactor;v2f vert (a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos=mul((float3x3)unity_ObjectToWorld,v.vertex);o.worldNormal=UnityObjectToWorldNormal(v.normal);o.objPos=v.vertex;o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.pos.xyz+=v.normal*saturate(_DissolveThread-_FlyFactor)*_FlyFactor;return o;}fixed4 frag (v2f i) : SV_Target{fixed3 worldNor=normalize(i.worldNormal);fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);fixed4 albedo = tex2D(_MainTex, i.uv)*_MainColor;fixed4 noiseColor=tex2D(_Noise,i.uv);float factor=noiseColor.r-_DissolveThread;clip(factor);fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo.rgb;fixed3 diffuse=_LightColor0.rgb*albedo.rgb*(0.5*dot(lightDir,worldNor)+0.5);float lerpFactor=saturate(sign(_DissolveColFactor-factor));return lerp(fixed4(ambient+diffuse,1),_DissolveColor,lerpFactor);}ENDCG}}
}