OpenGL -相同物体的不同表面上的不同纹理



我正在尝试为我使用OpenGL制作的游戏绘制一辆汽车。car对象存储在.obj文件中,并附带一个.mtl文件。

汽车有500多个顶点,100多个面,需要50多个不同的纹理应用到它们上,使用我自己的顶点和片段着色器。我通过使用缓冲对象来解决这个问题,它一次发送关于我的对象的所有信息。我的问题是试图将不同的纹理应用到同一物体的不同表面。

我发现这个问题的答案是将纹理绑定到某个纹理编号(即GL_TEXTURE0, GL_TEXTURE1等),并将Sampler2D传递给引用它的片段着色器。然而,我可以用这种方式存储50多个纹理吗?据我所知,它去GL_TEXTURE32。

另外,我如何告诉着色器只将纹理应用于汽车对象的特定面?

你不能这样渲染模型,你一次绑定所有的纹理。一个片段着色器,即使是高端的GL 4.1类硬件,也只能访问16个纹理。也就是说,它只能有16个采样器。

总的纹理计数更高,因为其他着色器阶段也可以使用纹理。

正确的处理方法是:

  1. 返回到你的建模师,让他们减少模型的纹理计数。
  2. 使用工具构建纹理图集(即:将所有图像放入单个纹理中),适当更改模型的纹理坐标。根据你计划支持的硬件,这可以是一个大的2D纹理或2D纹理数组。后者需要纹理坐标的第三个值:数组中图像的索引。
  3. 按纹理排序三角形。对于每个纹理,渲染所有使用该纹理的三角形。

#3是唯一不需要更改数据的解决方案。但需要注意的是:如果你经常渲染这辆车(比如每帧渲染数千次),状态改变开销可能会成为性能问题。#1和#2的某种组合通常是首选的方法。

顺便说一句,如果你的模型只有几百个面,但是50纹理,那么很可能在建模过程中出现了严重的错误。

不可能像那样使用任意数量的纹理,而不是以直接的方式。

基本上有3种解决方案:

  • 使用较少的纹理
    • 将几个单独的纹理打包到图集中。这需要你调整纹理坐标,注意贴图的创建(虽然一个不错的工具会自动帮你完成)。你可能也需要小心地为各向异性过滤留下足够的边界。
    • 将几个单独的纹理打包到一个数组纹理中。mipmaps和aniso没有问题,但需要硬件支持(GL 3.1卡)
  • 拆分模型
    • 更多的绘制调用和更多的状态变化和管道停机每辆车(对性能不利)
    • 解决方案:例如,绘制所有的车身在一个批次中,所有的轮胎在一个批次中,所有的灯在另一个批次中,以减少状态变化
  • 使用细节纹理和较少的"整体低细节"纹理
    • 类似于如何在地形上做纹理
    • 在像素着色器中组合,给每辆车一个单独的外观

为单个对象切换50种纹理将很快变成低性能噩梦。使用纹理图集

多纹理意味着提供多个纹理层,如颜色层,凹凸层,光泽等。但是它们不能用来替换地图集。

同样,如果你的模型由不同材质的部件组成,把它分开。每个材质都有自己的网格

相关内容

  • 没有找到相关文章

最新更新