我正在开发一个非常简单但可自定义的OpenGL ES 2渲染引擎(我知道像“统一”和“虚幻引擎”这样的东西存在,并且重新发明轮子可能不是最安全的事情,把它作为给定的;-))。
现在我正面临拾取对象:我不想做光线投射而我想做色彩选择(自由笑声:我在ES3上使用MRT当前的实现。它有效,但只有它工作的地方,如果你抓住我的漂移......)。
AFAIK在挑选颜色时,你可以有两个缓冲区(一个用于选择,一个用于渲染),或者两次写入同一个:每种方法都有它的优点和缺点。
假设我有一个未知数目的对象,那就更好了:
我认为这个问题可归纳为:“重复切换缓冲区,或切换程序和加载制服更加昂贵”?
哦......如果问题没有意义,请随时告诉我。)
答案 0 :(得分:1)
在移动设备上,你所做的drawcalls数量是最重要的性能因素之一,每个drawcall的驱动程序开销通常都很大(Android上比一般的IOS更大),所以绘制两次对象不会是有利于perf(将使用更多CPU =>驱动程序调用的成本)。
如果你有不超过256个不同的对象,那么没有MRT的简单解决方案就是使用RGBA渲染目标(而不是RGB)并存储对象" ID"在alpha通道中(以及灰度颜色)。
否则,您应该不惜一切代价避免重复切换缓冲区,否则您将获得缓慢的加载/存储操作(GPU被迫将当前缓冲区memcpy到"备份它"当切换到新缓冲区时,想象每帧花费数百次......)
所以回答你的问题,重复切换缓冲区比切换程序和加载制服要花费更多。
PS:如果您有超过256个对象,您最终可能会尝试渲染"切片"在256个对象之后,在每个切片之后,glRead缓冲区像素并检查alpha通道中的对象选择,然后glClear只有alpha并继续到下一个切片。但请注意,这可能不是非常有效,因为只要你想要读取缓冲区像素,CPU就必须停止,等待GPU完成渲染,这样你就破坏了CPU / GPU的并行性