初次尝试GPU Driver —— 大范围植被渲染之着色

《初次尝试GPU Driven —— 大范围植被渲染》中实现了草地分布,本文实现草的着色。

本文分四个部分:

  • 生成网格
  • 随机调整
  • 着色
  • 风场

生成草网格

网格形状通常有矩形和三角形,本文使用三角形的网格。

上图从左到右依次提高细节。

随机调整

用上一步生成的网格渲染,会看到这样的画面。

很显然,分布的太整齐了,草丛不是整齐排列的,所以每颗草不能都用一样的方向和大小渲染,在这一步将草随机一下。思路是通过草的世界坐标得出随机值,用该随机数去旋转&缩放顶点,因为每颗草的世界坐标是固定的,所以随机数也是固定的,又因为每颗草的坐标都不一样,所以随机数也可能会不一样(这不是病句)。

随机数的计算方法有很多,只要让其尽可能乱就行了,计算出缩放和旋转后,再加上之前算出来的世界坐标,就可以构建变换矩阵了。

float3 wcoord = _GrassCoords[instanceID];

...

float random(float2 pos)
{
return frac(sin(dot(pos, float2(12.9898, 78.2330))) * 1.9);
} ... // 平移/缩放/旋转
float rand = random(wcoord.xz);
// 随机缩放
float2 scale = lerp(float2(0.2, 0.5),
float2(0.3, 1.0), rand);
// 随机旋转
float2 rotate = float2(cos(rand * UNITY_PI * 2),
sin(rand * UNITY_PI * 2)); float4x4 transform = float4x4(float4(scale.x * rotate.x, 0, -rotate.y, wcoord.x),
float4( 0, scale.y, 0, wcoord.y),
float4( -rotate.y, 0, rotate.x, wcoord.z),
float4(0, 0, 0, 1)); ... o.wcoord = mul(transform, v.vertex);
o.vertex = UnityWorldToClipPos(o.wcoord);

草已经被打乱了,但每颗草太直了,接下来压弯每颗草,思路是将草往前倾斜,同时降低Y轴值,Y轴值越大,则倾斜越大,下压力越大。

float2 forward = float2(0, 1);
float2 offset = forward * scale.y * _Bend
* v.vertex.y * v.vertex.y;
v.vertex.xz += offset;
v.vertex.y -= length(offset);

把数量翻10倍后,画面如下:

着色

着色这部分简单处理,给定两个基础颜色,分别表示草的顶部和底部色,随后用Lambert光照着色。

float3 worldCoord = i.wcoord;
float3 worldNormal = normalize(i.normal);
float3 lightNormal = UnityWorldSpaceLightDir(worldCoord);
float4 color = lerp(_BottomColor, _TopColor, i.vcoord.y); fixed3 ambient = color * UNITY_LIGHTMODEL_AMBIENT.rgb;
fixed wDotL = max(0.2, dot(worldNormal,lightNormal));
fixed3 diffuse = color * wDotL * _LightColor0.rgb;
color.rgb += ambient;
color.rgb += diffuse;
return color;

风场

这一步加入风的影响,通过风向,风速,风力三个因素定义风,随时间挪动影响范围。

本文的风区分微风和强风,微风持续影响,强风按频率影响,可以抖动一下频率效果更佳。

本文强风用下图频率:

//  基础风
float3 wind = _WindDirect * _WindPower * v.vertex.y * v.vertex.y;
float windValue = tex2Dlod(_WindMask, float4(wcoord.xz / 64, 0, 0)).r;
// 微风
wcoord.xyz += wind * sin(_Time.y * _WindSpeed + dot(wcoord, _WindDirect)) * 0.3;
// 强风
wcoord.xyz += wind * saturate(sin(_Time.y * _WindSpeed + dot(wcoord, _WindDirect))) * windValue;
wcoord.xyz += wind * saturate(sin(0.75 * _Time.y * _WindSpeed + dot(wcoord, _WindDirect))) * windValue;
wcoord.xyz += wind * saturate(sin(0.25 * _Time.y * _WindSpeed + dot(wcoord, _WindDirect))) * windValue;

到此,渲染部分就结束了,下面展示一段加入高度图后的最终表现:



