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:剖切功能:在于实际坐标点与剖切面的夹角选择性剔除。渐变功能:根据高度区间变换做的混合,等高线:高度值根据设定参数计算,插值出等高线。
这里是我功能源代码,这里做了剖切和颜色渐变和光照,提供给大家做个参考吧。
效果如下:

unity中Shader实现地形中根据实际高度绘制等高线,剖切功能,颜色渐变等功能的更多相关文章
- Unity在Android和iOS中如何调用Native API
本文主要是对unity中如何在Android和iOS中调用Native API进行介绍. 首先unity支持在C#中调用C++ dll,这样可以在Android和iOS中提供C++接口在unity中调 ...
- Unity脚本在层级面板中的执行顺序测试3
断断续续的写了3篇,以后有时间可以做成一个系列了 前面2篇测试了GameObject的顺序,以及Awake和OnEnable的时机: Unity脚本在层级面板中的执行顺序测试1 http://www. ...
- Unity脚本在层级面板中的执行顺序测试4-附加整理
测试4为一些附加内容,后续的各种tips都加在此. 前几篇测试的链接: Unity脚本在层级面板中的执行顺序测试1 http://www.cnblogs.com/hont/p/4298110.html ...
- 【Unity】Unity中C#与Android中Java的互相调用遇到的一些问题
1.有关调用的一些问题: (1).在C#中直接调用java中的代码,无返回值: 在java中: public static void setAge(Context context , int leve ...
- OpenGL中shader读取实现
1.需要shader在OpenGL中工作,必须经过如下过程 2.代码实现 /********** * loadshader.h **********/ #pragma once #define _CR ...
- DirectX11中Shader的封装
引言 这个寒假学DirectX11的时候用的书是<Introduction to 3D Game Programming with DirectX 11>,里面关于Shader的部分全 ...
- (文档)Shader.Find (在编译时,只包含那些使用中的shader或位置在"Resources"文件夹中shader)
Shader.Find 查找 static function Find (name : string) : Shader Description描述 Finds a shader with the g ...
- Unity模块嵌入到Android中
嗨,大家好,小黑在沉寂了6个月之后,终于要继续写一篇博客了. 先吐槽一波上家公司PHD&&OMS,不吐不快.上家公司的小黑,每天不是在弄UIWidgets,就是再弄UIWidgets, ...
- Unity问答——怎么知道屏幕中目前有多少个敌人?
这篇博客源自我在泰课在线的回答.链接:http://www.taikr.com/group/1/thread/92 问:怎么知道屏幕中目前有多少个敌人? 答: 思路一:仅适用于2D游戏,因为这个方法没 ...
- 【Unity】4.3 地形编辑器
分类:Unity.C#.VS2015 创建日期:2016-04-10 一.简介 Unity拥有功能完善的地形编辑器,支持以笔刷绘制的方式实时雕刻出山脉.峡谷.平原.高地等地形.Unity地形编辑器同时 ...
随机推荐
- vue2组件封装示例
组件封装注意事项: 1.props:属性.是父容器给子组件参数传递的桥梁 2.this.$emit:事件.子组件通知父容器事件发生,并给父容器传递数据和参数 3.子组件中经常要用watch监控数据变化 ...
- JDK源码阅读-------自学笔记(十八)(java.lang.Enum枚举类)
枚举类简介 如果有必要定义一组常量的时候使用 所有的枚举类型隐性地继承自 java.lang.Enum,枚举实质上还是类. 每一个枚举中的成员,就相当于枚举的一个对象,默认都是public stati ...
- 用pageOffice控件实现 office word文档 强制留痕编辑Word
OA办公中,业务需要多人编辑word文档,需要强制留痕功能,用来查看文档编辑过程中的具体修改痕迹. 怎么实现word文档的强制留痕呢? 1 实现方法 通过pageOffice实现简单的在线打开编辑wo ...
- 一文搞懂RESTful开发
REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描述形式 http: ...
- linux基础之awk命令详解
一 awk主要是用来对指定对文本或者命令的输出逐行处理和分析的,下面来简单的看一下awk用法,方便以后需要使用的时候在回头看 1.1 基础的用法 [root@wxm ~]# cat test 1 ...
- uniapp-vue3-oadmin手机后台实例|vite5.x+uniapp多端仿ios管理系统
原创vue3+uniapp+uni-ui跨端仿ios桌面后台OA管理模板Uni-Vue3-WeOS. uniapp-vue3-os一款基于uni-app+vite5.x+pinia等技术开发的仿ios ...
- Bear and String Distance
传送锚点: codeforces.com Copy 4 26 bear output roar input 2 7 af output db input 3 1000 hey output -1 思路 ...
- shell脚本的调试
参数: -n :读一遍脚本中的命令但不执行,用于检查脚本中的语法错误 -v :一边执行脚本,一边将执行过的脚本命令打印到标准错误输出 -x :提供跟踪执行信息,将执行的每一条命令和结果依次打印出来 使 ...
- Xcode Debugger Extremely Slow , Xcode Swift调试器调试时极其慢(😡)
一.Xcode 调试器 我的项目是国内某办公软件的iOS客户端, 代码量极其庞大, 编译一次至少30min以上. 关键是,如果你遇到问题的时候,调试下断点,需要至少5min才能断下来,走下一步,又重复 ...
- IOS Video Tool Box后台解码失败
---恢复内容开始--- 1.VideoToolBox硬件解码H264流的过程中,如果App从前台按Home键进入后台,会立马产生一个-12903的错误 如果这个时候重置解码器,继续解码,会遇到 - ...