OpenGL - 在绑定不同的 FBO 时访问立方体贴图
OpenGL - Accessing a cubemap when a different FBO is bound
我在将我的阴影贴图实现从正向渲染切换到延迟渲染时遇到困难。我找到了问题所在,是立方体贴图未发送到着色器。我怀疑这是因为我的 "GBuffer" FBO 被绑定而不是立方体贴图 FBO。
如果 GLSL 可以在一次绘制调用中访问来自两个不同 FBO 的颜色附件,我想走那条路,这可能吗?
下面是正向渲染代码。
public void NormalPass(Shader shader)
{
// Reset state
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.UseProgram(shader.ID);
GL.Viewport(0, 0, Width, Height);
GL.CullFace(CullFaceMode.Back);
GL.ClearColor(0.5f, 0.5f, 0.5f, 1f);
// Uniforms
Matrix4 viewMatrix = player.GetViewMatrix();
Matrix4 projectionMatrix;
Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)Width / (float)Height, 0.1f, 100.0f, out projectionMatrix);
GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix);
GL.UniformMatrix4(shader.projectionMatrixLocation, false, ref projectionMatrix);
GL.Uniform3(shader.lightPositionLocation, lightPos);
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
DrawScene(shader, false); // False = Not shadowpass
GL.BindTexture(TextureTarget.TextureCubeMap, 0);
}
这里是失败的延迟渲染修改
public void Composite(Shader shader)
{
//Set up FBO reading/writing
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, gBuffer.FBO);
// Bind textures
GL.ActiveTexture(TextureUnit.Texture2);
GL.BindTexture(TextureTarget.Texture2D, gBuffer.positionTexture);
GL.ActiveTexture(TextureUnit.Texture1);
GL.BindTexture(TextureTarget.Texture2D, gBuffer.normalTexture);
GL.UseProgram(shader.ID);
GL.Disable(EnableCap.DepthTest);
GL.Viewport(0, 0, Width, Height);
GL.CullFace(CullFaceMode.Back);
GL.ClearColor(0.5f, 0.5f, 0.5f, 1f);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// Uniforms
Matrix4 viewMatrix = player.GetViewMatrix();
GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix);
GL.Uniform3(shader.lightPositionLocation, lightPos);
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
Quad2D.drawScreenSizedQuad(); // Draw the combined lighting and diffuse to screen
GL.BindTexture(TextureTarget.TextureCubeMap, 0);
}
很高兴根据要求提供更多信息。
If GLSL can access colour attachments from two different FBOs in a single draw call, I'd like to go that route, is this possible?
这个问题表明对正在发生的事情缺乏了解。 GLSL 访问 纹理,而不是 FBO 的颜色附件。
很明显,纹理可以用作颜色附件。但区别很重要,因为无论如何,GLSL 正在访问绑定的纹理,而不是 FBO 中的任何内容。
OpenGL 关于读取作为颜色附件附加到 FBO 的纹理的唯一规则是:只要这些纹理实际上没有附加到特定的帧缓冲区,它就会工作,该特定帧缓冲区是活动绘制帧缓冲区渲染命令。即便如此,OpenGL will only care if you break the feedback loop rules.
因此,您对读取帧缓冲区所做的绑定是毫无意义的。那不是使纹理可用于阅读或类似的东西;这不是读取帧缓冲区绑定点的目的。它仅用于 framebuffer reading commands and framebuffer blitting operations.
所以简单地将默认帧缓冲区绑定到 FramebufferTarget.Framebuffer
,就像您在转发案例中所做的那样,就可以了。
你的主要问题是:
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
您没有使用 glActiveTexture
来指定要绑定该立方体贴图的纹理单元。这意味着它将使用您设置的最后一个纹理单元:TextureUnit.Texture1
,并且您已经在那里绑定了一个 2D 纹理。从同一个纹理单元读取两种不同类型的两个纹理在 GLSL 中是非法的。
所以赔率很好,这不是你的意思。 总是 在任何 glBindTexture
调用之前使用 glActiveTexture
。除非你使用 glBindTextures
from GL 4.4/ARB_multibind or glBindTextureUnit
from GL 4.5/ARB_DSA.
我在将我的阴影贴图实现从正向渲染切换到延迟渲染时遇到困难。我找到了问题所在,是立方体贴图未发送到着色器。我怀疑这是因为我的 "GBuffer" FBO 被绑定而不是立方体贴图 FBO。
如果 GLSL 可以在一次绘制调用中访问来自两个不同 FBO 的颜色附件,我想走那条路,这可能吗?
下面是正向渲染代码。
public void NormalPass(Shader shader)
{
// Reset state
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.UseProgram(shader.ID);
GL.Viewport(0, 0, Width, Height);
GL.CullFace(CullFaceMode.Back);
GL.ClearColor(0.5f, 0.5f, 0.5f, 1f);
// Uniforms
Matrix4 viewMatrix = player.GetViewMatrix();
Matrix4 projectionMatrix;
Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)Width / (float)Height, 0.1f, 100.0f, out projectionMatrix);
GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix);
GL.UniformMatrix4(shader.projectionMatrixLocation, false, ref projectionMatrix);
GL.Uniform3(shader.lightPositionLocation, lightPos);
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
DrawScene(shader, false); // False = Not shadowpass
GL.BindTexture(TextureTarget.TextureCubeMap, 0);
}
这里是失败的延迟渲染修改
public void Composite(Shader shader)
{
//Set up FBO reading/writing
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, gBuffer.FBO);
// Bind textures
GL.ActiveTexture(TextureUnit.Texture2);
GL.BindTexture(TextureTarget.Texture2D, gBuffer.positionTexture);
GL.ActiveTexture(TextureUnit.Texture1);
GL.BindTexture(TextureTarget.Texture2D, gBuffer.normalTexture);
GL.UseProgram(shader.ID);
GL.Disable(EnableCap.DepthTest);
GL.Viewport(0, 0, Width, Height);
GL.CullFace(CullFaceMode.Back);
GL.ClearColor(0.5f, 0.5f, 0.5f, 1f);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// Uniforms
Matrix4 viewMatrix = player.GetViewMatrix();
GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix);
GL.Uniform3(shader.lightPositionLocation, lightPos);
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
Quad2D.drawScreenSizedQuad(); // Draw the combined lighting and diffuse to screen
GL.BindTexture(TextureTarget.TextureCubeMap, 0);
}
很高兴根据要求提供更多信息。
If GLSL can access colour attachments from two different FBOs in a single draw call, I'd like to go that route, is this possible?
这个问题表明对正在发生的事情缺乏了解。 GLSL 访问 纹理,而不是 FBO 的颜色附件。
很明显,纹理可以用作颜色附件。但区别很重要,因为无论如何,GLSL 正在访问绑定的纹理,而不是 FBO 中的任何内容。
OpenGL 关于读取作为颜色附件附加到 FBO 的纹理的唯一规则是:只要这些纹理实际上没有附加到特定的帧缓冲区,它就会工作,该特定帧缓冲区是活动绘制帧缓冲区渲染命令。即便如此,OpenGL will only care if you break the feedback loop rules.
因此,您对读取帧缓冲区所做的绑定是毫无意义的。那不是使纹理可用于阅读或类似的东西;这不是读取帧缓冲区绑定点的目的。它仅用于 framebuffer reading commands and framebuffer blitting operations.
所以简单地将默认帧缓冲区绑定到 FramebufferTarget.Framebuffer
,就像您在转发案例中所做的那样,就可以了。
你的主要问题是:
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
您没有使用 glActiveTexture
来指定要绑定该立方体贴图的纹理单元。这意味着它将使用您设置的最后一个纹理单元:TextureUnit.Texture1
,并且您已经在那里绑定了一个 2D 纹理。从同一个纹理单元读取两种不同类型的两个纹理在 GLSL 中是非法的。
所以赔率很好,这不是你的意思。 总是 在任何 glBindTexture
调用之前使用 glActiveTexture
。除非你使用 glBindTextures
from GL 4.4/ARB_multibind or glBindTextureUnit
from GL 4.5/ARB_DSA.