初次尝试GPU Driver —— 大范围植被渲染之着色的更多相关文章

  1. 初次尝试使用jenkins+python+appium构建自动化测试

    初次尝试使用jenkins+python+appium构建自动化测试 因为刚刚尝试使用jenkins+python+appium尝试,只是一个Demo需要很多完善,先记录一下今天的成果,再接再厉 第一 ...

  2. 孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库

    孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第三天.感觉这个东西学习起来还是那么困 ...

  3. 孤荷凌寒自学python第五十二天初次尝试使用python读取Firebase数据库中记录

    孤荷凌寒自学python第五十二天初次尝试使用python读取Firebase数据库中记录 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数 ...

  4. 孤荷凌寒自学python第五十一天初次尝试使用python连接Firebase数据库

    孤荷凌寒自学python第五十一天初次尝试使用python连接Firebase数据库 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库服 ...

  5. 微信小程序开发初次尝试-----实验应用制作(一)

    初次尝试微信小程序开发,在此写下步骤以做记录和分享. 1.在网上找了很多资料,发现这位知乎大神提供的资料非常全面. 链接 https://www.zhihu.com/question/50907897 ...

  6. 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试

    20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ...

  7. CPU与GPU区别大揭秘

    http://blog.csdn.net/xiaolang85/article/details/51500340 有网友在网上提问:“为什么现在更多需要用的是 GPU 而不是 CPU,比如挖矿甚至破解 ...

  8. 初次尝试python爬虫,爬取小说网站的小说。

    本次是小阿鹏,第一次通过python爬虫去爬一个小说网站的小说. 下面直接上菜. 1.首先我需要导入相应的包,这里我采用了第三方模块的架包,requests.requests是python实现的简单易 ...

  9. 怎样对ZBrush中的材料进行渲染和着色

    ZBrush可以实时的进行不断的渲染和着色. 对于绘制操作,ZBrush®增加了新的范围尺度,可以让你给基于像素的作品增加深度,材质,光照和复杂精密的渲染特效,真正实现了 2D 与 3D 的结合,模糊 ...

  10. 跨平台渲染框架尝试 - GPU Buffer的管理(1)

    buffer资源 下面来谈谈buffer的管理.buffer资源从广义上就是C语言的数组.如下图所示. 图 buffer的广义模型 在渲染管线中,无论是opengl还是dx或者其他的渲染api,都会提 ...

随机推荐

  1. 每天学五分钟 Liunx 0110 | 服务篇:守护进程 systemd

    有些进程会在系统上运行较长时间,如前面的 Hello World 程序运行时产生的进程.有些进程运行瞬间就结束了,如执行 ps 命令产生的进程,也有的进程会常驻在内存中,提供相应的服务,这样的进程称为 ...

  2. SV interface and Program3

    时钟域的理解 在仿真过程中,时钟跳变的一瞬间,CPU将时间域划分为不同的时钟域执行不同的代码 信号在芯片中都是金属丝,在进行跳变的时候都是电容的充放电过程,通常使用时钟上升沿进行模拟,而不使用时钟下降 ...

  3. 【MicroPython】生成micropython版本头文件 - py\makeversionhdr.py

    用法 $ python makeversionhdr.py mpversion.h 实现 带git仓 get_version_info_from_git 使用git指令:   git describe ...

  4. SQLServer性能优化之二

    SQLServer性能优化之二 背景 优化了机器的硬件配置之后性能好了很多 但是偶尔还是会出现阻塞. SQL总是奇奇怪怪的. 其实第一天时就感觉可能是索引存在问题. 但是dbcc 重建所有数据库的索引 ...

  5. [转帖]TiDB 最佳实践

    https://docs.pingcap.com/zh/tidb/stable/tidb-best-practices 本文档总结使用 TiDB 时的一些最佳实践,主要涉及 SQL 使用和 OLAP/ ...

  6. [转帖]jmeter(八)断言

    https://www.cnblogs.com/pachongshangdexuebi/p/11582891.html jmeter中有个元件叫做断言(Assertion),它的作用和loadrunn ...

  7. [转帖]Kafka 核心技术与实战学习笔记(八)kafka集群参数配置(下)

    一.Topic级别参数 Topic的优先级: 如果同时设置Topic级别参数和全局Broker参数,那么Topic级别优先 消息保存方面: retention.ms:规定Topic消息保存时长.默认是 ...

  8. 【转帖】【奇技淫巧】Linux | 安全保障防火墙-iptables

    虽然说Linux在安全方面确实相当于windows要更加可靠一些,但一般使用其作为服务器的我们,也不能大意,也是需要严格限制网络传输过程中的出入规则.上篇文章我们有聊到统计网络的信息,这篇文章来学习一 ...

  9. [转帖]JAVA之G1垃圾回收器

    https://www.cnblogs.com/boanxin/p/12292331.html 概述 G1 GC,全称Garbage-First Garbage Collector,通过-XX:+Us ...

  10. webpack配置scss

    安装依赖: cnpm i sass-loader -D cnpm i node-sass -D node-sass尽量去使用cnpm去安装 创建index2.scss文件 div { h2 { bac ...