unity3d 不规则外发光描边_Shader案例之内发光和边缘泛光效果
在很多游戲都可以看到這種效果,具體怎么去實現呢,其實超級簡單。首先呢,我們先去把內發光的效果給做出了,然后再去實現外發光的效果。
1,我們最開始先實現一個顯示再屏幕上的顏色:
pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"struct a2v{float4 vertex:POSITION;};struct v2f{float4 pos:SV_POSITION;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);return o;}fixed4 frag(v2f f):SV_TARGET{return fixed4(1,1,1,1);}芒果Uki2,我們可以使用視角方向和模型法線方向點積來分配顏色值,在這個球的最邊緣的法線剛好和視角方向垂直,根據點積的幾何意義我們可以知道,如果兩個向量的角度等于90度,那么它的點積結果就為0,反之,角度等于0的點積結果為1,這樣我們就可以得到一個以下的效果:
芒果Uki pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag(v2f f):SV_TARGET{//我們在世界空間下來計算向量fixed3 WorldNormal=normalize(f.Wnormal);//得到模型指向攝像機的方向fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);//我們用法線方向和視角方向的點乘來取到它們的點積值,//我們知道最邊緣的法線和視角方向剛好垂直,兩個垂直的向量的點積結果為0,//面對我們的法線和視角剛好重合在一起,方向也是一樣的,那么結果為1,fixed bright=max(0,dot(WorldNormal,ViewDir));return fixed4(1,1,1,1)*bright;}ENDCG}因為我們需要的是邊緣發光,希望是中間是沒有顏色的,顏色在旁邊,所以我們可以把點積的結果進行1減操作,從而取反:
float bright=1.0-saturate(dot(WorldNormal,ViewDir));芒果Uki我們發現這并不是我們想要的效果,范圍太大了,什么??范圍太大了,第一個想到的肯定是我們可以利用平方去控制它的范圍,好的,下面我們就去實現它:
Properties{_Scale("內發光范圍控制",Range(1,8))=1} //這個屬性用來控制開方的次數float _Scale; //我們在CGPROGRAM-ENDCG之間聲明了它bright=pow(bright,_Scale); //使用它芒果Uki3,我希望這個效果是中間透明的,邊緣才有顏色:
//在Subshader里設置一下透明混合所需的標簽 Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType "="Transparent"} //Pass中設置混合因子 Blend SrcAlpha OneMinusSrcAlpha不過混合紋理我們不需要開啟透明,這個透明我們可以用外發光的上,讓它看著有一種透明而且漸變的效果,所以我們只相加它的顏色,a通道還是用紋理的,現在得到了一個看起來不錯的效果,我們需要把它和紋理疊加在一起:
Shader "01/1"{Properties{_Scale("內發光范圍控制",Range(1,8))=1_MainTex("貼圖1",2D)="white"{}}SubShader{Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType "="Transparent"}pass{Blend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"sampler2D _MainTex;float4 _MainTex_ST;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;float4 texcoord:TEXCOORD0;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;float2 uv:TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;return o;}float _Scale;fixed4 frag(v2f f):SV_TARGET{fixed4 texcolor=tex2D(_MainTex,f.uv);fixed3 WorldNormal=normalize(f.Wnormal);fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);fixed bright=1.0-max(0,dot(WorldNormal,ViewDir));bright=pow(bright,_Scale);fixed4 edge=fixed4(1,1,1,1)*bright;fixed3 AddColor=edge.rgb+texcolor.rgb;return fixed4(AddColor,texcolor.a);}ENDCG}} } Properties{_Scale("內發光范圍控制",Range(1,8))=1_MainTex("貼圖1",2D)="white"{}_ScaleColor("內發光顏色",Color)=(1,1,1,1)} //偷偷加上控制內發光顏色的屬性 fixed4 edge=_ScaleColor*bright;4,接下來就該輪到我們的外發光效果了,實現方法也非常簡單,利用另一個pass來渲染,我們可以復制第一個pass進行修改,我們先渲染內發光再渲染外擴,反過來也是一樣的,不過第一種會比較節省性能,可以通過深度檢測過濾掉很多描邊繪制的像素,效率會更好。:
這是是這個shader的源代碼,希望能夠幫助到大家
Shader "01/1"{Properties{_Scale("內發光顏色范圍控制",Range(1,8))=1_Scale2("外輪廓顏色范圍控制",Range(1,8))=1_MainTex("貼圖1",2D)="white"{}_ScaleColor("內發光顏色",Color)=(1,1,1,1)_ScaleColor2("外輪廓顏色",Color)=(1,1,1,1)_outline("輪廓范圍",Range(0,1))=0.1}SubShader{Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType "="Transparent"}//外擴散發光pass{Blend SrcAlpha OneMinusSrcAlphaZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"sampler2D _MainTex;fixed4 _ScaleColor;fixed4 _ScaleColor2;fixed _outline;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;};v2f vert(a2v v){v.vertex.xyz+=v.normal*_outline;v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;return o;}float _Scale;float _Scale2;fixed4 frag(v2f f):SV_TARGET{fixed3 WorldNormal=normalize(f.Wnormal);fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);fixed bright=max(0,dot(WorldNormal,ViewDir));bright=pow(bright,_Scale2);_ScaleColor2.a=_ScaleColor2.a*bright;return fixed4(_ScaleColor2);}ENDCG}//=============================================================================== //第2個pass,內發光pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"sampler2D _MainTex;float4 _MainTex_ST;fixed4 _ScaleColor;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;float4 texcoord:TEXCOORD0;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;float2 uv:TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;return o;}float _Scale;fixed4 frag(v2f f):SV_TARGET{fixed4 texcolor=tex2D(_MainTex,f.uv);fixed3 WorldNormal=normalize(f.Wnormal);fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);fixed bright=1.0-max(0,dot(WorldNormal,ViewDir));bright=pow(bright,_Scale);fixed4 edge=_ScaleColor*bright;fixed3 AddColor=edge.rgb+texcolor.rgb;return fixed4(AddColor,texcolor.a);}ENDCG}} }最終效果:
不嫌棄的話可以來群里一起交流學習,干貨滿滿喲
總結
以上是生活随笔為你收集整理的unity3d 不规则外发光描边_Shader案例之内发光和边缘泛光效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: seo优化源码_武汉seo公司关键词SE
- 下一篇: docker pull的镜像放在哪里_D