大气层Shader(完整代码分享)

老规矩先上图:
大气层Shader(完整代码分享)_第1张图片

实现解析:
一、模型用的是Unity自带的Sphere
大气层Shader(完整代码分享)_第2张图片
二、因为有透明的过度,所以需要设置为透明的
大气层Shader(完整代码分享)_第3张图片
三、因为大气是包裹地球,并在地球底层的因而我们使用到的是模型的背面
大气层Shader(完整代码分享)_第4张图片
四、最后是得用球面的法线与射线机的角度,算出越靠近边缘超透明的效果,因为需求需要我这里云和背景的纯色是分开计算的。
大气层Shader(完整代码分享)_第5张图片
下同是完成代码分享

Shader "Custom/Aerosphere" {
	Properties{
		   [Header(Texture)]
				  _MainTex("RGB:基础色 A:环境遮罩",2D) = "white"{}
				  _NormMap("RGB法线贴图",2D) = "bump"{}
		   [Header(Diffuse)]
				  _MainCol("基本色",Color) = (0.5,0.5,0.5,1.0)
		   [Header(Fresnel)]
				  _FresnelPow("菲涅尔次幂",Range(0,5)) = 1
				  _FresnelPow2("云朵菲涅尔次幂",Range(0,20)) = 1
					  _Scale("缩放",Float) = 0.5
	}
		SubShader{
					  Tags{
					"RenderType" = "Transparent"
						   "Queue" = "Transparent"
						   "ForceNoShadowCasting " = "True"
						   "IgnoreProjector" = "True" }
		Pass{
			   Tags{"LightMode" = "ForwardBase"}
			   Blend SrcAlpha OneMinusSrcAlpha
			   Cull Front
			   CGPROGRAM
			   #pragma vertex vert
			   #pragma fragment frag
			   #include "Lighting.cginc"
			   #include "AutoLight.cginc"
			   #include "UnityCG.cginc"
			   #pragma multi_compile_fwdbase_fullshadows
			   #pragma target 3.0
					  //Texture
					  uniform sampler2D _MainTex;
					  uniform fixed4 _MainTex_ST;
					  uniform sampler2D _NormMap;
					  //Diffuse
					  uniform float3 _MainCol;
					  //Specular
					  uniform float _FresnelPow;
					  uniform float _FresnelPow2;
					  uniform float _Scale;
					  
					  //输入结构
					  struct a2v {
							float4 vertex:       POSITION;            //顶点信息
							float2 uv0:          TEXCOORD0;           //UV信息
							float4 normal:       NORMAL;                    //法线信息
							float4 tangent:      TANGENT;             //切线信息
					  };
					  //输出结构
					  struct v2f {
							float4 pos:SV_POSITION;                  //屏幕定点位置
							float2 uv0:TEXCOORD0;                    //UV
							float3 posWS:TEXCOORD1;                  //世界坐标位置
							float3 nDirWS:TEXCOORD2;          //世界坐标法线
							float3 tDirWS:TEXCOORD3;          //世界坐标切线
							float3 bDirWS:TEXCOORD4;          //世界坐标副切线
							LIGHTING_COORDS(5,6)              //投影相关
					  };
					  v2f vert(a2v v) {
							v2f o;                                                                      //新输出结构
							o.pos = UnityObjectToClipPos(v.vertex);                //顶点位置    OS>CS
							o.uv0 = v.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;;                                                              //传弟UV
							//o.uv0.x = o.uv0.x -0.5 * o.uv0.y * (_Scale);//o.uv0.y*_
							o.posWS = mul(unity_ObjectToWorld, v.vertex);   //点位置     CS>WS
							o.nDirWS = UnityObjectToWorldNormal(v.normal);  //法线位置   OS>WS
							o.tDirWS = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz,0)).xyz);           //切线方向
							o.bDirWS = normalize(cross(o.nDirWS,o.tDirWS)*v.tangent.w);              //副切方向
							TRANSFER_VERTEX_TO_FRAGMENT(o);                               //投影相关
							return o;
					  }
					  float4 frag(v2f i) :SV_TARGET{
						  //向量准备
						  float3 nDirTS = UnpackNormal(tex2D(_NormMap,i.uv0)).rgb;
						  float3x3 TBN = float3x3(i.tDirWS,i.bDirWS,i.nDirWS);
						  float3 nDirWS = normalize(mul(nDirTS, TBN));
						  float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);
						  float3 vrDirWS = reflect(-vDirWS, nDirWS);
						  float3 lDirWS = _WorldSpaceLightPos0.xyz;
						  float3 lrDirWS = reflect(-lDirWS,nDirWS);
						  //中间量准备
						  float ndotl = dot(nDirWS, lDirWS);
						  float vdotr = dot(vDirWS, lrDirWS);
						  float vdotn = dot(vDirWS, nDirWS);
						  //纹理采样
						  float4 var_MainTex = tex2D(_MainTex, i.uv0);
						  //光照模型
								 //环境镜面反射
								 float fresnel = pow(max(0.0, -vdotn), _FresnelPow);//菲涅尔
								 float fresnel2 = pow(max(0.0,  - vdotn), _FresnelPow2);//菲涅尔
								 //光源漫反射
								 var_MainTex.a = var_MainTex.a *fresnel2;
								 float3 baseCol = var_MainTex.aaa+(_MainCol*(1 - var_MainTex.a));

								 //返回值
						   return fixed4(baseCol.rgb, max(0, (fresnel.r-0.5)*5));
					}
					ENDCG
			 }
				  }
}

你可能感兴趣的:(Shader,大气层Shader,星球Shader,大气Shader,大气层,地球Shader)