2
\$\begingroup\$

I want to create a scene with 2D pre-rendered background and 3D models for characters (like those classic Final fantasy games).
For the background, I have 2 textures:

  • one to be displayed, with colors, details...
  • one to be used as depth buffer (depth value presented as grayscale value maybe)

I want to write a shader program to help me discard all the pixels(frags) which have the depth smaller than current depth.
But then, do the background and the models have to use the same shader?
What value to compare with the depth value?
Is this approach even possible?

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

"Is this approach even possible?"

What you could do is make a fine resolution full screen "quad" that has it's verticies displaced in the vertex shader according to a lookup into your "depth buffer" texture. That way, the perceived depth of your grayscale image will be written into the currently bound framebuffers depth buffer.

"I want to write a shader program to help me discard all the pixels(frags) which have the depth smaller than current depth."

You don't need to do this, just use OpenGL's depth test.

"What value to compare with the depth value?" OpenGL does this for you, provided you enabled depth testing.

Edit: And of course, the displacement in the vertex shader should approach the camera.

I think the vertex shader should look a bit like this:

attribute vec3 vert;
attribute vec2 uv;
uniform sampler2D depthTexture;
uniform float mapRange; //you will probably need to change this value for every scene

void main() {
  float displacement = texture2D(depthTexture, uv).w*mapRange; //preferably, for the texture you want single channel 32 bits, dunno if ES supports that though
  gl_Position = vec4(vert, 1)+vec4(0, 0, -displacement , 0); // the displacement moves along the negative z axis, which afaik is towards the camera.
}

Fragment shader:

void main() {
  gl_fragColor = vec4(1);
}
\$\endgroup\$
6
  • \$\begingroup\$ I'm trying to to render a texture, so why using a vertex shader and not fragment shader? or are you telling me to render that texture as uv-mapped to a mesh? \$\endgroup\$ Commented Sep 17, 2014 at 9:35
  • \$\begingroup\$ What your fragment shader will output means nothing, because it's the fragments depth position you're interested in. You can't affect the depth of a fragment from the fragment shader, the depth is determined only by the vertices that constitute the polygon of which the fragment is part of. \$\endgroup\$ Commented Sep 17, 2014 at 10:05
  • \$\begingroup\$ afaik, in desktop opengl we can set gl_fragdepth, in es we can use something like GL_OES_depth_texture but our device doesn't support that extension, so I want to try the discarding approach \$\endgroup\$ Commented Sep 17, 2014 at 10:38
  • \$\begingroup\$ @SkeletorDragonBlaster420BlazeI When you refer to "fine resolution full screen quad" do you mean one should send in a vertex for every texel? If you have just the 4 corners of the quad as an input positions to the vertex shader will the depth values be interpolated instead of being read from the texture? \$\endgroup\$ Commented Sep 22, 2014 at 4:35
  • 1
    \$\begingroup\$ @aledalgrande Ideally you would want to have 1 vertex for every texel of the depth texture, but I don't think this is very feasible (or maybe it is, I don't know the machine target). You can't have just a full screen quad, because then you only have 4 points to move around in the vertex shader, which mean that the depth will just look like a quad skewed in some direction. "will the depth values be interpolated instead of being read from the texture?", absolutely, this will be the case \$\endgroup\$ Commented Sep 22, 2014 at 12:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .