Skip to main content
GameDev.net gamedev.net
🔒 Locked

Depth values in shadow map

Started by finalbout Jan 11, 2007 at 11:10 PM 11 replies 1.6k views
Original Post
finalbout
finalbout
Hi this is my first post here. Wondering anyone might be able to offer any advice on a problem that i got stuck on while trying to render shadows in an Opengl application. I render the scene from the light's point of view using OpenGL into the shadow map which is the pretty standard method. However from here on I do not render the scene for a second pass as usual but use a fragment shader instead to create the final render.(Reason is due to some thesis project I'm working on) Therefore I will like to know how can i get the scalar depth values from the shadow map so that i can store them in a 2-dimensional array(u,v) where I can easily access them for use in my fragment shader. Thanks in advance for any help. one other question: those pixels on the shadow map where nothing is rendered on/no depth value, are they given a 0 or NULL or undefined value...or watever??? Thanks Regards, Jason
vincoof
vincoof
Please let me sum up few things :
- you render a picture from the light's point of view into a depth texture (the shadow texture),
- you do not use this texture for standard shadow mapping because you need a specific shader for your application instead,
- you can't access correct depth values from your texture.

Is that right ?

If so, have you checked the validity of the depth texture you rendered ?

Have you tried standard shadow mapping to make sure the texture is correct and its access too (texture coordinates in the shader) ?
finalbout
finalbout
Thanks vincoof for ur reply.

1. You are right. I render the scene from light's point of view into depth texture
2. Rigtht too because i am supposed to use scalar depth values from shadow map to do some calculations in the fragment shader.
3. Not more of can't access but I don't know how to access/get the scalar values stored in this depth texture. I tried searching for answers on the net but most people just use a function to compare depth value b/w this depth and the pixel depth which is standard way of shadow mapping.

So the main question is HOW to access the depth values in the depth texture/shadow map like you access elements from a simple array?

Thanks

Btw, using standard shadow mapping method with Cg programming gives me a good result with a flat triangle but if i used a sphere, the shadows are alright but the sphere is not shaded properly...(it will be better if i could put a screen shot here but oh well)...my main concern is still the HOW above

Thanks in advance

Regards,
Jason
Schrompf
Schrompf
What hinders you from simply sampling that texture you rendered in? Or did I miss something in your description? A texture is exactly an [x,y] array, using a fragment shader you can render anything you want into it. If you need the depth in it, just write a shader that passes the depth through from the vertex shader and puts it into the out register in the pixel shader.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
Kalidor
Kalidor
Quote:
Original post by finalbout
So the main question is HOW to access the depth values in the depth texture/shadow map like you access elements from a simple array?
You can sample a depth texture exactly the same way as a regular texture inside a fragment shader. You just need to have depth comparisons turned off for the depth texture, then you can use any of the non-shadow texture lookup functions (ie: texture2DProj instead of shadow2DProj in GLSL).
vincoof
vincoof
Yes sampling a texture is as easy as that. Depth textures and traditional color textures are sampled exactly the same way.

For instance in an ARB_program_shader program (copied from the ARB_fragment_program_shadow extension specification) :
!!ARBfp1.0# Example of depth texture sampling## SHOULD make sure that the 2D texture bound to texture unit 0:#    texture format of DEPTH_COMPONENT (for highest quality comparison)#    TEXTURE_MAG_FILTER is NEAREST#    TEXTURE_MIN_FILTER is NEAREST or NEAREST_MIPMAP_NEAREST#TEMP Dt;TEX Dt, fragment.texcoord[0], texture[0], 2D;# Here Dt.x contains the sampled depth component.
finalbout
finalbout
Thanks to all your replies. I appreciate it.
I learnt my stuff mainly from "The Cg Tutorial" so pardon me if I don't fully understand some part of what you all said.
Anyway,

Schrompf: Do you mean that after i render the scene from the light's point of view in my OpenGL application, i enable Cg and pass this texture to the vertex shader and assign it to as a texture coordinate set such as TEXCOORD0 and pass it to the fragment shader. Then do something like "float4 temp = tex2D(someUV,texCoord0)" where "someUV = (0.2,0.5)" for instance....Am i confusing u guys already?? This will give me the depth value at (0.2,0.5) of the texture map/shadow map as a float4 vector...Right?

Kalidor: Pretty much like above. When u say turn off depth comparisons, u mean in the application right? then the rest will be like above.

vincoof: I really don't understand this at all. Sorry.
"
TEMP Dt;
TEX Dt, fragment.texcoord[0], texture[0], 2D;
"
in the fragement shader, Dt.x is the sampled component??? at which part of the texture? I can use TEMP and TEX data structure? Sorry, but i'm really confused.

Anyway,
thanks guys for your help.

One other thing which i asked earlier, if i render the scene from the light's point of view where there is simply no occluders, what will be the depth value in the shadow map? NULL or just 0?? or undefined?

Thanks

Regards,
Jason
Schrompf
Schrompf
Quote:
Original post by finalbout
Schrompf: Do you mean that after i render the scene from the light's point of view in my OpenGL application, i enable Cg and pass this texture to the vertex shader and assign it to as a texture coordinate set such as TEXCOORD0 and pass it to the fragment shader. Then do something like "float4 temp = tex2D(someUV,texCoord0)" where "someUV = (0.2,0.5)" for instance....Am i confusing u guys already?? This will give me the depth value at (0.2,0.5) of the texture map/shadow map as a float4 vector...Right?


Well... yes. How do you sample other textures? It's just like that, there's no difference. Bind that texture to one sampler and sample from it with tex2D().

Just to be sure you understood: There is NO definition at all what data a texture can hold or what meaning this data has. If you decide to write a arbitrary number into the texture, it will stay there for you to read it by tex2D() and similar commands.

Quote:

One other thing which i asked earlier, if i render the scene from the light's point of view where there is simply no occluders, what will be the depth value in the shadow map? NULL or just 0?? or undefined?


You cleared that rendertarget before rendering into it? Well, that's the value you'll read back from pixels that weren't changed in the rendering process. If you did not clear the rendertarget, chances are it contains rubbish or the stuff you rendered into it last frame. Just like the backbuffer.

Bye, Thomas
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
Todo
Todo
Quote:
Original post by finalbout
vincoof: I really don't understand this at all. Sorry.
"
TEMP Dt;
TEX Dt, fragment.texcoord[0], texture[0], 2D;
"
in the fragement shader, Dt.x is the sampled component??? at which part of the texture? I can use TEMP and TEX data structure? Sorry, but i'm really confused.


Don't worry about that code snippet. It's a shader, but written in a language from before GLSL became part of the OpenGL standard. You're better off writing shaders in a higher level language (as this low level language isn't part of the standard).
finalbout
finalbout
Quote:

Just to be sure you understood: There is NO definition at all what data a texture can hold or what meaning this data has. If you decide to write a arbitrary number into the texture, it will stay there for you to read it by tex2D() and similar commands.

Just want to clarify so that i can understand better. When you say no definition what a texture can hold. Do you mean that this is when i just create a texture in my application and just pass in to my shaders as a sampler. In this case, the texture may hold any type of data.
But if i do a
//Create the shadow map textureglGenTextures(1, &shadowMapTexture);glBindTexture(GL_TEXTURE_2D, shadowMapTexture);glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);......drawScene();//Read the depth buffer into the shadow map textureglBindTexture(GL_TEXTURE_2D, shadowMapTexture);glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

in my OpenGL application, i am sort of assigning scalar numerical depth values into the texture a.k.a shadow map, because of the GL_DEPTH_COMPONENT there. In this case, the texture now hold numerical data.
Is my interpretation right?
Quote:

