OpenGL中的单色渲染到帧缓冲区对象?

Posted

技术标签:

【中文标题】OpenGL中的单色渲染到帧缓冲区对象?【英文标题】:Monochrome rendering in OpenGL to frambuffer object? 【发布时间】:2018-02-11 03:09:32 【问题描述】:

有没有办法在 OpenGL 中单色渲染到帧缓冲区?

我的最终目标是渲染到立方体纹理以在我的应用程序中创建阴影贴图。

据我了解,一种方法是,对于每个光源,将场景渲染 6 次(使用相机的 6 个可能的正交方向)到一个 FBO,然后将它们全部添加到立方体贴图中.

我已经拥有为一个这样的相机位置渲染深度图的着色器。然而,这些着色器以全 RGB 渲染,对于深度图来说,它比它需要的大 3 倍。有没有办法单色渲染以减小纹理的大小?

【问题讨论】:

是的,有单通道纹理格式。它们被命名为“R8”或“R16”。 【参考方案1】:

如何为阴影贴图(或立方体贴图)创建纹理?如果您在创建纹理时使用GL_DEPTH_COMPONENT[16|24|32] 格式,则纹理将是您想要的单通道。

查看官方文档:https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTexImage2D.xml

GL_DEPTH_COMPONENT

每个元素都是一个单一的深度值。 GL 将其转换为浮点数,乘以有符号比例因子 GL_DEPTH_SCALE,添加有符号偏差 GL_DEPTH_BIAS, 并钳制在 [0,1] 范围内(参见 glPixelTransfer)。

如您所见,它表示每个元素都是单一深度值。

所以如果你使用这样的东西:

 for (i = 0; i < 6; i++)
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
                 0,
                 GL_DEPTH_COMPONENT24,
                 size,
                 size,
                 0,
                 GL_DEPTH_COMPONENT,
                 GL_FLOAT,
                 NULL);

单个元素的大小必须是 24 位(可能是 32 位带填充)。否则,如果它将深度大小存储为 RGB[A],那么指定深度大小将是荒谬的。

这篇文章还验证了深度纹理是单通道纹理:https://www.opengl.org/discussion_boards/showthread.php/123939-How-is-data-stored-in-GL_DEPTH_COMPONENT24-texture

“我已经拥有为一个这样的相机位置渲染深度图的着色器。但是,这些着色器以全 RGB 渲染,对于深度图来说,它比它需要的大 3 倍。”

一般来说,您将场景渲染到阴影贴图以获得深度值(或距离),对吧?那你为什么要渲染为RGB呢?如果您只需要深度值,则不需要为附件着色,因为您不需要编写它们,您只需写入深度缓冲区(实际上,如果您没有在 frag 中覆盖其值,OpenGL 本身会这样做)

【讨论】:

以上是关于OpenGL中的单色渲染到帧缓冲区对象?的主要内容,如果未能解决你的问题,请参考以下文章

将OpenGL帧缓冲区对象与Qt(QOpenGLWidget)一起使用,绘制到帧缓冲区时如何禁用多重采样

用于片段着色器的 OpenGL GLSL 绑定采样器

OpenGL 渲染到纹理 - 黑屏

从帧缓冲区对象读取时,OpenGL 纹理坐标是相反的

将我的场景渲染到帧缓冲区对象(FBO)然后将该 FBO 渲染到屏幕所需的步骤是啥?

OpenGL 帧缓冲区缺失面