标签: multisampling

如何在OpenGL FBO中使用多重采样

我正在尝试为FBO启用mutlisampling和alpha-to-coverage.使用默认的帧缓冲区,我所要做的就是调用glEnable(GL_MULTISAMPLE)glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE).但是,我无法使用自己的FBO达到同样的效果.

我的目标:将场景绘制到FBO,就像使用上述属性绘制到默认帧缓冲区一样.从那里我希望能够将图像用作未来通过着色器的纹理.

这适用:制作没有多重采样/ alpha到覆盖的FBO的代码,1种颜色附件,1种深度附件:

// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,defaultColorAttachment0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,screenWidth,screenHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);

// Bind the texture to the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenWidth, screenHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, defaultDepthBuffer);
Run Code Online (Sandbox Code Playgroud)

这不起作用.试图制作多重采样FBO的代码:

// Generate the color attachment
glGenTextures(1,&defaultColorAttachment0);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, defaultColorAttachment0);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA, screenWidth, screenHeight, GL_FALSE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, defaultColorAttachment0,0);

// Generate the depth attachment
glGenRenderbuffers(1,&defaultDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, defaultDepthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, …
Run Code Online (Sandbox Code Playgroud)

c++ opengl fbo multisampling

26
推荐指数
1
解决办法
1万
查看次数

我选择的GLFW_SAMPLES实际上做了什么?

设置此变量有什么作用?例如,如果我将其设置为4,那意味着什么?

我在"Framebuffer相关提示"部分下阅读了glfw.org上的描述(参见这里:GLFW窗口指南).手册中说"GLFW_SAMPLES指定了用于多重采样的所需样本数.Zero禁用多重采样.GLFW_DONT_CARE表示应用程序没有首选项."

我还阅读了一般的多重采样说明(参见此处: Shawn Hargreaves的多重采样).

我大致了解多重采样的含义:在调整图像大小和重新绘制图像时,用于重绘图像的点数应该足够接近,以便我们看到的是图像的精确表示.数字示波器也会出现同样的想法 - 比如你正在采样正弦信号.如果采样速率恰好恰好等于波的频率(f),则示波器显示恒定电压,这与您希望看到的输入信号非常不同.为了避免这种情况,奈奎斯特定理告诉我们,我们应该以至少2f的速率进行采样.所以我看到计算机图形学中会出现问题,但我不知道究竟是什么功能

glfwWindowHint(GLFW_SAMPLES, 4); 确实.

opengl graphics multisampling glfw

10
推荐指数
1
解决办法
5009
查看次数

多样本如何真正起作用?

我对了解多重采样的工作原理非常感兴趣.我已经找到了关于如何启用或使用它的大量文献,但是关于它为了实现抗锯齿渲染它真正做了什么的信息非常少.在许多地方,我发现的是相互矛盾的信息,这些信息只会让我更加困惑.

请注意,我知道如何启用和使用多重采样(我实际上已经在使用它),我不知道的是多重采样渲染缓冲区/纹理中真正涉及的是什么类型的数据,以及如何在渲染管道中使用这些数据.

我可以很好地理解超级采样是如何工作的,但是多重采样仍然有一些我想要理解的模糊区域.

这是规格说的:(OpenGL 4.2)

像素样本值(包括颜色,深度和模板值)存储在此缓冲区(多重采样缓冲区)中.样本包含每种片段颜色的单独颜色值.

...

在多重采样渲染期间,像素片段的内容以两种方式改变.首先,每个片段包括具有SAMPLES位的覆盖值.

...

其次,每个片段包括SAMPLES深度值和关联数据集,而不是单样本渲染模式中维护的单个深度值和关联数据集.

因此,每个样本都包含不同的颜色,覆盖位和深度.与普通超级采样有什么区别?看起来像是对我的"加权"超级采样,其中每个最终像素值由其样本的覆盖值而不是简单平均值确定,但我对此非常不确定.那么样本级别的纹理坐标呢?

如果我在RGBF多重采样纹理中存储法线,我会在多边形的边缘上将它们"反锯齿"(即接近0)读回来吗?

每个片段调用一次片段着色器,除非它使用gl_SampleID,glSampleIn或具有"样本"存储限定符.如何为每个片段调用一次片段着色器并获得抗锯齿渲染?

opengl multisampling

9
推荐指数
1
解决办法
5077
查看次数

来自FBO的glReadPixels因多重采样而失败

我有一个带有颜色和深度附件的FBO对象,我将其呈现,然后从使用中读取glReadPixels(),我正在尝试添加多重采样支持.
而不是glRenderbufferStorage()我要求glRenderbufferStorageMultisampleEXT()颜色附件和深度附件.帧缓冲区对象似乎已成功创建并报告为完成.
渲染后我试图用它读取glReadPixels().当样本数为0时,即多重采样禁用,它完美地工作,我得到我想要的图像.当我将样本数量设置为其他东西时,比如4,帧缓冲区仍然构造正常但是glReadPixels()失败了INVALID_OPERATION

任何人都知道这里有什么问题吗?

编辑:glReadPixels的代码:

glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
Run Code Online (Sandbox Code Playgroud)

其中ptr指向一个宽度为*height uints的数组.

opengl fbo multisampling

7
推荐指数
1
解决办法
8157
查看次数

GL_MULTISAMPLE在哪里定义?

虽然我不鼓励我阅读OpenGL红皮书,但我仍然这样做,因为它是为初学者设计的唯一一本书,教程和/或文档虽然非常重要但并不能完全替代一本书.为了证明自己的合理性:)

