shader之——球形煙霧 &&CG函式saturate與abs的用法
阿新 • • 發佈:2019-02-09
今天接到個需求,做一個球形的煙霧,讓3D場景自己在場景裡去擺放,貼圖不是4方連續的,所以看上去有接縫哈,具體的讓特效自己去調效果了:
遇到了一個從來都沒注意過的問題,做了一個球形的煙霧,用了邊緣透明的方式,同時用了Cull Off,但是無論如何都無法顯示背面,找到了原因,在此記錄一下。
shader程式碼如下:
saturate 與 abs// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "effects/Smoke"{ Properties { _MainTex ("Base layer (RGB)", 2D) = "white" {} _ScrollX ("Base layer Scroll speed X", Float) = 1.0 _ScrollY ("Base layer Scroll speed Y", Float) = 0.0 _brightness ("brightness", Float) = 2.0 _color("color",color) = (1,1,1,1) } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } pass { Zwrite Off Cull Off Blend SrcAlpha OneMinusSrcAlpha LOD 100 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; float4 _MainTex_ST; float _ScrollX; float _ScrollY; float _brightness; fixed4 _color; struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; fixed4 color : COLOR; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; fixed4 color : TEXCOORD1; float NdotV :TEXCOORD2; }; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.texcoord.xy,_MainTex) + frac(float2(_ScrollX, _ScrollY) * _Time); o.color = v.color; float3 Normal =UnityObjectToWorldNormal( v.normal); float3 ViewDir =normalize( WorldSpaceViewDir( v.vertex)); o.NdotV =pow (abs(dot (Normal,ViewDir)),3); return o; } fixed4 frag (v2f i) : COLOR { fixed4 tex = tex2D (_MainTex, i.uv); fixed4 o = tex * i.color * _brightness * _color; o.a = tex.r * i.color.a * i.NdotV; return o; } ENDCG } } }
o.NdotV =pow (saturate(dot (Normal,ViewDir)),3);
這裡剛開始用了saturate,結果怎麼都不顯示雙面,折騰了好久,師傅告訴我,saturate不是這麼用的
saturate返回是0到1,而小於0的時候,也就是物體的背面,他永遠是返回0
abs 返回的是絕對值,他才可以把物體背面的法線由負方向變成正常向