【Unity Shader】手機端/較高精度, 實時雲端代碼分享

gif壓縮,失真很多,實際效果應該是好很多~


//cloudy_sky.shaderShader "Panda/Cloudy Sky"{ Properties{ _MainTex("MainTex", 2D) = "white" {} } SubShader { Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" } Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "util_v5.cginc" struct VertexInput { fixed4 vertex : POSITION; fixed2 uv : TEXCOORD0; }; struct VertexOutput { fixed4 pos : SV_POSITION; fixed2 uv : TEXCOORD0; }; sampler2D _MainTex; fixed4 integrate(in fixed4 sum, in fixed dif, in fixed den, in fixed3 bgcol, in fixed t) { //lighting fixed3 lin = fixed3(0.65,0.7,0.75)*1.4 + fixed3(1.0, 0.6, 0.3)*dif; fixed4 col = fixed4(lerp(fixed3(1.0,0.95,0.8), fixed3(0.25,0.3,0.35), den), den); col.xyz *= lin; col.xyz = lerp(col.xyz, bgcol, 1.0 - exp(-0.003*t*t)); //blending col.a *= 0.4; col.rgb *= col.a; return sum + col * (1.0 - sum.a); } fixed4 MARCH(inout fixed4 sum,inout fixed t, fixed3 ro, fixed3 rd, fixed3 bgcol,sampler2D tex) { for (int i = 0; i < 30; i++) { fixed3 pos = ro + t * rd; if (pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99) break; fixed den = map5(pos,tex); if (den > 0.01) { fixed dif = 0.0;// clamp((den - map5(pos + 0.3*sundir)) / 0.6, 0.0, 1.0); sum = integrate(sum, dif, den, bgcol, t); } t += max(0.05,0.02*t); } for (int ii = 0; ii < 30; ii++) { fixed3 pos = ro + t * rd; if (pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99) break; fixed den = map4(pos,tex); if (den > 0.01) { fixed dif = 0.0;// clamp((den - map4(pos + 0.3*sundir)) / 0.6, 0.0, 1.0); sum = integrate(sum, dif, den, bgcol, t); } t += max(0.05, 0.02*t); } for (int jj = 0; jj < 30; jj++) { fixed3 pos = ro + t * rd; if (pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99) break; fixed den = map3(pos,tex); if (den > 0.01) { fixed dif = 0.0;// clamp((den - map3(pos + 0.3*sundir)) / 0.6, 0.0, 1.0); sum = integrate(sum, dif, den, bgcol, t); } t += max(0.05, 0.02*t); } for (int kk = 0; kk < 30; kk++) { fixed3 pos = ro + t * rd; if (pos.y<-3.0 || pos.y>2.0 || sum.a > 0.99) break; fixed den = map2(pos,tex); if (den > 0.01) { fixed dif = 0.0;// clamp((den - map2(pos + 0.3*sundir)) / 0.6, 0.0, 1.0); sum = integrate(sum, dif, den, bgcol, t); } t += max(0.05, 0.02*t); } return sum; } fixed4 raymarch(in fixed3 ro, in fixed3 rd, in fixed3 bgcol, in fixed2 px,sampler2D tex) { fixed4 sum = 0.0; fixed t = 0.05*tex2D(_MainTex, px).x;//<< sum = MARCH(sum, t, ro,rd, bgcol,tex); return clamp(sum, 0.0, 1.); } fixed3x3 setCamera(in fixed3 ro, in fixed3 ta, fixed cr) { fixed3 cw = normalize(ta - ro); fixed3 cp = fixed3(sin(cr), cos(cr),0.0); fixed3 cu = normalize(cross(cw,cp)); fixed3 cv = normalize(cross(cu,cw)); return fixed3x3(cu, cv, cw); } fixed4 render(in fixed3 ro, in fixed3 rd, in fixed2 px,sampler2D tex) { //background sky fixed3 col = fixed3(0.6,0.71,0.75) - rd.y*0.2*fixed3(1.0,0.5,1.0) + 0.15*0.5; //clouds fixed4 res = raymarch(ro, rd, col, px, tex); col = col * (1.0 - res.w) + res.xyz; return fixed4(col, 1.0); } //---------------------------------------------------- VertexOutput vert(VertexInput v) { VertexOutput o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag(VertexOutput i) : SV_Target { fixed2 p = (0.5 - i.uv); //view matrix fixed3 ro = 4.0*normalize(fixed3(0.0,0.0,1.0)); fixed3 ta = fixed3(0.0, -1.0, 0.0); fixed3x3 ca = setCamera(ro, ta, 0.0); //ray matrix fixed3 rd = mul(ca , normalize(fixed3(p.xy, 0.15))); return render(ro, rd, p, _MainTex); } ENDCG } }}


