问题背景

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

解决方法

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

    目录 用法: 1.在base.js里导入layui插件 2.在使用的html页面里引入 base.js lucky.js index.html 用法: 1.在base.js里导入layui插件 2.在 ...

  2. IPv6 — 子网划分

    目录 文章目录 目录 前文列表 IPv6 的子网划分 前文列表 <IPv6 - 网际协议第 6 版> <IPv6 - 地址格式与寻址模式> <IPv6 - 协议头> ...

  3. IPv6 — 协议头

    目录 文章目录 目录 前文列表 IPv6 协议头格式 扩展报头 前文列表 <IPv6 - 网际协议第 6 版> <IPv6 - 地址格式与寻址模式> IPv6 协议头格式 IP ...

  4. [数字华容道] Html+css+js 实现小游戏

    [数字华容道] Html+css+js 实现小游戏 效果图 代码预览 在线预览地址 代码示例 <!DOCTYPE html> <html> <head> <m ...

  5. 【超详细】宝塔面板安装WordPress程序图文教程

    宝塔面板是目前广受用户喜爱的服务器控制面板之一,自己也在用,确实很方便,很多用户的网站都是基于宝塔面板搭建,今天简单介绍下宝塔面板是如何安装WordPress的,方便新手用户快速部署.也方便自己以后查 ...

  6. 大数据之Hadoop集群的HDFS压力测试

    测试HDFS写性能 原文:sw-code 1)写测试的原理 2)测试内容:向HDFS集群写10个128MB的文件(3个机器每个4核,2 * 4 = 8 < 10 < 3 * 4 =12) ...

  7. 【题解】A566.三点共线

    题目大意,给定在平面直角坐标系中的多个点,判断有多少个三元组 \((A, B, C)\) 满足共线性质. 题目链接:A566.三点共线. 大题思路就是暴力所有的三元组,判断三个元素的斜率是否相同即可. ...

  8. Android OpenMAX(八)如何学习OMXNodeInstance

    前面一篇文章中我们看到media.codec service创建OMX组件后会把组件传递给一个OMXNodeInstance对象,并且把OMXNodeInstance对象返回到Framework层,F ...

  9. Uni-app极速入门(一) - 第一个小程序

    Uni-app 介绍 官网:https://www.dcloud.io/index.html uni-app是为js开发者提供的一个全端开发框架,可以开发一次编译为web.App.小程序(微信/阿里/ ...

  10. React 中的 useRef 与 useState

    React 是一个流行的 JavaScript 库,用于构建用户界面.它提供了几个钩子,使开发人员能够管理状态并执行副作用. React 中两个常用的钩子是 useRef 和 useState .虽然 ...