我目前正在学习WebGL,而且我正在使用大量相同的多维数据集渲染场景,但翻译不同。
我相信我有两个选择;
缓冲单个立方体,使用uniform4fv进行平移并为每个立方体重新发送(到顶点着色器)。
缓冲我的所有立方体(用翻译硬编码的顶点)。
我的问题是关于哪种选择在哪些情况下更可取? - 我认为第一个选项更可取,但这取决于开销或更新统一变量。
答案 0 :(得分:1)
首先,它取决于您渲染的对象是动态还是静态。
对于静态几何,方法2将更有效。
对于动态几何,它取决于。权衡取决于状态变化与方法1的开销与计算CPU上的新顶点的成本之间的关系+使用方法2将这些顶点上传到GPU的每一帧。很难量化状态变化的确切成本,但是,它可以肯定的是,更大的对象需要更长的时间来计算和更新GPU。
根据经验,方法2可以更好地利用精灵,盒子等“小”对象,方法1可以更好地处理具有数千个顶点的“复杂”对象。究竟什么量化为“小”或“复杂”可能是gpu和驱动因素依赖,你必须在个人基础上进行测试。
drawElements
几乎总是优先于drawArrays
。
答案 1 :(得分:1)
正如WaclawJasper所说,有很多权衡。
在WebGL中执行操作的一般方法是每个对象一次绘制调用(第一种方法)。
另一种方法是使用实例化绘图using ANGLE_instanced_arrays
。在该方法中,您的翻译将存储在缓冲区中。您只需为每个实例更新缓冲区一个转换(第二个方法中每个顶点一个转换)。该方法假设所有实例都相同。
如果您的几何图形恰好是混合的(立方体+球体+金字塔),另一种方法是将您的方向数据放在纹理中。通过为每个顶点提供一个instanceId,您可以使用它来计算纹理中该实例数据的位置。在这种情况下,您将像上一个方法一样更新每个实例的一个方向。只是你要更新纹理而不是缓冲区。如果硬件支持读取AFAICT大多数硬件此时所做的浮点纹理(OES_texture_float
),则此方法非常简单。
作为在纹理中存储方向的示例three.js可选地将纹理中的骨矩阵存储为蒙皮网格渲染以绕过有限数量的制服。
请注意,使用纹理还可以将顶点数据放在纹理中。然后缓冲区只包含顶点索引。