Shader实现动态切换天空球

发表于2018-11-19
评论0 5.2k浏览
如果大家掌握天空盒是怎么实现的以后,想要实现天空球其实也很容易,但这篇可能会复杂一些, 给大家分享下的是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  
		}  
	}  
}  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: