iOS 设备使用 PowerVR 图形架构。PowerVR 架构是基于图块的延迟渲染模型。这个模型的主要好处是它不使用深度缓冲区。
但是,我可以访问我的 iOS 设备上的深度缓冲区。具体来说,我可以使用屏幕外帧缓冲区对象将深度缓冲区转换为颜色纹理并进行渲染。
如果 PowerVR 架构不使用深度缓冲区,我如何能够渲染深度缓冲区?
iOS 设备使用 PowerVR 图形架构。PowerVR 架构是基于图块的延迟渲染模型。这个模型的主要好处是它不使用深度缓冲区。
但是,我可以访问我的 iOS 设备上的深度缓冲区。具体来说,我可以使用屏幕外帧缓冲区对象将深度缓冲区转换为颜色纹理并进行渲染。
如果 PowerVR 架构不使用深度缓冲区,我如何能够渲染深度缓冲区?
基于图块的延迟渲染——顾名思义——是在逐个图块的基础上工作的。屏幕的每个部分都被加载到内部缓存中,再次处理和写出。硬件获取与当前图块和当前深度值重叠的三角形列表,并从中得出一组新的颜色和深度,然后再次将它们全部写出来。因此,虽然一个完全愚蠢的 GPU 可能对每个三角形的每个相关深度缓冲区值进行一次读取和一次写入,但 PowerVR 将在每批几何体中执行一次读取和一次写入,而光线投射式算法则在两者之间完成其余的工作。
在“纯”基于切片的延迟渲染器上实现 OpenGL 是不可能的,因为深度缓冲区需要可读。仅使深度缓冲区写入通常也效率不高,因为颜色缓冲区在任何时候都是可读的(显式地通过glReadPixels
或隐式地根据您根据操作系统的机制呈现帧缓冲区的时间),这意味着硬件可能有画一个场景,然后在上面画更多。
确实,基于图块的渲染器不需要传统的深度缓冲区即可工作。
TBR 将屏幕分割成图块,并使用快速片上内存完全渲染此图块的内容,以存储临时颜色和深度。然后,当 tile 完成时,最终值将移动到实际的帧缓冲区。但是,深度缓冲区中的深度值通常是临时的,因为它们只是用作隐藏表面算法。那么这种情况下的深度值可以在图块被渲染后被完全丢弃。
这意味着有效的基于图块的渲染器实际上并不需要在较慢的视频内存中使用全屏深度缓冲区,从而节省带宽和内存。
Metal API 轻松公开了此功能,允许您将深度缓冲区的 storeAction 设置为“无关”值,这意味着它不会将生成的深度值备份到主内存中。
The exception to this case is that you may need the depth buffer contents after rendering (i.e. for a deferred renderer or as a source for some algorithm that operates with depth values). In that case the hardware must ensure that the depth values are stored in the framebuffer for you tu use.
PowerVR 确实使用深度缓冲区,但与常规(即时模式渲染)GPU 的方式不同
基于 Tile 的不同渲染的不同部分意味着给定场景的三角形首先被处理(着色、变换、裁剪等)并保存到中间缓冲区中。只有在处理完整个场景后,才会一一渲染图块。
将所有处理过的三角形放在一个缓冲区中允许硬件执行隐藏表面移除- 移除最终会被其他三角形隐藏/透支的三角形。这显着减少了渲染三角形的数量,从而提高了性能并降低了功耗。
隐藏表面移除通常使用称为选项卡缓冲区和深度缓冲区的东西。(两者都是小型片上存储器,因为它们一次存储一个图块)
不知道你为什么说 PowerVR 不使用深度缓冲区。我的猜测是,这只是一种“营销”方式,说不需要为了执行深度测试而从系统内存执行昂贵的写入和读取。
ps
只是为了补充汤米的答案:基于图块的不同渲染的主要好处是: