天空球+云+山

我们平时做天空球的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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342