Shader实现动态切换天空球
发表于2018-11-19
如果大家掌握天空盒是怎么实现的以后,想要实现天空球其实也很容易,但这篇可能会复杂一些, 给大家分享下的是shader实现动态切换天空球,一起来看看吧。
最终效果
思路
改进之前的全景图,应用到天空球。
利用3dnoise算法,生成噪声。
源代码:
Shader"QQ/Sky/MultiSky" { Properties { _Color("Color",Color)=(1,1,1,1) _Rotation("Rotation",Range(0,360))=360 [NoScaleOffset]_MainTex("Texture1",2D)="white"{} [NoScaleOffset]_SecondTex("Texture2",2D)="white"{} _BlendColor("blendColor",Color)=(1,1,1,0) _Blend("blend",Range(0,1))=0.5 _Hill("hill",Range(0,1))=0.1 } SubShader { Tags{ "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" } ZwriteOff Pass { CGPROGRAM #pragmavertexvert #pragmafragmentfrag #include"UnityCG.cginc" structa2v { float4vertex:POSITION; }; structv2f { float4pos:SV_POSITION; float3wPos:TEXCOORD1; }; sampler2D_MainTex; float4_MainTex_ST; sampler2D_SecondTex; float_Blend; float_Hill; fixed4_Color; fixed4_BlendColor; float_Rotation; sampler2D_TexUp; sampler2D_TexDown; float3x3RotationY(float_y) { _y=radians(_y); float_sin=sin(_y); float_cos=cos(_y); returnfloat3x3(_cos,0,-_sin,0,1,0,_sin,0,_cos); } v2fvert(a2vv) { v2fo; o.pos=UnityObjectToClipPos(v.vertex); o.wPos=mul(unity_ObjectToWorld,v.vertex); returno; } float3hash23(float3p) { constfloat3k=float3(0.3183099,0.3678794,0.57465413); p=p*k+p.zyx; return-1.0+2.0*frac(16.0*p*frac(p.x*p.y*p.z*(p.x+p.y+p.z))); } floatperlinNoise(float3p) { float3i=floor(p); float3f=frac(p); float3u=f*f*(3.0-2.0*f); floatyx0=lerp(dot(hash23(i+float3(0.0,0.0,0.0)),f-float3(0.0,0.0,0.0)),dot(hash23(i+float3(1.0,0.0,0.0)),f-float3(1.0,0.0,0.0)),u.x); floatyx1=lerp(dot(hash23(i+float3(0.0,1.0,0.0)),f-float3(0.0,1.0,0.0)),dot(hash23(i+float3(1.0,1.0,0.0)),f-float3(1.0,1.0,0.0)),u.x); floatyy0=lerp(yx0,yx1,u.y); floatyz0=lerp(dot(hash23(i+float3(0.0,0.0,1.0)),f-float3(0.0,0.0,1.0)),dot(hash23(i+float3(1.0,0.0,1.0)),f-float3(1.0,0.0,1.0)),u.x); floatyz1=lerp(dot(hash23(i+float3(0.0,1.0,1.0)),f-float3(0.0,1.0,1.0)),dot(hash23(i+float3(1.0,1.0,1.0)),f-float3(1.0,1.0,1.0)),u.x); floatyy1=lerp(yz0,yz1,u.y); returnsaturate((lerp(yy0,yy1,u.z)+0.6)*0.5); } //pc端可用次迭代出细腻的效果 floatnoise_sum(float3p,intnum) { floatf=0.0; p*=4.0; floatc=1.0; for(inti=0;i<num;i++) { c*=0.5; f+=c*perlinNoise(p); p*=2.0; } returnf; } fixed4frag(v2fi):SV_Target { float3viewDir=normalize(_WorldSpaceCameraPos.xyz-i.wPos); viewDir=mul(RotationY(_Rotation),viewDir); floatu=(atan2(viewDir.x,viewDir.z)+UNITY_PI)/UNITY_TWO_PI; floatv=acos(viewDir.y)/UNITY_PI; float2uv=float2(u,v); fixed4tex0=tex2D(_MainTex,uv,float2(0.00001,0.0),float2(0.0,0.0)); fixed4tex1=tex2D(_SecondTex,uv,float2(0.00001,0.0),float2(0.0,0.0)); floatnoise=perlinNoise(viewDir*8); _Blend=(_Blend-0.4)*1.5; _Hill*=0.4; floatblend=smoothstep(_Blend-_Hill,_Blend+_Hill,noise); fixed4col=lerp(tex1,tex0,blend); col*=_Color; col+=(0.5-abs(blend-0.5))*3.0*_BlendColor*_BlendColor.a; returncol; } ENDCG } } }