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
}
}
}
