OpenGL/OpenTK填充内部空间

OpenGL/OpenTK填充内部空间,opengl,Opengl,我正在寻找一种用颜色“填充”三维几何体的方法,并且很可能在以后某个时候使用纹理 假设有那么一刻,你可以将你的头固定在一堵水泥墙中,从逻辑上说,你只能看到黑暗。然而,在OpenGL中,当您这样做时,由于剔除和几何图形的绘制方式,世界自然是中空和透明的。我想模拟其中的黑暗/颜色/纹理 我知道有些游戏是通过将纹理/颜色直接覆盖在hud上来实现的,因此会使玩家失明 不过,还有别的方法吗?假设运动员一半站在水中;他们可以部分地看到波浪下面。你将如何填充它,以防止他们能够清楚地看到屏幕下方现在是他们屏幕的一

我正在寻找一种用颜色“填充”三维几何体的方法,并且很可能在以后某个时候使用纹理

假设有那么一刻,你可以将你的头固定在一堵水泥墙中,从逻辑上说,你只能看到黑暗。然而,在OpenGL中,当您这样做时,由于剔除和几何图形的绘制方式,世界自然是中空和透明的。我想模拟其中的黑暗/颜色/纹理

我知道有些游戏是通过将纹理/颜色直接覆盖在hud上来实现的,因此会使玩家失明

不过,还有别的方法吗?假设运动员一半站在水中;他们可以部分地看到波浪下面。你将如何填充它,以防止他们能够清楚地看到屏幕下方现在是他们屏幕的一半


这个概念被称为什么?

这似乎与浏览所谓的“参与媒体”有关。在不太极端的一端,你会有轻雾,或烟雾。在中间,可以说,脏水。极端的情况是你的头在墙上的例子

以物理上精确的方式进行此操作并不简单,因为介质厚度越大,变暗效果越明显

但是你可以通过做一些假设,通过减少照明或使用较暗的颜色,使室内几何体(水下或墙内)更暗,来假装这一点。如果您关心深度效果,请查看OpenGL和fog

在水下,你可以把水的背面变成半透明的颜色,这样上面的东西就会有适当的颜色变化


如果你真的想准确地发疯,看看卡佳的。这涵盖了所有东西(包括发光的东西),但通常需要简化和近似才能更有用。

摄影机方法前面的纹理存在一个问题,即纹理是二维的,但您希望可视化三维体积的切片。关于你谈论的第一件事,头内墙的想法,我将向你指出“3D/体积纹理”。在水中对半站立时,您需要具有吸收功能的“体绘制”(由@user3670102讨论)

三维纹理 这里的总体思路是,您有一些函数,可以定义3D空间中任何地方的颜色,而不仅仅是曲面上的颜色(与常规纹理贴图一样)。这很好,因为您可以将几何体放置在任何位置,并根据3D位置在片段着色器中为其着色。想象一下,在卷中切一片,然后观察交叉点的颜色

对于迎面而来的效果,您可以在播放器前面绘制一个全屏多边形(就在近剪裁平面上,尽管您可能希望将其向前推一点,使其不太小),并根据3D功能对其进行着色。现在,它看起来很坚固,移动广告,而不是像你廉价地在屏幕上粘贴纹理一样

实际功能可以用3D纹理定义,但这需要大量内存。相反,您可以查看程序3D颜色(例如,程序木材或砖块着色器非常常见)。即使假设2D纹理通过体积“拉伸”也可以,或者更好的方法是根据绘制的相交点/曲面的角度为3个纹理(每个轴一个)加权

检测几何体与近剪裁平面的交点可能是这里最难的部分。如果我是你,我会看看z缓冲区的技巧,确保把所有东西都画成实心的非自交几何体。一个简单的想法可能是仅在使用前面绘制所有内容之后才绘制背面。如果你能看到背面,那近平面的一部分一定在某个东西里面。对于这些像素,可以计算世界空间中的近剪裁平面位置并应用3D纹理。尽管我怀疑有比把所有东西都画两次更快的方法

在现实中,可能没有光线到达你所看到的东西,它应该是黑色的,但我想忽略这一点,直接渲染颜色,不发光

吸收 这听起来比实际情况要困难得多。如果你有一个透明的固体,所有的颜色都是一样的(“均质”),那么它会移除光线,进一步的光线必须穿过它。想象许多阿尔法透明的表面,接受极限,你会有一个指数。剩余的灯光接近
1/exp(dist)
exp(-dist)
。谷歌“啤酒定律”。从

通过某种东西寻找距离的一个很好的方法是使用一个将距离绘制到浮点纹理的着色器,使用加法混合渲染背面(或海底/水底)。然后切换到减法混合并渲染所有正面(或水面)。剩下的纹理包含上述等式的距离/深度

体绘制
结合这两种想法,材料都是透明的固体,但颜色(可能还有密度)在整个体积中都有所不同。如果你有大量的数据,并且希望数据速度快,那么这就变得相当复杂了。渲染这种效果的直接方法是通过3D纹理(或程序函数,无论您使用什么)对光线进行数值积分,同时应用吸收函数。基本的强力欧拉积分可能会为近平面上的每个像素启动一条光线,然后以相等的距离向前移动。在你行进的每一步中,你假设颜色保持不变,并应用吸收,跟踪你剩下多少光。一个快速的谷歌出现。

在新的GTA 5中,我四处走动,去海滩思考这个问题。我走进水里,才意识到开发商避开了波浪下的视线。摄像机保持在其上方,但当玩家到达一定深度时,他们会将摄像机“捕捉”到波浪下方。我翻译
vec3 Absorbance = WaterColor * WaterDensity * -WaterDepth;
vec3 Transmittance = exp(Absorbance);