//util_v5.cgincfixed noise_v5(in fixed3 x, sampler2D _mainTex) { fixed3 p = floor(x); fixed3 f = frac(x); f = f * f*(3.0 - 2.0*f); //------------use texture instead to reduce GPU workload------------ fixed2 uv = (p.xy + fixed2(37.0, 17.0)*p.z) + f.xy; fixed2 rg = tex2Dlod(_mainTex, float4((uv + 0.5) / 256.0, 0., 0)).yx; //------------------------------------------------------------------ return -1.0 + 2.0*lerp(rg.x, rg.y, f.z);}#define NUM_OCTAVES 5fixed fbm_v5(in fixed2 _st, sampler2D _mainTex) { fixed v = 0.0; fixed a = .6;//amplitude fixed2 shift = fixed2(100.0, 100.0); // Rotate to reduce axial bias fixed2x2 rot = fixed2x2(cos(0.5), sin(0.5), -sin(0.5), cos(0.5)); for (int i = 0; i < NUM_OCTAVES; ++i) { v += a * noise_v5(fixed3(_st, 0.0), _mainTex);//<<<<<<<<<<< _st = mul(rot, _st) * 2.0 + shift; a *= 0.5; } return v;}fixed3 fbm_inaction_v5(fixed aspectR, fixed2 uv, fixed time, sampler2D _mainTex) { fixed2 st = uv * aspectR; fixed3 color = fixed3(1.0, 1.0, 1.0); fixed2 q = fixed2(0., 0.); q.x = fbm_v5(st + 0.00*time, _mainTex); q.y = fbm_v5(st + fixed2(1.0, 1.0), _mainTex); fixed2 r = fixed2(0., 0.); r.x = fbm_v5(st + 1.0*q + fixed2(1.7, 9.2) + 0.15*time, _mainTex); r.y = fbm_v5(st + 1.0*q + fixed2(8.3, 2.8) + 0.126*time, _mainTex); fixed f = fbm_v5(st + r, _mainTex); color = lerp(fixed3(0.101961, 0.619608, 0.666667), fixed3(0.666667, 0.666667, 0.498039), clamp((f*f)*4.0, 0.0, 1.0)); color = lerp(color, fixed3(0, 0, 0.164706), clamp(length(q), 0.0, 1.0)); color = lerp(color, fixed3(0.666667, 1, 1), clamp(length(r.x), 0.0, 1.0)); return fixed3((f*f*f + .6*f*f + .5*f)*color);}//==================================================================================// only for cloud//==================================================================================fixed map5(in fixed3 p, sampler2D t){ fixed3 q = p - fixed3(0.0, 0.1, 1.0)*_Time.y; fixed f; f = 0.50000*noise_v5(q, t); q = q * 2.02; f += 0.25000*noise_v5(q, t); q = q * 2.03; f += 0.12500*noise_v5(q, t); q = q * 2.01; f += 0.06250*noise_v5(q, t); q = q * 2.02; f += 0.03125*noise_v5(q, t); return clamp(1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0);}fixed map4(in fixed3 p, sampler2D t){ fixed3 q = p - fixed3(0.0, 0.1, 1.0)*_Time.y; fixed f; f = 0.50000*noise_v5(q, t); q = q * 2.02; f += 0.25000*noise_v5(q, t); q = q * 2.03; f += 0.12500*noise_v5(q, t); q = q * 2.01; f += 0.06250*noise_v5(q, t); return clamp(1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0);}fixed map3(in fixed3 p, sampler2D t){ fixed3 q = p - fixed3(0.0, 0.1, 1.0)*_Time.y; fixed f; f = 0.50000*noise_v5(q, t); q = q * 2.02; f += 0.25000*noise_v5(q, t); q = q * 2.03; f += 0.12500*noise_v5(q, t); return clamp(1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0);}fixed map2(in fixed3 p, sampler2D t){ fixed3 q = p - fixed3(0.0, 0.1, 1.0)*_Time.y; fixed f; f = 0.50000*noise_v5(q, t); q = q * 2.02; f += 0.25000*noise_v5(q, t);; return clamp(1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0);}

(因為是雲,這次用了2D texture map 降低GPU開銷,挑個近雲狀態的大塊非白噪音就好)


推薦閱讀:

暢遊引擎Genesis的現狀是如何?
Unity3d,UDK 和 CE3 三者之間各有什麼優缺點?如何選擇?
請問為什麼Unity3D使用mono做為跨平台解決方案?
哪裡有Unity3D遊戲開發的教程?

TAG:shader | Unity游戏引擎 | 3D |