unity中Shader實現地形中根據實際高度繪制等高線,剖切功能,顏色漸變等功能


問題背景

在做地形模塊時,需要根據實際地形高度畫出世界相應的等高線,以及根據高度做顏色漸變,以及剖切功能。

解決方法

通過像素點在世界坐標系下的真實高度值來判斷計算繪制等高線,剖切功能以及顏色漸變均有世界坐標實際高度值來判斷,具體邏輯在代碼中,這些均 在shder 中為的fragment階段進行,

Shader代碼

 1 Shader "Custom/StratumFrontShader" {
 2     Properties{
 3         _FristColir("MainColor", color) = (0,1,0,1)           //第一種顏色:綠
 4         _SecondColor("SecondColor", color) = (1,0,0,1)       //第二種顏色:紅
 5         _Diffuse("Diffuse", Color) = (1,1,1,1)
 6 
 7         _K("K", float) = 0.8
 8         _P("P", float) = 0.8
 9     }
10     SubShader {
11         pass {
12             CGPROGRAM
13             #pragma vertex vert
14             #pragma fragment frag
15             #include "unitycg.cginc"
16             #include "Lighting.cginc"
17 
18             fixed4 _Diffuse;
19             uniform half _K;
20             uniform half _P;
21 
22             //高低點顏色
23             fixed4 _FristColir;
24             fixed4 _SecondColor;
25             
26             //高低點值
27             float _HighValue;
28             float _LowValue;
29              
30             //是否顯示等高線
31             float _IsShowContour=0;
32 
33             //等高線密集比例
34             float _ContourScale=0.12;
35 
36             //是否是同一顏色
37             float _IsSameColor=0;
38 
39              //是否開啟剖切
40              float clipping;
41              float3 clipPlanePosition;
42              float3 clipPlaneNormal;
43 
44 
45             struct v2f {
46                 float4 pos:POSITION;
47                 float y : TEXCOORD1;
48                 fixed3 worldNormal: TEXCOORD2;
49                 fixed3 worldPos: TEXCOORD3;
50             };
51 
52             v2f vert(appdata_base v)
53             {
54                 v2f o;
55                 o.pos = UnityObjectToClipPos(v.vertex);
56                 o.worldNormal = UnityObjectToWorldNormal(v.normal);
57                 o.worldPos=mul(unity_ObjectToWorld,v.vertex).xyz;
58                 o.y = v.vertex.y;
59                 return o;
60             }
61             fixed4 frag(v2f IN):COLOR
62             {
63                float y = IN.y;
64     
65              //剖切邏輯
66               if ( clipping > 0.0 ) {
67                 float  r = dot( normalize( IN.worldPos - clipPlanePosition ), clipPlaneNormal );
68                  if ( r > 0.0 ) {
69                     discard;
70                  }
71                }
72 
73                //等高線
74                float f = abs( frac( y * _ContourScale ) - 0.5 );  
75                float df = fwidth( y * _ContourScale );             
76                float g = smoothstep( -df * 2, df * 2, f );
77                float3 lineCol = float3( 0.0, 0.0, 0.0 );
78 
79                //顏色隨高度漸變
80                float h=saturate((_HighValue-y)/(_HighValue-_LowValue));
81                h = _IsSameColor == 0 ? h : 0;//同一種顏色時為第一默認色
82                fixed3 col = lerp( _FristColir, _SecondColor, h );
83                g = _IsShowContour == 0 ? g : 1;
84                col = lerp( lineCol, col, g );
85 
86                //光照
87                float3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
88                float lightDot = clamp(dot(IN.worldNormal, worldLightDir), -1, 1);
89                lightDot = exp(-pow(_K* (1 - lightDot), _P));
90                float3 diffuse = _LightColor0.rgb * col * lightDot;
91                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
92                fixed3 color0=ambient + diffuse;
93 
94               return (fixed4(color0,1));
95             }
96             ENDCG
97         }
98     }
99 }

ps:剖切功能:在於實際坐標點與剖切面的夾角選擇性剔除。漸變功能:根據高度區間變換做的混合,等高線:高度值根據設定參數計算,插值出等高線。

這里是我功能源代碼,這里做了剖切和顏色漸變和光照,提供給大家做個參考吧。

效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM