内容简介:Unity的天空盒,不够动态,要支持天气系统渐变的话,必须要改进,让天空盒梦幻一些.我的shader的高画质处理有个multi_compile开关叫_FANCY_STUFF,从Unity官方的某个shader看到的,这个名字我很喜欢,梦幻.天空盒我主要实现了以下几个功能:
Unity的天空盒,不够动态,要支持天气系统渐变的话,必须要改进,让天空盒梦幻一些.
我的shader的高画质处理有个multi_compile开关叫_FANCY_STUFF,从Unity官方的某个shader看到的,这个名字我很喜欢,梦幻.
天空盒我主要实现了以下几个功能:
1.天空盒可以水平旋转
为什么要水平旋转呢,因为我自定义了一个太阳(月亮),旋转可以让他们和天空盒背景图更加匹配.甚至,你可以慢慢旋转天空盒来模拟云层的移动...
2.实现了太阳(月亮).
程序实现的太阳,有个好处就是可以移动位置,还可以调节大小和颜色.发出的光芒还可以影响天空盒的颜色,实现原理就是根据天空盒像素和世界原点的距离来决定太阳颜色亮度,几何上的意义就是天空盒的立方体和一个距离为半径的球体的相交,自然就产生了一个圆形太阳的形状.
3.从下到上的高度雾
雾可以影响天空,还是从下到上的高度雾.如下图,紫色的雾从下到上:
4.天空盒背景图无缝切换
天气系统的需要,比如从白天慢慢变到晚上.太阳变成了月亮,背景云层也改变了.原理就是两个天空盒贴图的混合过渡.
5.太阳光晕效果
太阳可以被collider遮挡,如果没挡住,就产生光晕
------------------------------------------------------------------------------------------------------------
经过以上几个处理后,天空盒看起来相对梦幻了:
编辑器界面:
shader:
Shader "Luoyinan/Scene/SkyBox"
{
Properties
{
_MainTex ("Cubemap Texture", Cube) = "white" {}
_FogColor("Height Fog Color", Color) = (1,1,1,1)
_Angle("Angle", Float) = 0
_AngleSpeed ("Angle Speed", Float) = 0.2
_SunDistance("Sun Distance", Float) = 20
_SunPower("Sun Power", Float) = 1
_MainTex2 ("Fading Cubemap Texture. Don't Set. ", Cube) = "white" {}
_Angle2("Fading Cubemap Texture Angle. Don't Set.", Float) = 0
_AngleSpeed2 ("Fading Cubemap Texture Angle Speed. Don't Set.", Float) = 0.2
}
SubShader
{
Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
Cull Off ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma multi_compile __ _FANCY_STUFF
#pragma multi_compile __ _FADING_ON
struct appdata_t
{
float4 vertex : POSITION;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 texcoord : TEXCOORD0;
#if _FADING_ON
float3 texcoord1 : TEXCOORD1;
#endif
half fog : TEXCOORD2;
#if _FANCY_STUFF
half3 dir : TEXCOORD3;
#endif
};
samplerCUBE _MainTex;
#if _FADING_ON
samplerCUBE _MainTex2;
half _Angle2;
half _AngleSpeed2;
fixed _GlobalFadingFactor;
#endif
half _AngleSpeed;
#if _FANCY_STUFF
fixed4 _GlobalMainLightDir;
fixed4 _GlobalMainLightColor;
half _SunDistance;
half _SunPower;
#endif
fixed4 _FogColor;
half _Angle;
v2f vert (appdata_t v)
{
v2f OUT;
OUT.pos = mul(UNITY_MATRIX_MVP, v.vertex);
// 天空盒水平旋转
_Angle += _Time.x * _AngleSpeed;
half sina, cosa;
sincos(_Angle, sina, cosa);
fixed2x2 m = fixed2x2(cosa, -sina, sina, cosa);
OUT.texcoord = half3(mul(m, v.vertex.xz), v.vertex.y).xzy;
#if _FADING_ON
_Angle2 += _Time.x * _AngleSpeed2;
sincos(_Angle2, sina, cosa);
m = fixed2x2(cosa, -sina, sina, cosa);
OUT.texcoord1 = half3(mul(m, v.vertex.xz), v.vertex.y).xzy;
#endif
#if _FANCY_STUFF
OUT.dir = v.vertex.xyz;
#endif
// 高度雾.高度越低雾越浓,所以v.vertex.y取反.模型空间Y值范围[-1, 1],所以乘以2.
half fogFactor = 2 * (1.0 - _FogColor.a) - v.vertex.y;
OUT.fog = saturate(fogFactor); // 颜色过渡范围[0, 1]
return OUT;
}
fixed4 frag (v2f IN) : SV_Target
{
fixed4 finalColor = texCUBE(_MainTex, IN.texcoord);
#if _FADING_ON
fixed4 fadingColor = texCUBE(_MainTex2, IN.texcoord1);
finalColor = lerp(finalColor, fadingColor, _GlobalFadingFactor);
#endif
finalColor = lerp(finalColor, _FogColor, IN.fog);
#if _FANCY_STUFF
// 太阳
half3 dir = normalize(IN.dir); // 天空盒中心为世界原点,所以位置就等于方向.
half3 dir_sun = normalize(_GlobalMainLightDir.xyz);
half dis = length(dir_sun - dir) * _SunDistance;
finalColor += (saturate(max(1 / dis, 0.01)) * _GlobalMainLightColor) * _SunPower;
#endif
finalColor.a = 0; // 等美术做好天空盒的alpha通道再开放
return finalColor;
}
ENDCG
}
}
Fallback Off
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。