ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-11-18 01:31:23  阅读:286  来源: 互联网

标签:color Driver vertex 着色 float4 wcoord GPU sin float2


初次尝试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倍后,画面如下:

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;

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

最终渲染
最终渲染

标签:color,Driver,vertex,着色,float4,wcoord,GPU,sin,float2
来源: https://www.cnblogs.com/mmc1206x/p/15570374.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有