Tricky question on shader

Nicolas Rougier <[email protected]>
Newsgroups gmane.comp.python.opengl.user
Message-ID <[email protected]>
Hi folks,

I've been playing with gaussian texture filtering using shaders and I obtained a strange "grid" effect on a completely uniform texture. Since all fragments get the same processing and same neighbouring values,I wonder if the grid is the result of some kind of artifact with floating points or the way texture coordinates are interpolated. Or I missed something completely obvious…

I attached the code below. It is self-contained and you should see the grid I'm talking about.

Nicolas

------------------------------------------------------------------------------
Special Offer -- Download ArcSight Logger for FREE!
Finally, a world-class log management solution at an even better 
price-free! And you'll get a free "Love Thy Logs" t-shirt when you
download Logger. Secure your free ArcSight Logger TODAY!
http://p.sf.net/sfu/arcsisghtdev2dev

_______________________________________________
PyOpenGL Homepage
http://pyopengl.sourceforge.net
_______________________________________________
PyOpenGL-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyopengl-users
filter-gaussian.py (text/x-python-script, 6.6 KB)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import math
import ctypes
import numpy as np
import OpenGL.GL as gl
import OpenGL.GLUT as glut

class Shader:
    def __init__(self, vert = None, frag = None, name=''):
        self.uniforms = {}
        self.name = name
        self.handle = gl.glCreateProgram()
        self.linked = False
        self._build_shader(vert, gl.GL_VERTEX_SHADER)
        self._build_shader(frag, gl.GL_FRAGMENT_SHADER)
        self._link()

    def _build_shader(self, strings, stype):
        count = len(strings)
        if count < 1:
            return
        shader = gl.glCreateShader(stype)
        gl.glShaderSource(shader, strings)
        gl.glCompileShader(shader)
        status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS)
        if not status:
            print gl.glGetShaderInfoLog(shader)
        else:
            gl.glAttachShader(self.handle, shader)

    def _link(self):
        gl.glLinkProgram(self.handle)
        temp = ctypes.c_int(0)
        gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, ctypes.byref(temp))
        if not temp:
            gl.glGetProgramiv(self.handle, gl.GL_INFO_LOG_LENGTH, ctypes.byref(temp))
            log = gl.glGetProgramInfoLog(self.handle)
            print log
        else:
            self.linked = True

    def bind(self):
        gl.glUseProgram(self.handle)

    def unbind(self):
        gl.glUseProgram(0)

    def uniformf(self, name, *vals):
        loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc
        if len(vals) in range(1, 5):
            { 1 : gl.glUniform1f,
              2 : gl.glUniform2f,
              3 : gl.glUniform3f,
              4 : gl.glUniform4f
            }[len(vals)](loc, *vals)

    def uniformi(self, name, *vals):
        loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc
        if len(vals) in range(1, 5):
            { 1 : gl.glUniform1i,
              2 : gl.glUniform2i,
              3 : gl.glUniform3i,
              4 : gl.glUniform4i
            }[len(vals)](loc, *vals)


vert = '''
void main()
{
    gl_FrontColor = gl_Color;
    gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
    gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
}
'''


frag = '''
float
gaussian(float x)
{
    float PI = 3.14159265358979323846264;
    return exp(-2.0 * x * x) * sqrt(2.0 / PI);
}

vec4
filter( float x, vec4 c0, vec4 c1, vec4 c2, vec4 c3 )
{
    vec4 r = c0 * gaussian(x+1.0); // h.x;
    r     += c1 * gaussian(x+0.0); // h.y;
    r     += c2 * gaussian(1.0-x); // h.z;
    r     += c3 * gaussian(2.0-x); // h.w;
    return r;
}

vec4
interpolate( sampler2D texture, vec2 uv, vec2 pixel )
{
    vec2 texel = uv/pixel - vec2(0.5,0.5) ;
    vec2 f = fract(texel);
    texel = (texel-fract(texel)+vec2(0.001,0.001))*pixel;

    vec4 t0 = filter( f.x,
        texture2D( texture, texel + vec2(-1, -1)*pixel ),
        texture2D( texture, texel + vec2( 0, -1)*pixel ),
        texture2D( texture, texel + vec2( 1, -1)*pixel ),
        texture2D( texture, texel + vec2( 2, -1)*pixel ) );

    vec4 t1 = filter( f.x,
        texture2D( texture, texel + vec2(-1,  0)*pixel ),
        texture2D( texture, texel + vec2( 0,  0)*pixel ),
        texture2D( texture, texel + vec2( 1,  0)*pixel ),
        texture2D( texture, texel + vec2( 2,  0)*pixel ) );

    vec4 t2 = filter( f.x,
        texture2D( texture, texel + vec2(-1,  1)*pixel ),
        texture2D( texture, texel + vec2( 0,  1)*pixel ),
        texture2D( texture, texel + vec2( 1,  1)*pixel ),
        texture2D( texture, texel + vec2( 2,  1)*pixel ) );

    vec4 t3 = filter( f.x,
        texture2D( texture, texel + vec2(-1,  2)*pixel ),
        texture2D( texture, texel + vec2( 0,  2)*pixel ),
        texture2D( texture, texel + vec2( 1,  2)*pixel ),
        texture2D( texture, texel + vec2( 2,  2)*pixel ) );

    return filter( f.y, t0, t1, t2, t3 );
}

uniform vec2 pixel;
uniform sampler2D texture;
void main()
{
    gl_FragColor = interpolate(texture, gl_TexCoord[0].xy, pixel);
}
'''


