这是一个绝对的初学者问题 .
背景:我不是真正的游戏开发者,但我正在努力学习低级3D编程的基础知识,因为这是一个有趣而有趣的话题 . 我选择Apple的Metal作为图形框架 . 我了解SceneKit和其他更高级别的框架,但我有意尝试学习低级别的部分 . 不幸的是,我已经走出了我的深度,并且网上似乎很少有面向初学者的金属资源 .
通过阅读Apple文档并按照我能找到的教程,我设法实现了一个简单的顶点着色器和片段着色器,并在屏幕上绘制了一个真实的3D模型 . 现在我正在尝试绘制第二个模型,但我有点卡住了,因为我不确定什么是真正最好的方法 .
我......
-
对我的所有模型使用单个顶点缓冲区和索引缓冲区,并在渲染单个模型时告诉MTLRenderCommandEncoder偏移量?
-
为每个模型都有一个单独的顶点缓冲区/索引缓冲区?这样的方法会扩大规模吗?
-
别的什么?
TL;DR: What is the recommended way to store the vertex data of multiple models in Metal (or any other 3D framework)?
2 回答
没有一种推荐方式 . 当你在Metal这么低的水平上工作时,有很多种可能性,你选择的那种很大程度上取决于你想要/需要优化的情况和性能特征 . 如果您只是在玩介绍项目,那么大多数决策都是无关紧要的,因为在您扩展到“真实”项目之前,性能问题不会受到影响 .
通常,游戏引擎每个模型使用一个缓冲区(或一组顶点/索引缓冲区),特别是如果每个模型需要不同的渲染状态(例如着色器,绑定纹理) . 这意味着当将新模型引入场景或不再需要旧模型时,可以将必需的资源加载到GPU存储器中/从GPU存储器移除(通过创建/销毁MTL对象) .
当你改变缓冲区时,用于从同一缓冲区的(不同部分)进行多次绘制的主要用例 . 例如,在第n帧上,您需要在新的顶点数据中计算/流式传输并将其写入缓冲区的第二个1KB ...然后,对于帧n 1,您可以切换缓冲区的哪些部分用于什么 .
为了给rickster的答案添加一点,我会将你的模型封装在一个包含一个缓冲区(或两个,如果你计算索引缓冲区)的模型中,每个模型,并传递一个可选参数,其中包含你想要的那个模型的实例数 . 创建 .
然后,保留一个额外的缓冲区,用于存储每个实例要引入的任何变体 . 通常,它只是变换和不同的材料 . 例如,
在我的例子中,材质包含UV变换,但所有实例的纹理必须相同 .
然后你的模型类看起来像这样,
带实例的顶点着色器看起来像这样,
以下是我使用实例化编写的一个示例,并进行了性能分析:http://tech.metail.com/performance-quaternions-gpu/
你可以在这里找到完整的代码供参考:https://github.com/endavid/VidEngine
我希望有所帮助 .