【问题标题】:OpenGL 3D textures and mapping on part of a quadOpenGL 3D 纹理和四边形部分的映射
【发布时间】:2011-01-27 22:15:01
【问题描述】:

我正在制作一个Minecraft-ish 地形引擎来学习一些 OpenGL 和 3D,除了我不满意的 FPS 之外,一切都很好。

当前:我目前只绘制可见面并使用平截头体剔除,立方体为 16 x 16 x 32 立方体块(目前)。

我每个块使用 6 个显示列表,每边一个(左、右、前、后、上、下),所以立方体不是一个一个地绘制,而是整个块的一面。

使用这种方法,我可以得到大约 20-100fps,这不是很好。分析说我向显卡发送了大约 100k 个顶点,当我看到天空并且顶点低于 10k 时,我的速度高达 200+fps,所以我想这是我的瓶颈。

我想做的事:因为少即是多,所以我继续前进并找到了这个:http://ogre3d.org/forums/viewtopic.php?f=2&t=60381&p=405688#p404631

据我了解,Kojack 使用巨大平面的 3D 网格,并以某种方式将 2D 纹理图集中的纹理绘制到这些巨大平面的某些位置。他说他使用 256x256x256 的 3D 纹理和绿色和蓝色通道来映射到 2D 纹理图集。

他的方法总计平面的顶点数是恒定的,如果应用我的地图,有时是无用的,但仍然比我现在拥有的少。

我的问题:他说的我没听懂:(,我想试试他的方法,但是我不明白他到底做了什么,主要是我觉得是我经验不足使用 3D 纹理(我想象的是一块像素)。他是如何将纹理从纹理图集映射到平面的一部分的,而这通过使用一些 3D 纹理贴图...

谁能解释一下 Kojack 做了什么,或者给我指出一些有用的地方,即使是谷歌现在也没有任何帮助。

【问题讨论】:

  • 我不知道着色器是什么,所以我想我没有使用它们,但我广泛使用 glVertex3f,所以我猜是固定功能。
  • 硬件:P4 3GHz 与 ATI Radeon X1600。 Minecraft 至少以 200FPS 的速度运行。
  • 是的,如果您不使用着色器,Kojack 的方法将不适用。
  • 使用 2 个三角形,我得到大约 650fps = 1.5ms/帧。我还测试了 8 个(总是每个三角形的所有顶点都在屏幕上),相同的数字,所以对于少量的三角形(带纹理)大约需要 1.5 毫秒。
  • 从您的屏幕截图来看,我认为您正在为每个立方体侧面显示列表进行单个纹理绑定?总共约 6 个?

标签: opengl texture-mapping


【解决方案1】:

这是您问题的答案。首先,他将场景视为 256 x 256 x 256 的立方体。对于每个轴,他在每个轴值(即从 0,0,0 到 0,256,256,然后从 1,0,0 到 1,256,256 等等)渲染 256 个正方形(每个由两个三角形组成)立方体的全尺寸256,0,0 到 256,256,256)。然后,他面向另一个方向做同样的事情 - 使用相反的法线 - 每个轴总共有 512 个正方形 / 1024 个三角形。对 y 和 z 重复该过程,总共得到 3072 个三角形和 3072 个顶点(顶点仅出现在 256 x 256 x 256 立方体的边缘)。

现在是纹理。实际上,他正在绘制每个立方体,但是通过使纹理在该位置透明来使一些不可见。他有两个纹理,一个 256 x 256 x 256 3D 纹理和一个 16 x 16 texture atlas 由较小的纹理组成。为了绘制纹理,首先他使用他正在绘制的立方体的坐标作为 3D 纹理中的纹理坐标。因此,如果他在位置绘制立方体,例如42,7,13,则3D纹理坐标为42,7,13。在3D纹理内部,他存储的都是绿色和蓝色值,对应于要绘制的纹理图集中子纹理的u,v坐标。所以在他的例子中,3D 纹理中的颜色是 R = 0(未使用),G = 2,B = 4,A = 0(未使用)。他使用 2 & 4 作为 u, v 坐标,然后在纹理图集中的 2, 4 位置绘制纹理。由于纹理图集基本上只是一个巨大的纹理,对应于 16 x 16 (256) 个较小的纹理,因此只绘制较小的纹理之一(在这种情况下,2 和 4 将通过将它们除以 16 转换为纹理坐标,因此它们变为 2/16 = 0.125 和 4/16 = 0.25。这些对应于图集中位置 2,4 的子纹理的 0,0,而该子纹理的 1,1 位于 0.125 + 1 /16 和 0.25 + 1/16。这些坐标用于纹理立方体。

如果他想挖出一个立方体,他需要做的就是将那个点存储在3D纹理中的值更改为指向图集中的透明子纹理,所以如果纹理图集中的0,0是一个完全透明的子纹理,他可以在3D图集中将该位置的纹理设置为R = 0(未使用),G = 0,B = 0,A = 0(未使用)。

【讨论】:

  • 谢谢,但这是非常理论上的。我没有得到的是 3D 纹理:所以他将部分 3D 纹理映射到这 3072 个正方形上,从 3D 传递到 2D,然后他对特定纹理使用某种着色器(我必须阅读多一点)。他如何只修改纹理的一部分?我找不到任何可以做到这一点的功能 - 还是它特定于我不熟悉的 3D 纹理?
  • 3D 纹理仅用于查找。他将子立方体的位置视为 3D 纹理中的纹理坐标,这给了他一个颜色 RGBA,他只使用 GB 值作为 2D 纹理图集的查找。
【解决方案2】:

尝试将您的面部纹理放入texture atlas。每个面的纹理绑定方式太多了。

【讨论】:

  • 谢谢,这是瓶颈。现在我一直以大约 100 FPS 的速度运行。不是很好,我仍然想尝试 Kojack 的方法,但更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多