if __name__ == '__main__':
    import sys

    def on_display( ):
        gl.glClearColor(1,1,1,1)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

        x,y,w,h = gl.glGetIntegerv(gl.GL_VIEWPORT)
        gl.glEnable( gl.GL_BLEND )
        gl.glBlendFunc (gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
        gl.glColor( 1, 0, 0, 1 )

        shader.bind()
        gl.glEnable( gl.GL_TEXTURE_2D )
        gl.glActiveTexture( gl.GL_TEXTURE0 )
        gl.glBindTexture( gl.GL_TEXTURE_2D, texture_id)
        shader.uniformi('texture', 0)
        shader.uniformf('pixel', 1.0/Z.shape[0], 1.0/Z.shape[1])
        gl.glBegin( gl.GL_QUADS )
        gl.glTexCoord2f( 0, 1 ), gl.glVertex2f( x,   y   )
        gl.glTexCoord2f( 0, 0 ), gl.glVertex2f( x,   y+h )
        gl.glTexCoord2f( 1, 0 ), gl.glVertex2f( x+w, y+h )
        gl.glTexCoord2f( 1, 1 ), gl.glVertex2f( x+w, y   )
        gl.glEnd()
        shader.unbind()
        glut.glutSwapBuffers( )


    def on_reshape( width, height ):
        gl.glViewport( 0, 0, width, height )
        gl.glMatrixMode( gl.GL_PROJECTION )
        gl.glLoadIdentity( )
        gl.glOrtho( 0, width, 0, height, -1, 1 )
        gl.glMatrixMode( gl.GL_MODELVIEW )
        gl.glLoadIdentity( )


    def on_keyboard( key, x, y ):
        if key == '\033':
            sys.exit( )

    glut.glutInit( sys.argv )
    glut.glutInitDisplayMode( glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH )
    glut.glutCreateWindow( "glumpy filters" )
    glut.glutReshapeWindow( 800, 800 )
    glut.glutDisplayFunc( on_display )
    glut.glutReshapeFunc( on_reshape )
    glut.glutKeyboardFunc( on_keyboard )

    def func3(x,y):
        return (1-x/2+x**5+y**3)*np.exp(-x**2-y**2)
    x = np.linspace(-3.0, 3.0, 32)
    y = np.linspace(-3.0, 3.0, 32)
    Z = func3(*np.meshgrid(x, y))
    Z = (Z-Z.min())/(Z.max()-Z.min())
    Z[:] = 0.5

    texture_id = gl.glGenTextures(1)
    gl.glPixelStorei( gl.GL_UNPACK_ALIGNMENT, 1 )
    gl.glPixelStorei( gl.GL_PACK_ALIGNMENT, 1 )
    gl.glBindTexture( gl.GL_TEXTURE_2D, texture_id )
    gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST )
    gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST )
    gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP )
    gl.glTexParameterf( gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP )
    gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA,
                     Z.shape[0], Z.shape[1], 0, gl.GL_ALPHA, gl.GL_FLOAT, Z )
    gl.glTexEnvf( gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_MODULATE )
    shader = Shader(vert,frag)
    glut.glutMainLoop( )
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.