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 } } }
效果对比如下: