Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 29

Thread: Reading the depth buffer into texture memory

  1. #11
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by dr4cula View Post
    Any other ideas?
    You'll need to post more complete code. There's nothing inherently wrong with the code you've posted, but it's missing a few key pieces, e.g. the setup of the camera projection, and renderSceneElements().

    Here is a working example based upon the parts which you posted:
    http://pastebin.com/JQzGr1Rk

  2. #12
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    18
    Quote Originally Posted by GClements View Post
    You'll need to post more complete code. There's nothing inherently wrong with the code you've posted, but it's missing a few key pieces, e.g. the setup of the camera projection, and renderSceneElements().

    Here is a working example based upon the parts which you posted:
    http://pastebin.com/JQzGr1Rk
    Hm... I changed my renderSceneElements() to the following for testing purposes and it almost seems to work (screenshot: http://tinypic.com/view.php?pic=14jw8xi&s=5)

    Code :
           glPushMatrix();
    		glBegin(GL_QUADS);
    			glNormal3f(0.0f, 1.0f, 0.0f);
    			glVertex3f(0.0f, 0.0f, 0.0f);
    			glVertex3f(0.0f, 0.0f, 10.0f);
    			glVertex3f(20.0f, 0.0f, 10.0f);
    			glVertex3f(20.0f, 0.0f, 0.0f);
    		glEnd();
     
    		glTranslatef(10.0f, 0.0f, 5.0f);
    		glBegin(GL_QUADS);
    			glNormal3f(1.0f, 0.0f, 0.0f);
    			glVertex3f(0.0f, 0.0f, 0.0f);
    			glVertex3f(0.0f, 0.0f, 2.0f);
    			glVertex3f(0.0f, 2.0f, 2.0f);
    			glVertex3f(0.0f, 2.0f, 0.0f);
    		glEnd();
    	glPopMatrix();

    As for the camera's projection stuff, I just use gluLookAt() from a set of calculated vectors based on the camera's pitch, yaw and roll. I've got a collection of scenes that I can switch between and this is where the camera's projection is set up:

    Code :
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
    	glLoadIdentity(); // load Identity Matrix
     
    	// position the camera
    	Vector3 position = cam_.getPositionVec();
    	Vector3 lookAt = cam_.getLookAtVec();
    	Vector3 up = cam_.getUpVec();
    	gluLookAt(position.x_, position.y_, position.z_, lookAt.x_, lookAt.y_, lookAt.z_, up.x_, up.y_, up.z_); //Where we are, What we look at, and which way is up
     
     
    	// check for polygon mode
    	if(wireframe_) {
    		glPolygonMode(GL_FRONT, GL_LINE);
    	}
    	else {
    		glPolygonMode(GL_FRONT, GL_FILL);
    	}
     
    	// render the currently selected scene
    	p_currentScene_->render();

    And that's it. From there it goes into the render code that I've posted.

    Thank you so much for your help already! I'm just completely stumped as to why I'm getting these odd results...

    EDIT: realized I forgot to post the overall projection stuff (this is set up only once and called only again if the window is resized):
    Code :
    void WindowHandler::ResizeGLWindow(int width, int height) {
    	if (height==0) { // Prevent A Divide By Zero error
    		height=1; // Make the Height Equal One
    	}
     
    	glViewport(0,0,width,height);
     
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
     
    	//calculate aspect ratio
    	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 0.1 ,1500.0f);
     
    	glMatrixMode(GL_MODELVIEW);// Select The Modelview Matrix
    	glLoadIdentity();// Reset The Modelview Matrix
    }

    EDIT2: Now I'm even more confused. Decided to make the "floor" a bit more detailed and then this happened instead (on the right): http://i42.tinypic.com/zxwbuu.png

    I swapped the single big quad with this:

    Code :
    glPushMatrix();
    			for(int i = 0; i < 20; i++) {
    				glTranslatef(1.0f, 0.0f, 0.0f);
    				glPushMatrix();
    					for(int j = 0; j < 10; j++) {
    						glBegin(GL_QUADS);
    							glNormal3f(0.0f, 1.0f, 0.0f);
    							glVertex3f(0.0f, 0.0f, 0.0f);
    							glVertex3f(0.0f, 0.0f, 1.0f);
    							glVertex3f(1.0f, 0.0f, 1.0f);
    							glVertex3f(1.0f, 0.0f, 0.0f);
    						glEnd();
    						glTranslatef(0.0f, 0.0f, 1.0f);
    					}
    				glPopMatrix();
    			}
    		glPopMatrix();

    What on Earth is going on?
    Last edited by dr4cula; 07-27-2013 at 11:38 AM.

  3. #13
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by dr4cula View Post
    Hm... I changed my renderSceneElements() to the following for testing purposes and it almost seems to work (screenshot: http://tinypic.com/view.php?pic=14jw8xi&s=5)
    FWIW, I find that the Z component of the glTranslate() call needs to be a fraction below 0.5 to avoid depth-fighting. I used 0.499 in the example I posted, but the optimum value depends upon the near plane and other factors.

    Quote Originally Posted by dr4cula View Post
    EDIT2: Now I'm even more confused. Decided to make the "floor" a bit more detailed and then this happened instead (on the right): http://i42.tinypic.com/zxwbuu.png

    I swapped the single big quad with this:

    Code :
    glPushMatrix();
    	for(int i = 0; i < 20; i++) {
    		glTranslatef(1.0f, 0.0f, 0.0f);
    You can't change the model-view matrix when drawing the scene, because you're setting GL_TEXTURE_GEN_MODE to GL_OBJECT_LINEAR, so the texture coordinates are based upon the values passed to glVertex() without any model-view transformation applied, and planeMatrix only includes the "camera" transformations (i.e. those from the gluPerspective() and gluLookAt() calls).

    You would need to either switch to GL_EYE_LINEAR (and omit the model-view matrix from the calculation of planeMatrix), or apply every transformation to both the model-view matrix and the texture matrix simultaneously, or update the tex-gen planes whenever you update the vertex transformation, or transform the vertices in the program before passing them to glVertex().

    Or you could switch to using shaders, where you get to control the transformations directly.

  4. #14
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    18
    Quote Originally Posted by GClements View Post
    FWIW, I find that the Z component of the glTranslate() call needs to be a fraction below 0.5 to avoid depth-fighting. I used 0.499 in the example I posted, but the optimum value depends upon the near plane and other factors.


    You can't change the model-view matrix when drawing the scene, because you're setting GL_TEXTURE_GEN_MODE to GL_OBJECT_LINEAR, so the texture coordinates are based upon the values passed to glVertex() without any model-view transformation applied, and planeMatrix only includes the "camera" transformations (i.e. those from the gluPerspective() and gluLookAt() calls).

    You would need to either switch to GL_EYE_LINEAR (and omit the model-view matrix from the calculation of planeMatrix), or apply every transformation to both the model-view matrix and the texture matrix simultaneously, or update the tex-gen planes whenever you update the vertex transformation, or transform the vertices in the program before passing them to glVertex().

    Or you could switch to using shaders, where you get to control the transformations directly.
    I tried switching to GL_EYE_LINEAR, however if I omit the gluLookAt() (which is the model-view part of the planeMatrix) then I'm not getting the results I'm looking for. If I keep that there then it sorta looks OK (the shadow is translated away from the object for whatever reason). I tried this version with my full scene as well and the shadowmap was all over the place there. If I can get the shadowmap working for these 2 panels then I can start looking into the construction of the renderSceneElements() more critically but as it stands now, I'm not still not happy with the two-planes result: http://tinypic.com/view.php?pic=16ive6e&s=5

    Did I even understand your idea with the GL_EYE_LINEAR correctly? The reason I'm going with this solution is that it seems the easiest out of the other options in the fixed-function pipeline OpenGL.

    Thank you so much for your help in advance!

    EDIT: So I tried adding 2 cubes to the scene (GL_EYE_LINEAR with gluLookAt() in planeMatrix) and if I had only 1 cube, it looked OK. Once I added another one of the following happened: 1) the 2nd cube didn't cast a shadow, 2) the 2nd cube casted a massive shadow. Here's what I mean: http://i40.tinypic.com/smghtf.png

    Thanks in advance!
    Last edited by dr4cula; 07-28-2013 at 08:11 AM.

  5. #15
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    [QUOTE=dr4cula;1253262]I tried switching to GL_EYE_LINEAR, however if I omit the gluLookAt() (which is the model-view part of the planeMatrix) then I'm not getting the results I'm looking for.[QUOTE].
    My mistake. planeMatrix needs to contain the part of the model-view transformation which is specific to the light, but not subsequent transformations which are applied to the object.

    Quote Originally Posted by dr4cula View Post
    Did I even understand your idea with the GL_EYE_LINEAR correctly? The reason I'm going with this solution is that it seems the easiest out of the other options in the fixed-function pipeline OpenGL.
    I've posted an updated version which uses eye-linear coordinates. The object can be moved/rotated using shift/control and the arrow/page keys.

    The eye planes are transformed by the inverse-transpose of the model-view matrix at the point that glTexGen() is called, so the model-view matrix needs to be set to the identity matrix at that point (at least, it matters what it's set to; see below).

    The bottom line is that the texture coordinates actually used for the lookup in the second pass need to exactly match (other than the 0..1 -> -1..+1 conversion) the clip coordinates from the first pass. So any transformations which are applied to the vertex coordinates in the first pass must also be applied to the texture coordinates in the second pass.

    "Constant" transformations (i.e. the perspective and look-at transformations which define the view) are dealt with by planeMatrix, but dynamic transformations (transforming objects within the scene) also need to be included, and using eye-linear texture generation does that.

    I think that if you want to apply a gluLookAt() for the camera, you will need to have that transformation in place for the glTexGen() calls, so that using eye-linear coordinates doesn't result in it being applied twice.

  6. #16
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    18
    Ok, so the only difference I could find between our codes was the light FOV. As soon as I changed it to 90.0, the massively long shadows disappeared. This is why I think it was happening: due to the shadowmapping method, everything behind an object from the light's limited POV is shadowed, hence the long shadows from different angles than the light's original angle. Kinda hard to explain what I mean :P But yeh, once I added the call to glLoadIdentity(), the shadow map got stuck in the camera and floated around with it. But like you said, the gluLookAt() for the camera needs to be in place before glTexGen() calls (which it was anyways due to the program's setup) so all I had to do was fix the angle (besides GL_EYE_LINEAR mapping).

    Now, I thought I was done with the problems but ran into 2 odd artifacts:

    1) shadows seem to be translated a bit from the object that casts them: changing the light's near plane changes this. Going from 0.1 to 1.0 gives perfect results distance wise but produces another problem: incorrect texture mapping on some objects. Here's what I mean: http://i40.tinypic.com/an1un9.png
    Also, this is independent of the distance to the light source as there's another cube in the scene further back that has the same problem with the top face texture.

    2) there are weird mappings behind the light: http://i44.tinypic.com/2qnnpjm.png
    One way I can think of to remove those mappings is to disable texturing before rendering the back wall but that doesn't seem like the best idea.

    I can't thank you enough for your invaluable insight! Hope you can help me cross the finish line!

  7. #17
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by dr4cula View Post
    Ok, so the only difference I could find between our codes was the light FOV. As soon as I changed it to 90.0, the massively long shadows disappeared. This is why I think it was happening: due to the shadowmapping method, everything behind an object from the light's limited POV is shadowed, hence the long shadows from different angles than the light's original angle.
    The FoV angle only affects how much of the scene gets rendered. So long as both the shadow caster and shadow target fit within the frustum used in the first pass, the FoV angle won't have any effect.
    However, if any part of the scene lies outside of the frustum, then you'll be getting depth values based upon the texture's wrap mode, which will invariably produce the wrong results.
    Essentially, the frustum used for rendering the depth map needs to encompass all objects which can cast or receive a shadow which is within the camera's frustum. For a simple scene, you can just set the camera's frustum so that it bounds the scene. For more complex scenes, it's common to use multiple depth maps, with one covering the entire region of interest, and another only covering areas closer to the viewpoint. The former is used as a fall-back if the texture coordinates for the former are out of range.

    Quote Originally Posted by dr4cula View Post
    Now, I thought I was done with the problems but ran into 2 odd artifacts:

    1) shadows seem to be translated a bit from the object that casts them: changing the light's near plane changes this.
    Offsetting the Z translation to avoid depth fighting can cause this.

    Quote Originally Posted by dr4cula View Post
    Going from 0.1 to 1.0 gives perfect results distance wise
    The ratio of the far plane to the near plane determines the degree of non-linearity in the depth buffer. Too high a ratio will result in nearly all of the depth range being used for points close to the near plane, resulting in a loss of depth precision for the rest of the scene.

    The problem can be avoided by using an orthographic projection for the light (i.e. a directional light rather than a point light), or using a linear depth buffer (which requires shaders).

    Quote Originally Posted by dr4cula View Post
    but produces another problem: incorrect texture mapping on some objects. Here's what I mean: http://i40.tinypic.com/an1un9.png
    Also, this is independent of the distance to the light source as there's another cube in the scene further back that has the same problem with the top face texture.
    This looks like depth fighting. When using a reciprocal depth buffer, the Z offset has to be tuned based upon the various parameters (light distance, near/far plane distance, scene dimensions, etc).

    Quote Originally Posted by dr4cula View Post
    2) there are weird mappings behind the light: http://i44.tinypic.com/2qnnpjm.png
    Anything which is outside of the frame rendered in the first pass will be wrong. If you're using point lights which are "inside" the scene, things get more complex. Using a cube map should be viable, but it requires rendering 6 views for each light, and I don't know whether it can be done without using shaders.

  8. #18
    Junior Member Newbie
    Join Date
    Jul 2013
    Posts
    18
    Thanks for explaining everything in such detail! Really appreciate it.

    Quote Originally Posted by GClements View Post
    This looks like depth fighting. When using a reciprocal depth buffer, the Z offset has to be tuned based upon the various parameters (light distance, near/far plane distance, scene dimensions, etc).
    Yep, I thought that as well first but then I enabled multitexturing and mapped the shadowmap onto texture unit 1 and I'm still getting the same odd pattern: http://i39.tinypic.com/opcjkn.png
    The image on the right is the top face of the cube (kinda hard to see but it's there).

    EDIT: or actually wait, I was getting z-fighting beforehand with just TU0 as well (0.499 modification)... So what, am I casting shadows on top of each other or?

    EDIT2: Nevermind, I moved the light in the y-direction and it works fine now: http://i44.tinypic.com/33ug6rq.png

    There aren't enough words to describe how grateful I am for your help GClements: seriously, thank you so much. The internet needs more people like you
    Last edited by dr4cula; 07-29-2013 at 09:13 AM.

  9. #19
    Junior Member Regular Contributor
    Join Date
    Nov 2012
    Location
    Bremen, Germany
    Posts
    167
    Sorry if interrupting.
    Not having done shadow-mapping I've got a question: In the image linked above the shadow cast from the box seems to jump out of the plane it is projected on. Is the image just tricking my eye?
    Would the density of the shadow vary based on the distance between the shadowing surface and the light source in nature because of light-Diffusion?

  10. #20
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by hlewin View Post
    In the image linked above
    Which one?
    Quote Originally Posted by hlewin View Post
    the shadow cast from the box seems to jump out of the plane it is projected on. Is the image just tricking my eye?
    Possibly, or it might be caused by the depth offset required to avoid depth fighting.

    Quote Originally Posted by hlewin View Post
    Would the density of the shadow vary based on the distance between the shadowing surface and the light source in nature because of light-Diffusion?
    In its simplest form (used here), shadow mapping results in hard shadows, although there are various techniques which can be used to soften them.

Posting Permissions

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