Opengles着色器插值问题

时间:2018-02-16 07:54:02

标签: ios opengl-es opengl-es-2.0 fragment-shader vertex-shader

我看到与着色器插值精度有关的问题。由于着色器对变化变量(在这种情况下为高度)的插值精度,我得到如下所示的扭曲蓝线。我该如何解决?

enter image description here

以下是将数据提供给着色器的方法:

    uint8_t * oglData = CVPixelBufferGetBaseAddress(_pixelBuffer);  

    for (NSInteger i = 0; i < 256; i++) {

       /* Only first two columns blue in BGRA 256x1 buffer */     
        if (i < 2) {
            oglData[4 * i] =   255;
            oglData[4 * i + 1] =  0;
            oglData[4 * i +2]   = 0;
            oglData[4 * i +3] = 1;
        } else {
            oglData[4 * i] =   0;
            oglData[4 * i + 1] =  0;
            oglData[4 * i +2]   = 0;
            oglData[4 * i +3] = 1;
        }
    }
}

以下是着色器:

顶点着色器:

   attribute vec4 position;
   attribute vec4 inputTextureCoordinate;

   varying vec2 textureCoordinate;
   varying float height;

   void main()
   {
     gl_Position = position;                                                          
     textureCoordinate = vec2(inputTextureCoordinate.x, 0.0);
     height = inputTextureCoordinate.y;
   }

Fragment Shader:

   varying highp vec2 textureCoordinate;
   varying highp float height;

   uniform sampler2D inputImageTexture;
   uniform lowp vec4 backgroundColor;

   void main() {
     lowp vec3 colorChannels = texture2D(inputImageTexture, textureCoordinate).rgb;
                                                               //  
    if (colorChannels.b >= height) {                
                 gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
    } else {                                                      
        gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);                                                  
    }

  }

这是绘图代码:

glActiveTexture( GL_TEXTURE0 );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, oglData);

glUniform1i( _inputImageTexture, 0 );

// Set texture parameters
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

glVertexAttribPointer( ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices );
glEnableVertexAttribArray( ATTRIB_VERTEX );

glVertexAttribPointer( ATTRIB_TEXTURECOORDINATE, 2, GL_FLOAT, 0, 0, textureCoordinates );
glEnableVertexAttribArray( ATTRIB_TEXTURECOORDINATE );

glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );

glBindRenderbuffer( GL_RENDERBUFFER, _colorBufferHandle );
[_oglContext presentRenderbuffer:GL_RENDERBUFFER];

编辑:将GL_LINEAR更改为GL_NEAREST解决了问题,这意味着根据min&amp;的类型插入不同的vars。 mag滤镜在纹理参数?但是使用GL_Nearest会创建非平滑曲线。

1 个答案:

答案 0 :(得分:2)

  

我该如何解决?

你不能(至少不是直接) - 这是GPU内部的固定功能硬件,所以你只需要忍受它。

  

将GL_LINEAR更改为GL_NEAREST解决了这个问题,这意味着根据min&amp;的类型插入不同的变量。纹理参数中的mag滤镜?

否 - 变化插值与纹理min / mag滤波器无关。

您的问题是变量插值的不准确性导致您的texture()函数调用中的采样点输入偏离纹素中心,因此GL_LINEAR纹理过滤开始产生影响。 通过使用GL_NEAREST,您可以有效地量化采样点,因此只要误差小于纹理宽度的一半,就可以快速回到所需的纹素。