【问题标题】:Partial redraw to FBO OpenGL部分重绘到 FBO OpenGL
【发布时间】:2019-09-03 17:22:31
【问题描述】:

我的场景被组织成由浮点纹理(16 位带 alpha)支持的 FBO 组成的元素组。然后将这些 FBO 从上到下混合在一起以生成最终场景。所有 FBO 都是屏幕大小。当屏幕尺寸变大(在 Intel HD Graphics 630 上 > 2048)时,帧率会直线下降。这是由于填充率问题(我已尝试使用无操作叶节点和较小的纹理格式来验证这一点)。有没有办法将 FBO 的一部分传送到另一个 FBO 的一部分?在绘制带纹理的四边形之前可能是这样的:

void FrameBufferManager::SetViewportFromClipBox(const Geometry::BoundingBox& clipBox)
{
    const auto& lowerLeft = clipBox.GetLowerLeft();
    const auto lx = static_cast<GLsizei>(lowerLeft.x);
    const auto ly = static_cast<GLsizei>(lowerLeft.y);
    const auto width = static_cast<GLsizei>(clipBox.GetWidth());
    const auto height = static_cast<GLsizei>(clipBox.GetHeight());
    glViewport(lx, ly, width, height);
    glScissor(lx, ly, width, height);
}

在顶点着色器中,几何体被转换,使得clipBox 之外的点将落在 ((-1, -1) (1, 1)) 之外。以上内容能否确保 clipBox 之外的像素不会浪费 GPU 内存带宽/填充率?如果没有,是否有任何方法可以做到这一点,而无需创建一堆小型 FBO 并根据对象位置在这些 FBO 之间拆分对象渲染?

【问题讨论】:

  • 我测试了上面的代码,如果有人需要使用自定义着色器进行 blitting,它似乎可以解决问题中提到的 GPU 上的性能问题。

标签: opengl-es rendering framebuffer


【解决方案1】:

有没有办法将一个 FBO 的一部分 blit 到另一个 FBO 的一部分?

从 OpenGL ES 3.0 开始,您可以使用glBlitFramebuffer

glBlitFramebuffer — 将一块像素从读取帧缓冲区复制到绘制帧缓冲区

void glBlitFramebuffer(
    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
    GLbitfield mask, GLenum filter);

这个函数也由扩展 NV_framebuffer_blit 提供,它是针对 OpenGL ES 2.0 编写的。

【讨论】:

    猜你喜欢
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多