问题背景

在做地形模块时,需要根据实际地形高度画出世界相应的等高线,以及根据高度做颜色渐变,以及剖切功能。

解决方法

通过像素点在世界坐标系下的真实高度值来判断计算绘制等高线,剖切功能以及颜色渐变均有世界坐标实际高度值来判断,具体逻辑在代码中,这些均 在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实现地形中根据实际高度绘制等高线,剖切功能,颜色渐变等功能的更多相关文章

  1. Unity在Android和iOS中如何调用Native API

    本文主要是对unity中如何在Android和iOS中调用Native API进行介绍. 首先unity支持在C#中调用C++ dll,这样可以在Android和iOS中提供C++接口在unity中调 ...

  2. Unity脚本在层级面板中的执行顺序测试3

    断断续续的写了3篇,以后有时间可以做成一个系列了 前面2篇测试了GameObject的顺序,以及Awake和OnEnable的时机: Unity脚本在层级面板中的执行顺序测试1 http://www. ...

  3. Unity脚本在层级面板中的执行顺序测试4-附加整理

    测试4为一些附加内容,后续的各种tips都加在此. 前几篇测试的链接: Unity脚本在层级面板中的执行顺序测试1 http://www.cnblogs.com/hont/p/4298110.html ...

  4. 【Unity】Unity中C#与Android中Java的互相调用遇到的一些问题

    1.有关调用的一些问题: (1).在C#中直接调用java中的代码,无返回值: 在java中: public static void setAge(Context context , int leve ...

  5. OpenGL中shader读取实现

    1.需要shader在OpenGL中工作,必须经过如下过程 2.代码实现 /********** * loadshader.h **********/ #pragma once #define _CR ...

  6. DirectX11中Shader的封装

    引言 ​ 这个寒假学DirectX11的时候用的书是<Introduction to 3D Game Programming with DirectX 11>,里面关于Shader的部分全 ...

  7. (文档)Shader.Find (在编译时,只包含那些使用中的shader或位置在"Resources"文件夹中shader)

    Shader.Find 查找 static function Find (name : string) : Shader Description描述 Finds a shader with the g ...

  8. Unity模块嵌入到Android中

    嗨,大家好,小黑在沉寂了6个月之后,终于要继续写一篇博客了. 先吐槽一波上家公司PHD&&OMS,不吐不快.上家公司的小黑,每天不是在弄UIWidgets,就是再弄UIWidgets, ...

  9. Unity问答——怎么知道屏幕中目前有多少个敌人?

    这篇博客源自我在泰课在线的回答.链接:http://www.taikr.com/group/1/thread/92 问:怎么知道屏幕中目前有多少个敌人? 答: 思路一:仅适用于2D游戏,因为这个方法没 ...

  10. 【Unity】4.3 地形编辑器

    分类:Unity.C#.VS2015 创建日期:2016-04-10 一.简介 Unity拥有功能完善的地形编辑器,支持以笔刷绘制的方式实时雕刻出山脉.峡谷.平原.高地等地形.Unity地形编辑器同时 ...

随机推荐

  1. git学习--GitHub上如何进行PR(Pull Request)操作

    目录 一.前言 二.实现步骤 2.1 将小红在GitHub上的Repository clone到小明的本地电脑 2.1.1 fork小红在GitHub上的Repository到小明的GitHub 2. ...

  2. 07. C语言程序执行流程控制

    [有条件执行语句] if esle 语句 if else 语句根据一个条件确定是否执行一段代码,执行条件是一个布尔值,布尔值为true则执行,为false则不执行,同时可以设置不符合条件时执行的语句. ...

  3. addEventListener添加事件监听

    removeEventListener移除事件监听 window.addEventListener('mousedown', e => this.closeMenu(e)) window.add ...

  4. Atera 用户为最终用户提供对办公计算机的远程访问

    ​一言以蔽之:由 Splashtop 提供支持的 Atera 的客户远程访问功能允许使用 Atera 的 MSP 设置和管理其最终用户对办公计算机的远程访问. 新冠肺炎大流行已加速了全球远程工作的进程 ...

  5. Ubuntu Snap 简述

    Ubuntu Snaps Ubuntu Snaps 是 Ubuntu 的母公司 Canonical 于 2016 年 4 月发布 Ubuntu16.04 LTS(LongTermSupport,长期支 ...

  6. pageoffice6提取word指定位置(数据区域)的值

    在实际的开发过程中,经常会遇到提取Word文档中指定位置的数据保存到数据库中的需求,PageOffice客户端控件即支持在线保存Word文件,也支持Word文档中的指定位置的数据或所有的数据提交到服务 ...

  7. 微信公众号,微信小程序,百度小程序免费发放了

    小程序免费领取了,是真的免费哦 每人限领一套,100%开源,无后门 免费领取方式直接看tpframe官方网站

  8. Istio(八):istio安全之认证,启用mTLS

    目录 一.模块概览 二.系统环境 三.istio认证 3.1 证书创建与轮换 3.2 对等认证和请求认证 3.2.1 对等认证 3.2.2 请求认证 3.3 mTLS 3.3.1 双向 TLS 3.3 ...

  9. 【C#】爬取百度贴吧帖子 通过贴吧名和搜索关键词

    背景:最近喜欢看百度贴吧,因为其内容大多都是吧友的真实想法表达等等原因.但是通过网页去浏览贴吧,始终觉得不够简介,浏览帖子的效率不高,自己就萌发了通过自己爬取贴吧感兴趣的关键字内容,自己写了个winf ...

  10. 领域驱动设计(Domain-Driven Design,简称DDD)【简介 个人学习笔记】

    找到了第 1 篇资料:领域驱动设计详解:是什么.为什么.怎么做? - 知乎 找到了第 2 篇资料:领域驱动架构(DDD)建模中的模型到底是什么? - 知乎 找到了第 3 篇资料:一文看懂DDD 领域驱 ...