【问题标题】:OpenGL - Different textures on different surfaces of the same objectOpenGL - 同一对象的不同表面上的不同纹理
【发布时间】:2011-10-10 22:19:06
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: opengl textures texturing


    【解决方案1】:

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

    基本上有3种解决方案:

    • 使用更少的纹理
      • 将多个单独的纹理打包成一个图集。这需要你 调整纹理坐标并注意创建 mipmap (尽管一个不错的工具会自动为您完成)。您可能还需要注意为各向异性过滤留出足够的边界。
      • 将多个单独的纹理打包到一个阵列纹理中。 mipmap 和 aniso 没有问题,但需要硬件支持(GL 3.1 卡)
    • 拆分模型
      • 更多的绘制调用和更多状态变化和管道停顿每辆车(对性能不利)
      • 解决方案:绘制例如一个批次的所有车身,一个批次的所有轮胎,另一个批次的所有灯,以减少状态变化
    • 使用细节纹理和更少的“整体低细节”纹理
      • 类似于在地形上进行纹理处理的方式
      • 在像素着色器中进行组合,为每辆车提供独特的外观

    【讨论】:

      【解决方案2】:

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

      多重纹理旨在提供多个纹理层,如颜色层、凹凸层、光泽度等。但它们不能用于替换图集。

      此外,如果您的模型由不同材料的零件组成,请将其拆分。每种材质都有自己的网格。

      【讨论】:

        【解决方案3】:

        您不能以这种方式渲染模型,您可以一次绑定所有纹理。一个片段着色器,即使对于高端 GL 4.1 级硬件,也只能访问 16 个纹理。也就是说,它只能有 16 个采样器。

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

        处理它的正确方法是执行以下操作之一:

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

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

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

        【讨论】:

          猜你喜欢
          • 2017-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-15
          • 2020-10-28
          • 1970-01-01
          • 2012-08-31
          • 1970-01-01
          相关资源
          最近更新 更多