如何在 Moderngl EGL 后端启用抗锯齿?
How to enable Anti-aliasing in Moderngl EGL backend?
此代码在没有抗锯齿 (samples=0
) 时呈现彩色三角形。但是当我打开抗锯齿 (samples=1...32
) 时,它无法渲染任何东西。如何使其与抗锯齿一起使用?
也许我无法直接从多重采样 fbos 或纹理中读取像素,但我不知道如何解决这个问题。
import numpy as np
from PIL import Image
import moderngl
ctx = moderngl.create_standalone_context(backend='egl')
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=2),
depth_attachment=ctx.depth_texture((512, 512), samples=2)
)
fbo.use()
vertices = np.array([
-1.0, -1.0, 1.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0],
dtype='f4',
)
prog = ctx.program(vertex_shader="""
#version 330
in vec2 in_vert;
in vec3 in_color;
out vec3 color;
void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
color = in_color;
}
""",
fragment_shader="""
#version 330
out vec4 fragColor;
in vec3 color;
void main() {
fragColor = vec4(color, 1.0);
}
""",
)
vao = ctx.simple_vertex_array(prog, ctx.buffer(vertices), 'in_vert', 'in_color')
vao.render(mode=moderngl.TRIANGLES)
image = Image.frombytes('RGBA', (512, 512), fbo.read(components=4))
image = image.transpose(Image.FLIP_TOP_BOTTOM)
image.save('triangle.png', format='png')
无法直接从多采样帧缓冲区读取数据。请注意,在多样本帧缓冲区中,为每个样本存储像素。每个样品的颜色必须混合成一种颜色。这可以通过 glBlitFramebuffer
来实现。
创建 2 个帧缓冲区。使用 samples=0
创建一个帧缓冲区,这个帧缓冲区用于读取像素数据。创建一个多采样帧缓冲区,它是渲染的目标。
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=0),
)
fbo_msaa = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=8),
)
将像素数据从多样本帧缓冲区复制到单样本帧缓冲区。我还没有找到任何 ModernGL class 或提供该功能的方法。
无论如何,必须绑定多样本帧缓冲区以进行读取,必须绑定单个样本帧缓冲区以进行写入,并且必须复制颜色数据。在本机 OpenGL 中,它看起来如下所示:
gl.glBindFramebuffer(gl.GL_READ_FRAMEBUFFER, fbo_msaa.glo)
gl.glBindFramebuffer(gl.GL_DRAW_FRAMEBUFFER, fbo.glo)
gl.glBlitFramebuffer(0, 0, 512, 512, 0, 0, 512, 512, gl.GL_COLOR_BUFFER_BIT, gl.GL_LINEAR)
总计:
import numpy as np
from PIL import Image
import moderngl
import OpenGL.GL as gl
ctx = moderngl.create_standalone_context(backend='egl')
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=0)
)
fbo_msaa = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=8)
)
fbo_msaa.use()
vertices = np.array([
-1.0, -1.0, 1.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0],
dtype='f4',
)
prog = ctx.program(vertex_shader="""
#version 330
in vec2 in_vert;
in vec3 in_color;
out vec3 color;
void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
color = in_color;
}
""",
fragment_shader="""
#version 330
out vec4 fragColor;
in vec3 color;
void main() {
fragColor = vec4(color, 1.0);
}
""",
)
vao = ctx.simple_vertex_array(prog, ctx.buffer(vertices), 'in_vert', 'in_color')
vao.render(mode=moderngl.TRIANGLES)
gl.glBindFramebuffer(gl.GL_READ_FRAMEBUFFER, fbo_msaa.glo)
gl.glBindFramebuffer(gl.GL_DRAW_FRAMEBUFFER, fbo.glo)
gl.glBlitFramebuffer(0, 0, 512, 512, 0, 0, 512, 512, gl.GL_COLOR_BUFFER_BIT, gl.GL_LINEAR)
image = Image.frombytes('RGBA', (512, 512), fbo.read(components=4))
image = image.transpose(Image.FLIP_TOP_BOTTOM)
image.save('triangle.png', format='png')
很遗憾我遇到了一个新问题。如果 multisampe 帧缓冲区也有深度缓冲区,那么 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_msaa.glo)
会失败,无论出于何种原因。
这需要进一步调查。
编辑:
我刚刚发现,当使用 Renderbuffer rather than a Texture 作为深度缓冲区时没有任何问题:
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=0),
)
fbo_msaa = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=8),
depth_attachment=ctx.depth_renderbuffer((512, 512), samples=8)
)
因此,它似乎是 ModernGL 中的错误,与多采样纹理深度缓冲区附件有关。
此代码在没有抗锯齿 (samples=0
) 时呈现彩色三角形。但是当我打开抗锯齿 (samples=1...32
) 时,它无法渲染任何东西。如何使其与抗锯齿一起使用?
也许我无法直接从多重采样 fbos 或纹理中读取像素,但我不知道如何解决这个问题。
import numpy as np
from PIL import Image
import moderngl
ctx = moderngl.create_standalone_context(backend='egl')
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=2),
depth_attachment=ctx.depth_texture((512, 512), samples=2)
)
fbo.use()
vertices = np.array([
-1.0, -1.0, 1.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0],
dtype='f4',
)
prog = ctx.program(vertex_shader="""
#version 330
in vec2 in_vert;
in vec3 in_color;
out vec3 color;
void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
color = in_color;
}
""",
fragment_shader="""
#version 330
out vec4 fragColor;
in vec3 color;
void main() {
fragColor = vec4(color, 1.0);
}
""",
)
vao = ctx.simple_vertex_array(prog, ctx.buffer(vertices), 'in_vert', 'in_color')
vao.render(mode=moderngl.TRIANGLES)
image = Image.frombytes('RGBA', (512, 512), fbo.read(components=4))
image = image.transpose(Image.FLIP_TOP_BOTTOM)
image.save('triangle.png', format='png')
无法直接从多采样帧缓冲区读取数据。请注意,在多样本帧缓冲区中,为每个样本存储像素。每个样品的颜色必须混合成一种颜色。这可以通过 glBlitFramebuffer
来实现。
创建 2 个帧缓冲区。使用 samples=0
创建一个帧缓冲区,这个帧缓冲区用于读取像素数据。创建一个多采样帧缓冲区,它是渲染的目标。
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=0),
)
fbo_msaa = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=8),
)
将像素数据从多样本帧缓冲区复制到单样本帧缓冲区。我还没有找到任何 ModernGL class 或提供该功能的方法。
无论如何,必须绑定多样本帧缓冲区以进行读取,必须绑定单个样本帧缓冲区以进行写入,并且必须复制颜色数据。在本机 OpenGL 中,它看起来如下所示:
gl.glBindFramebuffer(gl.GL_READ_FRAMEBUFFER, fbo_msaa.glo)
gl.glBindFramebuffer(gl.GL_DRAW_FRAMEBUFFER, fbo.glo)
gl.glBlitFramebuffer(0, 0, 512, 512, 0, 0, 512, 512, gl.GL_COLOR_BUFFER_BIT, gl.GL_LINEAR)
总计:
import numpy as np
from PIL import Image
import moderngl
import OpenGL.GL as gl
ctx = moderngl.create_standalone_context(backend='egl')
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=0)
)
fbo_msaa = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=8)
)
fbo_msaa.use()
vertices = np.array([
-1.0, -1.0, 1.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0],
dtype='f4',
)
prog = ctx.program(vertex_shader="""
#version 330
in vec2 in_vert;
in vec3 in_color;
out vec3 color;
void main() {
gl_Position = vec4(in_vert, 0.0, 1.0);
color = in_color;
}
""",
fragment_shader="""
#version 330
out vec4 fragColor;
in vec3 color;
void main() {
fragColor = vec4(color, 1.0);
}
""",
)
vao = ctx.simple_vertex_array(prog, ctx.buffer(vertices), 'in_vert', 'in_color')
vao.render(mode=moderngl.TRIANGLES)
gl.glBindFramebuffer(gl.GL_READ_FRAMEBUFFER, fbo_msaa.glo)
gl.glBindFramebuffer(gl.GL_DRAW_FRAMEBUFFER, fbo.glo)
gl.glBlitFramebuffer(0, 0, 512, 512, 0, 0, 512, 512, gl.GL_COLOR_BUFFER_BIT, gl.GL_LINEAR)
image = Image.frombytes('RGBA', (512, 512), fbo.read(components=4))
image = image.transpose(Image.FLIP_TOP_BOTTOM)
image.save('triangle.png', format='png')
很遗憾我遇到了一个新问题。如果 multisampe 帧缓冲区也有深度缓冲区,那么 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_msaa.glo)
会失败,无论出于何种原因。
这需要进一步调查。
编辑:
我刚刚发现,当使用 Renderbuffer rather than a Texture 作为深度缓冲区时没有任何问题:
fbo = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=0),
)
fbo_msaa = ctx.framebuffer(
color_attachments=ctx.texture((512, 512), 4, samples=8),
depth_attachment=ctx.depth_renderbuffer((512, 512), samples=8)
)
因此,它似乎是 ModernGL 中的错误,与多采样纹理深度缓冲区附件有关。