天空球+云+山

2018-07-10  本文已影响0人  星易乾川

我们平时做天空球的uv接缝贴图不好处理,看了官方shader的源码,结合借鉴了candycat美女的动态噪波云效果,做了一个天空球

Unity中Lighting里的天空盒的UV是纯圆形的

image

官方shader中是用CUBEMap实现的,我也在这基础上修改

image

分为几大块:背景上下渐变色+一层云半透cubemap+中景山脉半透cubemap+前景动态噪波云

image
Properties {
    _SkyColor0 ("Sky Color Up", Color) = (0, 0, 1, 1)
    _SkyColor1 ("Sky Color Down", Color) = (0.5, 0.5, 1, 1)
    [Space(50)]
    [NoScaleOffset] _Tex ("BackCloudCubemap   (HDR)", Cube) = "grey" {}
    _Tint ("Tint Color", Color) = (1, 1, 1, 1)
    [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0
    _RotationSpeed ("RotationSpeed", Range(0, 10)) = 2.51
    [Space(50)]
    [NoScaleOffset] _Tex2 ("MiddleTex", Cube) = "grey" {}
    _UVY ("UVY", Range(-1, 3.0)) = 0
    [Space(50)]
    [NoScaleOffset] _Octave0 ("Octave 0", 2D) = "white" {}
    [NoScaleOffset] _Octave1("Octave 1", 2D) = "white" {}
    [NoScaleOffset] _Octave2 ("Octave 2", 2D) = "white" {}
    [NoScaleOffset] _Octave3 ("Octave 3", 2D) = "white" {}
    _CloudColor ("Cloud Color", Color) = (1, 1, 1, 0.7)
    _Speed ("Speed", Range(-1.0, 1.0)) = -0.49
    _Emptiness ("Emptiness", Range(0.0, 1.0)) = 0.441
    _Sharpness ("Sharpness", Range(0.0, 1.0)) = 0.711
}
SubShader {
    Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
    Cull Off ZWrite Off
  //渐变背景色pass
            Pass { 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            fixed _BackTexSpeed;
            fixed4 _SkyColor0;
            fixed4 _SkyColor1;
            sampler2D _Octave0;
            sampler2D _Octave3;
            float _UVY;
            struct appdata {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;        
            };
            struct v2f {
                float4 pos : SV_POSITION;
                half2 uv : TEXCOORD0;
                float2 texcoord1 : TEXCOORD1;
            };

            v2f vert (appdata v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;
                o.uv = half2(o.uv.x+_Time.y*_BackTexSpeed,o.uv.y);
                o.texcoord1 = v.texcoord;
            o.texcoord1 = half2(o.texcoord1.x,o.texcoord1.y + _UVY);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target {
                fixed4 col;
                col.rgb = lerp(_SkyColor1.rgb, _SkyColor0.rgb, pow(i.uv.y, 1));                 
                col.a = 1.0;                     
                return  col;
            }
            ENDCG
        }
//背景云pass
    Pass {
            Blend SrcAlpha OneMinusSrcAlpha 
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag       
            #include "UnityCG.cginc"
            half4 _Tint;
             half4 _Tex_HDR;
            half4 _Tint1;
            samplerCUBE _Tex;
            float _Rotation;    
            fixed _Emptiness;
            fixed _Sharpness;
            sampler2D _Main_Textures;
            float4 _Main_Textures_ST;       
            float _RotationSpeed;
            struct appdata {
                float4 vertex : POSITION;
                float3 texcoord : TEXCOORD0;
                 UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            struct v2f {
                float4 pos : SV_POSITION;       
                half4 uv0 : TEXCOORD0;
                half4 uv1 : TEXCOORD1;
                half2 uv2 : TEXCOORD2;
                float3 texcoord : TEXCOORD3;
                float3 texcoord1 : TEXCOORD4;
                 UNITY_VERTEX_OUTPUT_STEREO
            };
            //旋转矩阵
         float3 RotateAroundYInDegrees (float3 vertex, float degrees)
        {
            float alpha = degrees * UNITY_PI / 180.0;
            float sina, cosa;
            sincos(alpha, sina, cosa);
            float2x2 m = float2x2(cosa, -sina, sina, cosa);
            return float3(mul(m, vertex.xz), vertex.y).xzy;
        }

            v2f vert (appdata v) {
                v2f o;
            UNITY_SETUP_INSTANCE_ID(v);
                        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                    
            float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation+_Time.y*_RotationSpeed);
            o.pos = UnityObjectToClipPos(rotated);
            o.texcoord = v.vertex.xyz;
    
                return o;
            }
            fixed4 frag (v2f i) : SV_Target {
                            half4 tex = texCUBE (_Tex, i.texcoord) ;
                half3 c = DecodeHDR (tex, _Tex_HDR) ;
                c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb ;
                return half4(c,tex.a);
            }
            ENDCG
        }   
       //动态云和中景山
        Pass {
            Blend SrcAlpha OneMinusSrcAlpha 
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag       
            #include "UnityCG.cginc"
            half4 _Tint;
            half4 _Tint1;
            float _Rotation;
            fixed4 _CloudColor;
            sampler2D _Octave0;
            sampler2D _Octave1;
            sampler2D _Octave2;
            sampler2D _Octave3;
            float4 _Octave0_ST;
            float4 _Octave1_ST;
            float4 _Octave2_ST;
            float4 _Octave3_ST;
            float _Speed;
            fixed _Emptiness;
            fixed _Sharpness;       
            samplerCUBE _Tex2;
            float _UVY;
            struct appdata {
                float4 vertex : POSITION;
                float3 texcoord : TEXCOORD0;
                 UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            struct v2f {
                float4 pos : SV_POSITION;       
                half4 uv0 : TEXCOORD0;
                half4 uv1 : TEXCOORD1;
                half2 uv2 : TEXCOORD2;
                float3 texcoord : TEXCOORD3;
                float3 texcoord1 : TEXCOORD4;
                 UNITY_VERTEX_OUTPUT_STEREO
            };
             float3 RotateAroundYInDegrees (float3 vertex, float degrees)
        {
            float alpha = degrees * UNITY_PI / 180.0;
            float sina, cosa;
            sincos(alpha, sina, cosa);
            float2x2 m = float2x2(cosa, -sina, sina, cosa);
            return float3(mul(m, vertex.xz), vertex.y).xzy;
        }
            v2f vert (appdata v) {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.pos = UnityObjectToClipPos(v.vertex);
                o.texcoord1 = v.vertex.xyz;
                    o.texcoord1 = half3(o.texcoord1.x,o.texcoord1.y + _UVY,o.texcoord1.z);  
                o.uv0.xy = TRANSFORM_TEX(v.texcoord, _Octave0) + _Time.x * 1.0 * _Speed * half2(-1.0, 0.5);
                o.uv0.zw = TRANSFORM_TEX(v.texcoord, _Octave1) + _Time.x * 1.5 * _Speed * half2(-1.0, 1.0);
                o.uv1.xy = TRANSFORM_TEX(v.texcoord, _Octave2) + _Time.x * 2.0 * _Speed * half2(-1.0, -1.0);
                o.uv1.zw = TRANSFORM_TEX(v.texcoord, _Octave3) + _Time.x * 2.5 * _Speed * half2(-1.0, -0.5);        
                return o;
            }   
            fixed4 frag (v2f i) : SV_Target {
                fixed4 col = 0;
                float4 n0 = tex2D(_Octave0, i.uv0.xy);
                float4 n1 = tex2D(_Octave1, i.uv0.zw);
                float4 n2 = tex2D(_Octave2, i.uv1.xy);
                float4 n3 = tex2D(_Octave3, i.uv1.zw);
                      //分型布朗函数计算
                float4 fbm = 0.5 * n0 + 0.25 * n1+ 0.125 * n2 + 0.0625 * n3;
                fbm = (clamp(fbm, _Emptiness, _Sharpness) -  _Emptiness)/(_Sharpness - _Emptiness);
                      //光线穿透云层半透
                fixed4 ray = fixed4(0.0, 0.2, 0.4, 0.6);
                fixed amount = dot(max(fbm - ray, 0), fixed4(0.25, 0.25, 0.25, 0.25));
                col.rgb = amount  +  2.0 * (1.0 - amount) * 0.4;
                col.a = amount * 1.5;   
                half4 tex2 = texCUBE (_Tex2, i.texcoord1);                              
            return  tex2*(1-col.a) + col*col.a * _CloudColor;
            }
            ENDCG
        }   
}
Fallback Off
}
上一篇下一篇

猜你喜欢

热点阅读