You cleared that rendertarget before rendering into it? Well, that's the value you'll read back from pixels that weren't changed in the rendering process. If you did not clear the rendertarget, chances are it contains rubbish or the stuff you rendered into it last frame. Just like the backbuffer.


for this, by rendertarget do you mean depth bit such as
//First pass - from light's point of viewglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

So if i cleared everything and i render from the light's point of view where the scene is just a triangle on top of a square which acts as a receiver. The places/pixels of the screen that has absolutely nothing but also read into the depth buffer which is read into the shadow map texture will be rubbish values? If this is the situation, how can i ever know if a value i read later in the fragment shader is a valid depth value or just a rubbish inaccurate numerical value?

Can i assign initial values to my texture in my OpenGL application after i create it say...assign a value of -999 to all texels of the texture? So later in my shader program, if i check that the value of a part of the texture is -999, i know it is not what i want, an invalid depth value. If this is possible, how do i go about assigning numerical values to my texture in my OpenGL application? Thanks

Thanks for the help.

Jason

[Edited by - finalbout on January 14, 2007 4:00:35 AM]
Schrompf
Schrompf
Quote:
Original post by finalbout
in my OpenGL application, i am sort of assigning scalar numerical depth values into the texture a.k.a shadow map, because of the GL_DEPTH_COMPONENT there. In this case, the texture now hold numerical data.
Is my interpretation right?


Hmm... sorry, I don't use OpenGL. You better read that up in the documentation.

Normally, textures are just 2D arrays of 1D to 4D vectors. You can write whatever values or vectors of values you can think of in it. Of course there are limitations from the texel format you use, but within that limits you are free to store what you want.

Quote:

for this, by rendertarget do you mean depth bit such as
//First pass - from light's point of viewglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



That should initialise the whole texture to a certain value. The DEPTH bit clears the associated depth buffer, the COLOR bit clears the texture itself. There's another GL command to specify what value is used. I guess there's a default value if you don't specify one. Propably (1, 1, 1, 1) or (0, 0, 0, 1). Look into the documentation for the name of that command.

One more hint at the end: you could have spared yourself most of the waiting time for response if you try to look into the documentation FIRST. Some of your questions are easily answered by the docs.

Bye, Thomas
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
Todo
Todo
Quote:
Original post by Schrompf
One more hint at the end: you could have spared yourself most of the waiting time for response if you try to look into the documentation FIRST. Some of your questions are easily answered by the docs.


I have to agree with Schrompf. You seem to know little about the OpenGL pipeline to begin with, yet you are trying to create with something that requires more than basic knowledge. Get yourself educated on OpenGL first. We are here to help you if you are stuck, and not to teach you 3D CG.

The call you are looking for is glClearDepth. It will clear the depth buffer (see GL_DEPTH_BIT) to the given value (which is a normalized floating point number between 0. and 1. inclusive, not a random value such as -999). Someone mentioned "the semantics" of a texture are yours to determine. While this is true (in todays hardware), depth buffers do not fall under this category. OpenGL for example, classifies the type of a depth buffer as one of the GL_DEPTH_COMPONENT_xxx constants. DirectX has similar restrictions (and often opts to combine the depth and stencil buffers as early as per type). Also, depth buffer lookups (for shadow mapping) are relatively new in OpenGL. Consequently, looking up a depth value requires some careful state setting. Refer to the specs for more in-depth information.
vincoof
vincoof
Quote:
Original post by finalboutvincoof: I really don't understand this at all. Sorry.
"
TEMP Dt;
TEX Dt, fragment.texcoord[0], texture[0], 2D;
"
in the fragement shader, Dt.x is the sampled component??? at which part of the texture? I can use TEMP and TEX data structure? Sorry, but i'm really confused.


TEMP is a declaration keyword and TEX is an operation keyword. But since you seem to be looking at high-level languages, don't bother learning low-level languages. I was just quoting the most basic operation found in a specification which shows that you that you can sample a depth texture just like you can sample a color texture.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.