Results 1 to 4 of 4

Thread: Z values output from shader are inverted.

  1. #1
    Junior Member
    Join Date
    Jul 2010
    Posts
    3

    Z values output from shader are inverted.

    I'm having trouble with z buffering, in my application it seems that the z values of fragments coming out of the vertex shader are the wrong way around, and this is effectively causing the scene to draw the 'wrong' way around, with fragments further away drawing over the top of fragments closer.

    Below is my vertex shader:

    Code :
    attribute vec4 vPosition;
    attribute vec4 vColor;
    attribute vec4 vTexture;
    uniform mat4 u_modelMatrix;
    uniform mat4 u_projectionMatrix;
    uniform mat4 u_textureMatrix;
    varying vec2 a_texCord;
    varying vec4 aColor;
    void main()
    {
       vec4 transformCord = u_textureMatrix * vTexture;"
       gl_Position = u_projectionMatrix * u_modelMatrix * vPosition;
       aColor = vColor;
       a_texCord = transformCord.xy;
    }

    I simply added the line: gl_Position.z = -gl_Position.z; and this inverts the z values and causes the scene to draw properly. This however, is only fixing the symptom, and as DepthFunc is set to LEQUAL i guess the problem can only be in the projection/modelview matrix? Anyone have any ideas on how to flip the z axis in either of these to produce the same result as flipping it here? The maths is a little confusing and nothing i try in either the projection or model view matrix solve the issue. Is this the only place to really fix the problem?

  2. #2
    Senior Member
    Join Date
    May 2010
    Posts
    207

    Re: Z values output from shader are inverted.

    I agree that it's most likely to be your projection matrix...but it's hard to guess what you've done wrong without seeing the code.

    This is what I use (JavaScript...for WebGL):

    Code :
      this.perspective = function ( fovY, aspect, near, far )
      {
        var t =  Math.tan ( fovY / 360.0 * Math.PI ) * near ;
        var b = -t ;
        var r =  t * aspect ;
        var l = -r ;
        var dX = r - l ;
        var dY = t - b ; 
        var dZ = far - near ;
        if ( near <= 0 || far <= 0 || dX <= 0 || dY <= 0 || dZ <= 0 ) return ;
        this.m[1] = this.m[2] = this.m[ 3] = this.m[ 4] = this.m[ 6] =
                    this.m[7] = this.m[12] = this.m[13] = this.m[15] = 0 ;
        this.m[ 0] = 2 * near / dX ;
        this.m[ 5] = 2 * near / dY ;
        this.m[ 8] =  (r + l) / dX ;
        this.m[ 9] =  (t + b) / dY ;
        this.m[10] = -(near + far) / dZ ;
        this.m[11] = -1 ;
        this.m[14] = -2 * near * far / dZ ;
      }

  3. #3
    Junior Member
    Join Date
    Jul 2010
    Posts
    3

    Re: Z values output from shader are inverted.

    Ok so a bit of background, I'm porting from GL 1.5 with extensions, to GLES 2.0, and the projection matrix I'm using in GLES2 works perfectly with the programmable pipe in GL 1.5 (as that's where it originated), all i've changed is doubles to floats as GLES2 only supports floats. I assumed maths was just maths, and it would work fine, but there's possibly a difference in how Z is dealt with between the 2 API's, and i need to flip the Z in the matrix(?).

    Below is the code used to work out the projection matrix:
    Code :
    static void R_SetupProjectionMatrix(const refdef_t *rd, mat4x4_t m)
    {
    #ifndef	GLES2          //if OGL
    	GLdouble xMin, xMax, yMin, yMax, zNear, zFar;
    #else
    	GLfloat xMin, xMax, yMin, yMax, zNear, zFar;
    #endif
     
    	if (ri.params & RP_SHADOWMAPVIEW)
    		// do not alter the farclip distance for shadow map views
    		;
    	else if (rd->rdflags & RDF_NOWORLDMODEL)
    		ri.farClip = 2048;
    	else
    		ri.farClip = R_FarClip();
     
    	zNear = Z_NEAR;
    	zFar = ri.farClip;
     
    	yMax = zNear * tan(rd->fov_y * M_PI / 360.0);
    	yMin = -yMax;
     
    	xMax = zNear * tan(rd->fov_x * M_PI / 360.0);
    	xMin = -xMax;
     
    	xMin += -(2 * glState.cameraSeparation) / zNear;
    	xMax += -(2 * glState.cameraSeparation) / zNear;
     
    	m[0] = (2.0 * zNear) / (xMax - xMin);
    	m[1] = 0.0f;
    	m[2] = 0.0f;
    	m[3] = 0.0f;
    	m[4] = 0.0f;
    	m[5] = (2.0 * zNear) / (yMax - yMin);
    	m[6] = 0.0f;
    	m[7] = 0.0f;
    	m[8] = (xMax + xMin) / (xMax - xMin);
    	m[9] = (yMax + yMin) / (yMax - yMin);
    	m[10] = -(zFar + zNear) / (zFar - zNear);
    	m[11] = -1.0f;
    	m[12] = 0.0f;
    	m[13] = 0.0f;
    	m[14] = -(2.0 * zFar * zNear) / (zFar - zNear);
    	m[15] = 0.0f;
    }

    Here are the values output for the matrix (apologies, the forum strips my formatting). I've interpreted the matrix as being in COLUMN major order, so if this is wrong just swap element 11 and 14 (i actually did this in the code at one point, but it just made the player really small.):
    3.7320509 0 0 0
    0 2.48803401 0 0
    0 0 -1.00391388 -8.01565552
    0 0 -1 0
    Incase this doesn't give you enough info, and you want the various input values, here they are:

    zNear = 4
    zFar = 2048 (in the player setup menu where I'm currently testing, the RDF_NOWORLDMODEL flag is set)

    fov_x = 30
    fov_y = 43.7927361
    M_PI defined as 3.14159265358979323846
    cameraSeparation = 0
    therefore....
    yMax = 1.6076951
    yMin = -1.6076951
    xMax = 1.07179677
    xMin = -1.07179677
    The fov values are specifically to do with the player model being rendered in this case.
    I can give the Model View matrix also if this is needed. It looks to me as if your code and mine are... pretty much exactly the same. Perhaps the problem isnt here?

  4. #4
    Senior Member
    Join Date
    May 2010
    Posts
    207

    Re: Z values output from shader are inverted.

    Well, I guess I'm out of ideas. I'm pretty sure there is no difference in the orientation of matrices and such between OpenGL and OpenGLES - that would be just crazy.

    (Although there **IS** a difference between OpenGL/OpenGLES and Direct3D...the range of Z goes 0..1 on one and -1..1 on the other (I have temporarily forgotten which is which!)...that produces some interesting oddities when you feed a projection designed for one into the other).

Similar Threads

  1. Getting wrong values from image2d_
    By sezaru in forum OpenCL
    Replies: 0
    Last Post: 07-22-2011, 02:48 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •