• 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:剖切功能:在于实际坐标点与剖切面的夹角选择性剔除。渐变功能:根据高度区间变换做的混合,等高线:高度值根据设定参数计算,插值出等高线。

    这里是我功能源代码,这里做了剖切和颜色渐变和光照,提供给大家做个参考吧。

    效果如下:

  • 相关阅读:
    Spring Boot启动命令参数详解及源码分析
    面试题-关于Java线程池一篇文章就够了
    Spring Boot中@ConditionalOnProperty使用详解
    Spring Boot通过ImportBeanDefinitionRegistrar动态注入Bean
    Spring Boot 注解之ObjectProvider源码追踪
    软件从业者不可不读的一本书
    SpringBoot之DispatcherServlet详解及源码解析
    书终于交稿了,聊聊写技术书这件事
    Python IDE:pycharm
    python安装
  • 原文地址:https://www.cnblogs.com/answer-yj/p/12533537.html
Copyright © 2020-2023  润新知