如何在Moderngl EGL后端中启用抗锯齿? [英] How to enable Anti-aliasing in Moderngl EGL backend?

查看:254
本文介绍了如何在Moderngl EGL后端中启用抗锯齿?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当没有抗锯齿(samples=0)时,此代码将呈现一个彩色三角形.但是,当我打开抗锯齿(samples=1...32)时,它什么也无法渲染.如何使其具有抗锯齿功能? 也许我不能直接从多重采样fbos或纹理中读取像素,但是我不知道如何解决.

This code renders a colored triangle when there is no anti-aliasing (samples=0). But when I turn on anti-aliasing (samples=1...32) it can't render anything. How to make it work with anti-aliasing? Perhaps I cannot read pixels from multisample fbos or textures directly but I don't know how to fix that.

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 来实现.

It is not possible to read data from a multisample framebuffer directly. Note, in a multisample framebuffer the pixels are stored for each sample. The color for each sample has to be mixed to a single color. That can be achieved by glBlitFramebuffer.

创建2个帧缓冲区.用samples=0创建一个帧缓冲区,该帧缓冲区用于读取像素数据.创建一个多样本帧缓冲区,它是渲染的目标.

Create 2 framebuffers. Create a framebuffer with samples=0, this framebuffer is used to read the pixel data. Create a mutlisample framebuffer, which is the target of the rendering.

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 类或方法. br> 无论如何,必须将多样本帧缓冲区绑定为读取,并且必须将单样本帧缓冲区绑定为写入,并且必须复制颜色数据.在本机OpenGL中,外观如下:

Copy the pixel data from the multisample framebuffer to the single sample framebuffer. I have not found any ModernGL class or method which provides that.
Anyway the multisample framebuffer has to be bound for reading and the single sample framebuffer has to be bound for writing and the color data has to be copied. In native OpenGL this looks as follows:

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')


可悲的是,我遇到了一个新问题.如果多样本帧缓冲区也具有深度缓冲区,则glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_msaa.glo)出于任何原因都会失败.
这需要进一步调查.


Sadly I encountered a new issue. If the multisampe framebuffer has a depth buffer, too, then glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_msaa.glo) fails, for whatever reason.
This needs to be investigated further.

修改:

我刚刚发现,使用渲染缓冲区,而不是深度缓冲区的纹理:

I just figured out, that there is not any issue, when using a Renderbuffer rather than a Texture for the depth buffer:

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 中的错误,与多样本纹理深度缓冲区附件有关.

Hence, it seams to be a bug in ModernGL, related to multisample texture depth buffer attachment.

这篇关于如何在Moderngl EGL后端中启用抗锯齿?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