全屏模糊 GLSL 显示对角线(OpenGL 核心)

Posted

技术标签:

【中文标题】全屏模糊 GLSL 显示对角线(OpenGL 核心)【英文标题】:Fullscreen blur GLSL shows diagonal line (OpenGL core) 【发布时间】:2014-02-07 08:32:57 【问题描述】:

在 OpenGL 2.1 中,我们可以通过使用全屏四边形渲染到 FBO 来创建后处理效果。 OpenGL 3.1 移除了GL_QUADS,所以我们必须使用两个三角形来模拟它。

不幸的是,我在尝试应用这种技术时遇到了一个奇怪的问题:对角线出现在两个三角形的斜边上!

此屏幕截图演示了该问题:

  

我在使用GL_QUADS 的 OpenGL 2.1 中没有对角线 - 当我切换到 GL_TRIANGLES 时,它出现在 OpenGL 3.x 核心中。不幸的是,大多数在线教程都建议使用两个三角形,但没有一个显示这个问题。

// Fragment shader
#version 140
precision highp float;

uniform sampler2D ColorTexture;
uniform vec2 SampleDistance;

in vec4 TextureCoordinates0;
out vec4 FragData;

#define NORM (1.0 / (1.0 + 2.0 * (0.95894917 + 0.989575414)))
//const float w0 = 0.845633832 * NORM;
//const float w1 = 0.909997233 * NORM;
const float w2 = 0.95894917 * NORM;
const float w3 = 0.989575414 * NORM;
const float w4 = 1 * NORM;
const float w5 = 0.989575414 * NORM;
const float w6 = 0.95894917 * NORM;
//const float w7 = 0.909997233 * NORM;
//const float w8 = 0.845633832 * NORM;

void main(void)

    FragData = 
        texture(ColorTexture, TextureCoordinates0.st - 2.0 * SampleDistance) * w2 +
        texture(ColorTexture, TextureCoordinates0.st - SampleDistance) * w3+
        texture(ColorTexture, TextureCoordinates0.st) * w4 +
        texture(ColorTexture, TextureCoordinates0.st + SampleDistance) * w5 +
        texture(ColorTexture, TextureCoordinates0.st + 2.0 * SampleDistance) * w6
    ;


// Vertex shader
#version 140
precision highp float;

uniform mat4 ModelviewProjection; // loaded with orthographic projection (-1,-1):(1,1)
uniform mat4 TextureMatrix;       // loaded with identity matrix
in vec3 Position;
in vec2 TexCoord;

out vec4 TextureCoordinates0;

void main(void)

    gl_Position = ModelviewProjection * vec4(Position, 1.0);
    TextureCoordinates0 = (TextureMatrix * vec4(TexCoord, 0.0, 0.0));

我做错了什么?是否有建议的方式在 OpenGL 3.x/4.x 内核中执行全屏后处理效果?

【问题讨论】:

GL_TRIANGLES 不能很好地替代 GL_QUADS。如果要绘制单个四边形,GL_TRIANGLE_STRIPGL_QUADS 的顶点顺序将相同,因此请使用 GL_TRIANGLE_STRIP 和最初用于构建四边形的 4 个顶点。否则你必须无缘无故地添加 2 个额外的顶点。 GL_TRIANGLE_STRIP 能解决你的问题吗? 确实,GL_TRIANGLE_STRIP 有效。问题出在我的元素缓冲区规范中,即典型的 PEBKAC 问题。请在下方添加答案,以便我接受并关闭此问题! GL_TRIANGLE_STRIPGL_QUADS 实际上没有相同的顶点顺序来绘制具有 4 个顶点的相同四边形。第 3 和第 4 个顶点是相反的。 GL_TRIANGLE_FAN 可以直接替换GL_QUADS,4 个顶点的顶点顺序相同。 您或@AndonM.Coleman 能否为这个问题添加一个可接受的答案,因为它似乎已经解决了?问候布米。 【参考方案1】:

Reto Koradi 是正确的,我怀疑这就是我写原始评论时的意思;老实说,我不记得这个问题了。

您绝对必须交换 2 个顶点索引来绘制条而不是四边形,否则您最终会从四边形的一部分中切出一个较小的三角形。

ASCII 艺术显示以 0、1、2、3 顺序生成的图元之间的差异:

GL_QUADS   GL_TRIANGLE_STRIP   GL_TRIANGLE_FAN

  0-3             0 3               0-3
  | |             |X|               |\|
  1-2             1-2               1-2

                  0-2
                  |/|
                  1-3

至于为什么这可能比使用 6 个不同顶点的两个三角形产生更好的结果,浮点方差可能是罪魁祸首。索引渲染通常可以解决这个问题,但是使用像 GL_TRIANGLE_STRIP 这样的原始类型需要少 2 个索引来将四边形绘制为两个三角形。

【讨论】:

以上是关于全屏模糊 GLSL 显示对角线(OpenGL 核心)的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL GLSL 通过任意形状混合两个纹理

Opengl 3.3 不绘制任何东西。使用 GLSL 330 核心

OpenGL 3.+ glsl 兼容性一团糟?

使用 SDL2 和 xcode 4.6。我设法创建了一个 OpenGL 3.2 核心上下文。但是不能使用 glsl 1.50

OpenGL/GLSL 颜色附件范围

C#开发的OpenRA的GLSL介绍