0

首先:
Windows XP SP3、2GB RAM、Intel core 2 Duo 2.33 GHz、nVidia 9600GT 1GB RAM。OpenGL 3.3 全面更新。

我在做什么的简短描述:
理想情况下,我需要在每帧使用 glTexSubImage2D 将一个单个像素放入 GL 纹理 (A) 中。
然后,在 shader-FBO-quadfacingcamera 设置中修改纹理,并用生成的 FBO 替换原始图像。

当然,我不想要 FBO 反馈循环,所以我将修改后的版本放在临时纹理中,并使用 glCopyTexSubImage2D 单独进行更新。

现在的顺序是:

1)每帧使用glTexSubImage2D将一个像素放入GL纹理(A)中(宽度=高度= 1)。
2) 此修改后的版本 A 将在 shader-FBO-quad 设置中使用/修改,以渲染成不同的纹理 (B)。
3) 使用 glCopyTexSubImage2D 将生成的纹理 B 覆盖在 A 上。
4) 重复...

通过重复这个循环,我想通过将着色器中的颜色值每帧乘以 0.99 来实现缓慢的淡入淡出效果。

有两件事是严重错误的:
1) 每帧重复 0.99 的衰减因子,衰减在 RGB 48、48、48 处停止。因此,留下一串没有完全淡出的灰色像素。
2) 程序以 100 FPS 运行。很坏。因为如果我注释掉 glCopyTexSubImage2D 程序将以 1000 FPS 运行!

我也通过注释掉 glTexSubImage2D 并单独留下 glCopyTexSubImage2D 来实现 1000 FPS。这一事实澄清了 glTexSubImage2D 和 glCopyTexSubImage2D 本身不是瓶颈(我试图用辅助 FBO 替换 glCopyTexSubImage2D 来进行复制,结果相同)。

观察:瓶颈显示了这两个命令何时起作用!

困难模式:请不要 PBO。

与源代码和 exe 链接:
http
://www.mediafire.com/? ymu4v042a1aaha3(使用 CodeBlocks 和 SDL)
FPS 计数被写入 stdout.txt

我要求解决那里暴露的两件事。
预期结果:在 800-1000 FPS 时完全淡出到纯黑色。

4

2 回答 2

0

对于问题 1:

您在这里遇到了一些精度(和量化)问题。我假设您正在使用一些 8 位 UNORM 帧缓冲区格式,因此您写入的任何内容都将在 256 个级别的下一个离散步骤中四舍五入。想一想:48*0.99 = 47.52,最终还是 48,所以它不会变得更暗。使用一些真正的浮点格式将是一个解决方案,但它可能会大大降低整体性能......

您选择的淡出操作根本不是最佳选择,最好添加一些线性项以确保您将值减少至少 1/255。

问题2:很难说这里的实际瓶颈是什么。由于您不使用 PBO,因此您仅限于同步纹理更新。

但是,为什么您需要进行复制操作呢?这种事情的标准方法是一些纹理/FBO/颜色缓冲区“乒乓”,你只需在每次迭代后交换纹理的“角色”。所以你得到了序列:

  1. 更新 A
  2. 渲染到 B(从 A 读取)
  3. 更新 B
  4. 渲染到 A(从 B 读取)
于 2013-06-07T19:59:05.903 回答
0

问题 2:尽可能快地将任意像素喷到纹理中。
由于从主内存动态上传数据到 GPU 的绝对最快的方法可能是顶点数组或 VBO,所以问题 2 的解决方案变得微不足道:
1)创建顶点数组和颜色数组
(或交错坐标和颜色、性能/带宽可能会有所不同);
2) Z分量=0。我们希望点在地板上;
3) 正射投影向下的相机
(确保屏幕尺寸与坐标范围完全匹配);
4) 使用带有 glPointSize=1 的 GL_POINTS 和禁用 GL_POINT_SMOOTH 的 FBO 渲染到纹理。

很标准。现在程序以 750 fps 运行。足够近。我的梦想就像“嘿妈妈看!我正在以 1000 fps 的速度运行 glTexSubImage2D!” 然后嗯。
虽然 glCopyTexSubImage2D 非常快。会推荐。

不确定这是否是 GPU 加速衰落的最佳方法,但鉴于结果,必须注意此方法的 Force 高度集中。无论如何,通过设置最小恒定递减变量来解决中途停止衰落的问题,因此即使指数曲线失败,无论如何衰落都会结束。

于 2013-06-11T21:10:01.680 回答