我有一个附加了2个纹理的Framebuffer是否可以在同一个片段着色器函数中从纹理A读取并写入纹理B?
感谢。
答案 0 :(得分:1)
这比我想象的要复杂。我认为只要你没有采样并渲染到相同的纹理就可以了,无论纹理是否附加到FBO。但是在试图找到一些确凿的规范报价来支持这一点时,情况变得不那么明确了。
4.5规范确实包含一个似乎证实了我最初本能的短语(强调添加):
具体来说,如果任何着色器阶段获取纹素并且相同的纹素通过片段着色器输出写入,则渲染片段的值为未定义,即使读取和写入是不在同一次抽奖中
有趣的是,“通过片段着色器输出写入”不会出现在4.4及更高版本的规格版本中。我不知道在4.5中添加这个是仅仅是为了澄清,还是在4.5中放宽了反馈循环的规则。我在更改日志中找不到任何可以提供有关更改的更多背景信息的内容。
最多4.4,规范说如果纹理附加到当前绘制帧缓冲区并进行采样,则会有一个反馈循环。由于没有其他说法,这将包括纹理附加到FBO但不用作绘制缓冲区的情况。
如果您不渲染并从相同纹理中采样,那么事情大多数情况下我都不会感到惊讶。但为了完全安全,特别是如果你不依赖于OpenGL 4.5,你应该从FBO中取消附加采样纹理。不包括在绘制缓冲区列表中是不够的。
答案 1 :(得分:1)
扩展Reto的答案。
你可以从纹理A中读取并写入纹理B,但是你不能这样做:
uniform sampler2D B; // Sampler for texture B.
layout (location = 0) out vec3 A; // Write to texture
A = texture(B,Texcoord);
这是无效的,您必须使用第三个变量。
您无法在同一个绘制调用中读取和写入纹理,但是您可以从一个纹理读取并写入另一个纹理,这两个纹理都位于同一个绘制调用中的同一帧缓冲区中。你必须确保在绑定帧缓冲区时绑定它就像这样。
glbindframebuffer(GL_FRAMEBUFFER, fboHandle)
这是因为帧缓冲区将被写入和读取并且`GL_FRAMEBUFFER将允许你这样做。