现在,有一个使用多重采样的抗锯齿的例子,其中涉及到 glEnable(GL_MULTISAMPLE);

我使用Qt,我得到一个编译错误,因为GL_MULTISAMPLE是一个未声明的标识符.我目前看到以下原因:

  • 对于某些实现,包括Qt附带的实现,未定义GL_MULTISAMPLE.
  • 它不在GL/gl.h或GL/glu.h中,而是在<QGLWidget>Qt中未包含或未附带的其他标题中
  • 它已过时/弃用

上述原因之一是否正确?如果没有,这就是我没有它的原因,我怎样才能获得?提前致谢

c++ opengl qt multisampling

7
推荐指数
2
解决办法
1万
查看次数

如何在Qt5的OpenGL中启用多重采样(抗锯齿)?

在创建窗口时如何启用多重采样?我应该如何初始化OpenGL以匹配?

opengl multisampling qt5

7
推荐指数
1
解决办法
8193
查看次数

如何在 MTKView 中使用多重采样?

我正在尝试使用MTKView. 我有MTKView一个代表。我将视图的sampleCount属性设置为 4。我创建了一个rasterSampleCount设置为 4的管道状态描述符,并使用它来创建渲染时使用的渲染管道状态。

在代理的draw(in:)方法,我通过获取该视图的当前渲染通道描述符和设置创建渲染过程描述storeActionmultisampleResolve。我也设置了尝试storeAndMultisampleResolve无济于事。

我为渲染通道描述符创建了一个解析纹理,它与视图具有相同的宽度和高度以及相同的像素格式。

鉴于上述情况,我在渲染过程中得到了一个完整的红框。我已经使用金属调试器来查看纹理,并且视图的纹理和解析纹理都有正确的渲染。我在 AMD 机器上,全红色纹理通常表示未初始化的纹理。

我需要做些什么才能让渲染进入屏幕?

下面是我设置视图、管道状态和解析纹理的方法:

    metalView = newMetalView
    metalView.sampleCount = 4
    metalView.clearColor = MTLClearColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
    device = newMetalView.device!

    let metalLibrary = device.makeDefaultLibrary()!
    let vertexFunction =  metalLibrary.makeFunction(name: "vertexShader")
    let fragmentFunction = metalLibrary.makeFunction(name: "fragmentShader")

    let pipelineStateDescriptor = MTLRenderPipelineDescriptor.init()
    pipelineStateDescriptor.label = "Particle Renderer"
    pipelineStateDescriptor.vertexFunction = vertexFunction
    pipelineStateDescriptor.fragmentFunction = fragmentFunction
    pipelineStateDescriptor.colorAttachments [ 0 ].pixelFormat = metalView.colorPixelFormat …
