漂浮岛场景WebGL效果解析

访问在线地址,代码在此处

场景构图

该场景使用了3个岩石模型,一些通用的阙类植物、树木模型,还有空中的鸟类模型。

场景的渲染顺序:深度预通道,岩石,鸟类,天空,云粒子。
1_x1lNILGL3C-JzpJ8WN4boA.gif

相机路径和物体放置

为了能造成一种无尽的随机场景的效果,有两种选择:真正的随机场景和循环生成的路径。第一种需要将对象动态放置在相机前面,但是这意味着这些位置必须动态传输到 GPU。因此,更好的选择是生成一次静态循环的路径,并在相机移动时沿其路径绘制对象。

可以在 ObjectPlacement.ts 文件的positionOnSpline函数中找到用于生成基本样条线的函数。它为具有动态变化半径的相机创建一条环形路径。应用几个谐波来随机化圆半径,因此它看起来虽然是随机的,但仍然是比较完美的循环路径。然后,所有物体都放置在这条路径周围:树木位于相机下方,岩石位于上方和两侧。

对象的位置和旋转以 GPU 纹理的形式存储在类型化数组 Float32Array 中。

Renderer.ts 中的 drawInstances 方法渲染仅从样条线上的某个点可见的对象。由于场景简单,无需使用视锥体剔除(对象是在相机前后一定距离处绘制的)。此可见距离略大于雾开始距离,因此新对象看起来完全被雾覆盖并且不会出现。实例是从前到后排序的,因此在绘制时它们会使用 Z 缓冲区剔除。

只有岩石和树木模型才会以这种方式沿着相机路径放置。鸟群使用特定的线性路径,并能以最少的路径覆盖场景的整个区域。

以下是可视化的相机路径,仅在其附近渲染了一部分对象:
1_tb9w5J2ws0G96MzS5_jhBw.gif

雾效立方体贴图

最初的实现是使用了颜色均匀的雾,但是看起来相当普通。为了添加更多来自不同方向的颜色变化(例如太阳光晕),我们决定使用立方体贴图来实现雾效,这样我们可以通过创建立方体贴图并调整场景预设中的几种颜色来完全改变整个场景的外观。如果是一张全景贴图的话,我们可以使用数字孪生平台的全景图转盒子贴图工具将全景图图像转换为 6 个立方体贴图,然后调整它们的旋转以适合我们的坐标系 (Z-up)。

可以在 FogShader.ts 的静态常量中找到立方体贴图雾的实现。所有雾着色器都使用它们。顶点着色器用于颜色混合的最终雾系数,也包含高度雾系数。

在Web演示用户界面中,可以调整不同的雾参数: 起始距离(fogStartDistance)、过渡距离(fogDistance)、高度偏移(fogHeightOffset)和高度乘数(fogHeightMultiplier)。此外,更改一天中的场景时间是通过为每个预设使用不同的立方体贴图纹理和几种颜色来完成的。

岩石上的草

为了让岩石不那么突兀,我们还在它们上面应用了草的纹理。该技术通常用于模拟被雪覆盖或被雨水浸泡的表面。草纹理与基于顶点法线的岩石纹理混合。可以使用 UI面板 中的grassAmount 滑块来查看它如何影响草在岩石上的分布。

在岩石顶部应用草纹理的着色器的源代码位于 FogVertexLitGrassShader.ts 中。

云的渲染

云不是实例化的,而是逐个绘制的,因为这些对象的变换矩阵必须调整为始终面向相机。它们的数量并不多,因此不会添加太多的draw call。实际上,如果 GPU 状态未更改(未更新uniform、切换混合模式等),那么即使是非实例渲染在现代移动和桌面 GPU 上也相当快。

这个着色器还有一个小技巧。当相机飞过云层时,它们可能会被近剪裁平面突然剔除。为了防止这种情况发生,应用了一个简单的_smoothstep_来实现在相机前面淡入淡出。可以在 FogSpriteShader 中找到代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搞GIS图形的sky.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值