OpenGL中的水渲染

3

我完全不知道如何渲染水源(海洋、湖泊等)。每个教程都假定我已经具备基础知识,因此对这个问题进行抽象论述,但我并没有。

我的目标是在我的地形中拥有一个基于高度的水位。

我找不到任何好的文章来帮助我入门。


绘制一个单一的透明蓝色四边形,使用所需高度的 alpha 混合。这样做过于简单,但你想要多复杂呢? - jozxyqk
@jozxyqk 我希望它具有可控的波高、反射和法线贴图。 - McLovin
1个回答

16

这个问题比较广泛。我会将它分解成单独的组件,逐个进行处理。希望这能帮助缩小可能存在的问题范围,不幸的是,我只能提供高层次的讨论,而非你直接需要的答案。

波浪模拟(几何和动画):

一种程序化方法可以基于某些噪声函数为位置和时间提供固定的高度。一个非常基本的想法是y = sin(x) + cos(z)。一些更复杂的例子可以在GPUGems中找到。

enter image description here

就像图片中一样,您可以通过 创建网格,在网格 x,y 位置采样高度 (y) 并用三角形连接这些点来渲染几何图形。

如果您明确地在一个二维数组中存储了所有高度,您可以创建一些相当不错的波浪和涟漪。这里的想法是基于相邻高度更新高度,使用一些简单的规则。例如,每个高度向平均相邻高度移动,但也趋向于平衡高度等于零。为了使其有效运行,高度需要具有速度值以给水体动量。

我在这里找到了一些这种动态水的示例:

height_v[i][j] += ((height_west+ height_east + height_south + height_north)/4 - height[i][j]);
height_v[i][j] *= damping;
height[i][j] += height_v[i][j];

渲染:

使用透明度是制作水效果的一个很好的第一步。在模拟运行正常之前,我会从这里开始。您需要的主要效果是反射,因此我将仅介绍这个。稍后,您可能需要使用菲涅尔比例来缩放反射值。您可能希望基于距离(参见Beer定律,本质上是exp(-distance * density))在水下产生吸收效应(如雾)。如果变得非常花哨,您可能希望使用折射来渲染水的下面部分。但现在回到反射...

最简单的渲染平面反射的方法可能是模板反射,其中您将从水下绘制场景,并使用模板缓冲区仅影响先前绘制水的像素。

这里有一个示例here

enter image description here

然而,当你的表面崎岖不平且反射光线被扰动时,这种方法就不起作用了。
与其直接将水下反射视图渲染到屏幕上,你可以将其渲染到纹理中(翻译:在纹理中生成)。然后在渲染水体时就有了反射的颜色信息。棘手的部分是计算反射向量后确定从纹理的哪个位置进行采样。
一个例子可以在这里找到。

enter image description here

这个使用纹理,但仅用于完美平面的反射。

另请参阅:如何在OpenGL中绘制镜子反射?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接