Unity Shader实现太空中的大气层效果
发表于2018-12-18
本篇文章给大家介绍下shader实现太空中的大气层效果。

代码如下:
Shader "Custom/Atmosphere Glow"
{
Properties
{
//大气层的颜色
_AtmoColor("Glow Color", Color) = (1,1,1,1)
//大气层反射效果的强化量
_InnterRingFactor("Glow Factor", Float) = 5
//大气层相对于地表的偏移
_Offset("Vertex Offset", Float) = 0
}
SubShader
{
Tags
{
"IgnoreProjector" = "True"
"Queue" = "Transparent"
"RenderType" = "Transparent"
}
Pass
{
Blend One One
AlphaTest Greater 0.1
ColorMask RGBA
Cull Back Lighting Off ZWrite Off Fog{ Color(0,0,0,0) }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma glsl
#pragma target 3.0
uniform float _InnterRingFactor;
uniform float4 _AtmoColor;
uniform float _Offset;
struct VertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct VertexOutput
{
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1;
};
VertexOutput vert(VertexInput v)
{
VertexOutput o;
//获得顶点的发现方向
o.normalDir = normalize(mul(unity_ObjectToWorld,float4(v.normal, 0)).xyz);
//对原来的顶点进行偏移
v.vertex.xyz += (_Offset*v.normal);
//在世界中的顶点信息
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
//转换后得到偏移后的顶点信息
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
return o;
}
float4 frag(VertexOutput i) : COLOR
{
//视角方向
float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
//项目里没有使用光源,shader中模拟(0,0,0)点为太阳光照(点光源)
float3 lightDirection = normalize((0,0,0) - i.posWorld.xyz);
float ndl = dot(i.normalDir, lightDirection);
float ndv = dot(i.normalDir, viewDirection);
//实现的效果为内侧描边
//这里当ndv为正数时,指数越大,效果越小,ndv为负数时1-ndv为大于1的数,指数越大,效果越强
float3 innerRing = saturate(_AtmoColor.xyz * pow(1 - ndv,_InnterRingFactor)) ;
//光源方向参与到运算中
float3 finalColor = saturate(pow(ndl + max(0.2, dot(-lightDirection, viewDirection)), 3)) * (innerRing * 2) ;
return float4(finalColor, 1);
}
ENDCG
}
}
}
效果对比如下:


