OpenGL/OpenTK填充内部空间

20

我正在寻找一种方法来为三维几何图形着色,以及可能在以后某个时候增加纹理。

假设你现在把头伸进了一堵混凝土墙里,你会看到纯黑色。然而,在OpenGL中,当你这样做时,由于裁剪和几何图形的绘制方式,世界是自然的空心和透明的。我想模拟其中的黑暗/颜色/纹理。

我知道有些游戏通过在hud上直接覆盖纹理/颜色来实现这一点--从而使玩家变得失明。

还有其他办法吗?假设玩家站在水中间,他们可以部分地看到水下面。如何填充才能防止他们清晰地看到现在屏幕的一半以下的东西?

这个概念叫什么?


1
在新的GTA 5中,我四处走动并去了海滩思考。我走进水里才意识到开发人员避免看到波浪下面。相机停留在上面,但当玩家达到一定深度时,他们会“捕捉”相机到波浪下面。我认为这是开发人员避免半进半出的必然性。然而,我发誓我以前见过游戏使用半进半出的机制。 - Krythic
2个回答

6
使用“相机前纹理”方法的问题在于,纹理是2D的,但您想要可视化3D体积的一个切片。对于您提到的关于头部穿过墙壁的想法,我会向您指出“3D /体积纹理”。对于半身浸入水中的情况,您需要使用“吸收”的“体积渲染”(由@user3670102讨论)。
3D纹理
这里的一般思想是您有一些函数,它定义了3D空间中的每个位置的颜色,而不仅仅是表面上的颜色(与常规纹理映射不同)。这很好,因为您可以将几何图形放置在任何位置,并根据3D位置在片段着色器中着色。想象一下通过体积进行切片并查看交点颜色。
对于头部进入墙壁的效果,您可以在玩家前面绘制一个全屏多边形(就在近裁剪平面上,尽管您可能希望将其向前推一点,以使其不太小),并根据3D函数对其进行着色。现在它看起来会适当地坚固,并随着玩家的移动而移动,而不像您只是便宜地将纹理贴在屏幕上。

enter image description here

实际函数可以用三维纹理来定义,但这会占用大量内存。相反,您可以尝试使用过程化的三维颜色(例如过程化木材或砖块着色器)。即使是假设一个二维纹理通过体积“挤压”也可以工作,或者更好的方法是基于您正在绘制的交点/表面的角度对三个纹理(每个轴一个)进行加权。
在这里检测几何图形和近裁剪平面的交点可能是最难的部分。如果我是你,我会看看z缓冲区的技巧,并确保将所有内容都绘制为实心的非自交几何。一个简单的想法可能是在绘制完所有正面后仅绘制背面。如果您能看到背面,则该近平面的某个部分必须在某物体内部。对于这些像素,您可以计算世界空间中的近裁剪平面位置并应用三维纹理。虽然我怀疑除了两次绘制所有内容之外,还有更快的方法。
实际上,可能没有光线照射到您所看到的物体,因此应该是黑色的,但我想只需忽略这一点并直接呈现颜色,无需照明。
吸收
这听起来比实际困难得多。如果你有一些完全相同颜色(“均匀”的)透明固体,那么它会移除光线,光线需要通过它传播的距离越远。想象许多α-透明表面,取极限,就得到一个指数函数。剩余的光线接近于1/exp(dist)exp(-dist)。谷歌“比尔定律”。从这里
vec3 Absorbance = WaterColor * WaterDensity * -WaterDepth;
vec3 Transmittance = exp(Absorbance);

一种通过渲染背面(或海床/水底)来找到距离的好方法是使用着色器以浮点纹理绘制距离,使用加法混合。然后切换到减法混合并渲染所有正面(或水面)。这样你就得到了一个包含上述方程距离/深度的纹理。
体积渲染
将这两个想法结合起来,物质既是透明的固体,但颜色(和可能的密度)在整个体积中变化。如果数据量很大且需要快速处理,则会变得非常复杂。直接渲染它的一种简单方法是在三维纹理(或过程函数,无论你使用什么)中数值积分射线,同时应用吸收函数。基本的暴力欧拉积分可以为近平面上的每个像素启动一条射线,然后以均匀距离向前移动。在每个步骤中,您假设颜色保持不变并应用吸收,跟踪剩余的光量。快速搜索this

好的,我已经两次挂出赏金请求了,而你迄今为止给出了最好的答案。干得好,谢谢。 - Krythic

3
这似乎与查看所谓的“参与媒体”有关。在较不极端的情况下,您可能会遇到轻雾或烟雾。在中间可能是脏水。极端情况将是您头部进入墙壁的示例。
以物理准确的方式进行此操作并不容易,因为当媒体的厚度更大时,变暗效果更加明显。
但是,您可以通过做出一些假设并使内部几何形状(在水下或墙内)变暗来模拟此过程,例如减少照明或使用较暗的颜色。如果您关心深度效果,请查看OpenGL和雾。
对于水下,您可以使水的背面成为半透明颜色,从而导致其上方的物体颜色发生适当的变化。
如果您真的想要精确地进行操作,请查看Kajia的渲染方程。它涵盖了所有内容(包括发光的东西),但通常需要简化和近似才能更有用。

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