sinsro
sinsro

Reputation: 915

Render depth buffer to texture

Quite new at shaders, so please bear with me if I am doing something silly here. :)

I am trying to render the depth buffer of a scene to a texture using opengl ES 2.0 on iOS, but I do not seem to get entirely accurate results unless the models have a relatively high density of polygons showing on the display.

So, for example if I render a large plane consisting of only four vertices, I get very inaccurate results, but if I subdivide this plane the results get more accurate for each subdivision, and ultimately I get a correctly rendered depth buffer.

This reminds me a lot about affine versus perspective projected texture mapping issues, and I guess I need to play around with the ".w" component somehow to fix this. But I thought the "varying" variables should take this into account already, so I am a bit at loss here.

This is my vertex and fragment shader:

[vert]
uniform mat4 uMVPMatrix;
attribute vec4 aPosition; 
varying float objectDepth;
void main()
{
    gl_Position=uMVPMatrix * aPosition;
    objectDepth=gl_Position.z;
}

[frag]
precision mediump float;
varying float objectDepth;
void main()
{
    //Divide by scene clip range, set to a constant 200 here
    float grayscale=objectDepth/200.0;
    gl_FragColor = vec4(grayscale,grayscale,grayscale,1.0);
}

Please note that this shader is simplified a lot just to highlight the method I am using. Although for the naked eye it seems to work well in most cases, I am in fact rendering to 32 bit textures (by packing a float into ARGB), and I need very high accuracy for later processing or I get noticeable artifacts.

I can achieve pretty high precision by cranking up the polygon count, but that drives my framerate down a lot, so, is there a better way?

Upvotes: 1

Views: 2084

Answers (2)

the swine
the swine

Reputation: 11031

This is very simple, the depth is not linear so you can not use linear interpolation for z ... you will solve it very easily if you interpolate 1/z instead of z. You can also perform some w math, exactly as suggested by rasmus. You can read more about coordinate interpolation at http://www.luki.webzdarma.cz/eng_05_en.htm (page about implementing a simple software renderer)

Upvotes: 0

rasmus
rasmus

Reputation: 3216

You need to divide z by the w component.

Upvotes: 2

Related Questions