Run Code Online (Sandbox Code Playgroud)

multisampling swift metal metalkit

7
推荐指数
1
解决办法
738
查看次数

FBO Blitting无效

我正在尝试将多重采样的场景渲染为纹理,这是我正在使用的代码.我有黑屏.我在init结束时检查fbo完整性,并且他们报告两个fbo都已完成.

void init_rendered_FBO() {
    glGenFramebuffers(1,&fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glGenTextures(1,&fbo_tex);
    glBindTexture(GL_TEXTURE_2D, fbo_tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_screen, height_screen, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width_screen, height_screen);
    glBindTexture (GL_TEXTURE_2D, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0);
    int objectType;
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType);
    ASSERT(objectType == GL_TEXTURE);
    int objectName;
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName);
    ASSERT(glIsTexture(objectName) == GL_TRUE);
    int wid, hei, fmt;
    glBindTexture(GL_TEXTURE_2D, objectName);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &wid);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &hei);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT,
            &fmt);
    glBindTexture(GL_TEXTURE_2D, …
Run Code Online (Sandbox Code Playgroud)

opengl graphics fbo multisampling

6
推荐指数
1
解决办法
3886
查看次数

WebGL 帧缓冲多重采样

我知道 webgl 可以抗锯齿或多采样你渲染到屏幕上的东西以避免硬边,但是当我使用帧缓冲区时它不再这样做了,并且屏幕上有一堆锯齿状边缘。

如何让帧缓冲区使用多重采样?

javascript multisampling webgl

6
推荐指数
2
解决办法
3855
查看次数

具有多种颜色附件的多采样帧缓冲区的分辨率

尝试在延迟着色之上实现抗锯齿,我尝试使用多重采样渲染缓冲区,然后使用缓冲区位块传输传递解析样本。

  1. 按照延迟着色的传统做法,我使用发出 3 个颜色输出的专用着色器来渲染场景:

    • 职位
    • 法线
    • 漫反射和镜面反射
  2. 然后将它们用于照明计算通道,从而产生最终的场景纹理

  3. 使用简单的着色器将场景纹理渲染到全屏四边形的屏幕上

正如您可能猜到的,渲染到屏幕时,屏幕上的 MSAA 不会应用于场景纹理的内容:为了实现抗锯齿,我因此选择在步骤 1) 中使用多重采样渲染缓冲区,并引入了额外的步骤1.1) 分辨率。当然,多重采样仅对彩色图是必要的/有用的,对其他两张图来说不是必需的/有用的。

我的问题是,显然,具有多个渲染缓冲区/颜色附件的帧缓冲区只能为相同类型的附件定义;这意味着如果一个附件经过多次采样,那么所有其他附件也必须经过多次采样。

这成为分辨率期间位置和法线缓冲区的一个问题,因为几何体和照明会因抗锯齿而受到影响。

  • 我对帧缓冲区附件的理解是否有效?
  • 有没有办法解决这个问题,以便在漫反射和镜面贴图上仍然进行多重采样,但不影响其他贴图?
    // Create the frame buffer for deferred shading: 3 color attachments and a depth buffer
    glGenFramebuffers(1, &gBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    {
        // - Position color buffer
        glGenRenderbuffers(1, &gPosition);
        glBindRenderbuffer(GL_RENDERBUFFER, gPosition);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, gPosition);

        // - Normal color buffer
        glGenRenderbuffers(1, &gNormal);
        glBindRenderbuffer(GL_RENDERBUFFER, gNormal);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, gNormal);

        // …
Run Code Online (Sandbox Code Playgroud)

opengl multisampling framebuffer deferred-rendering deferred-shading

5
推荐指数
1
解决办法
815
查看次数