初次尝试GPU Driver —— 大范围植被渲染之着色
2021/11/18 6:10:41
本文主要是介绍初次尝试GPU Driver —— 大范围植被渲染之着色,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
初次尝试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 —— 大范围植被渲染之着色的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-15JavaMailSender是什么,怎么使用?-icode9专业技术文章分享
- 2024-11-15JWT 用户校验学习:从入门到实践
- 2024-11-15Nest学习:新手入门全面指南
- 2024-11-15RestfulAPI学习:新手入门指南
- 2024-11-15Server Component学习:入门教程与实践指南
- 2024-11-15动态路由入门:新手必读指南
- 2024-11-15JWT 用户校验入门:轻松掌握JWT认证基础
- 2024-11-15Nest后端开发入门指南
- 2024-11-15Nest后端开发入门教程
- 2024-11-15RestfulAPI入门:新手快速上手指南