gpt4 book ai didi

c++ - OpenGL 逐网格 Material (着色器)

转载 作者:行者123 更新时间:2023-11-28 04:32:25 41 4
gpt4 key购买 nike

所以,我正在使用 C++ 和 OpenGL 4 开发一个简单的游戏引擎。现在我正在努力渲染导入的模型。

我使用 FBX sdk 以一种非常简单的方法导入 fbx 模型:基本上我访问 fbx 的每个节点并将网格数据附加到一个稍后用于渲染的大结构。但是,我希望能够为模型使用的每种 Material 指定不同的片段着色器(例如,为汽车轮辋和灯光指定不同的着色器)。

作为引用,UE4 有一个 Material 系统,允许用户使用类似蓝图的编辑器定义简单的着色器。

我想将类似的概念应用于我的引擎,允许创建一个指定一段片段着色器代码和一组要使用的纹理的 Material 对象。

我面临的问题是:

  1. 很明显,我必须为使用不同 Material 的每个模型部分分开绘制调用,因为我不能在绘制调用中间交换程序(可以吗?):在这一点上,最好有每个部分或单个部分单独的 vao/vbo/ebo 并跟踪一个部分结束和下一个部分开始的位置? (我想这是最好的选择)
  2. 仅预编译着色器片段并将其动态附加到当前程序(即 glAttach + glLinkProgram + glUseProgram)是一个好习惯,还是为每种 Material 预链接整个程序更好,考虑到顶点着色器始终相同?

最佳答案

  1. 不可以,您不能在绘图调用过程中更改程序。根据您的数据布局,对于 GPU 将如何执行有不同的意见和测试。我的经验是,如果您在第一次上传网格数据后不打算修改它们,最有效的方法是使用一个 VAO,两个 VBO:一个用于索引,一个用于其余数据。发出绘制调用时,您可以根据网格数据(您应该跟踪)偏移索引缓冲区,并偏移着色器属性的配置。由于内存块是连续的,因此这种方法允许对缓存更加友好和高效的内存访问。然而,正如我所提到的,在某些情况下这不是最有效的方法(尽管我相信它仍然足够有效)。这取决于您的硬件和驱动程序。

  2. 在启动渲染循环之前预编译并链接所有程序。这是最有效的方法

另外,我建议您研究一下 UBER 着色器技术。此方法基于为不同的可能输入创建着色器,并创建一组 defines 或子例程体系结构,允许您编译同一着色器的不同版本(例如,您可能有一个具有法线纹理的模型,您可能想要应用凹凸贴图,但其他模型可能没有此纹理,因此执行完全相同的着色器将导致未定义的行为或崩溃)。

关于c++ - OpenGL 逐网格 Material (着色器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52513723/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com