shadow mapping problem

Started by
6 comments, last by _WeirdCat_ 8 years, 11 months ago
I'm trying to render shadow using shadow mapping. But something is wrong. I think my shader could be wrongly written.
What I've tried to do is the following.
Generate the framebuffer for shadow map.
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
GLuint shadow;
glGenTextures(1, &shadow);
glBindTexture(GL_TEXTURE_2D, shadow);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT ,
1366, 768,
0, GL_DEPTH_COMPONENT, GL_FLOAT,
0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
1366, 768,
0, GL_DEPTH_COMPONENT, GL_FLOAT,
NULL);shadow, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "framebuffer error" << endl;
else
cout << "framebuffer is complete" << endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
Use two shader programs. The first is used to render into the depth texture of the framebuffer. The second is used for normal rendering and shadow.
The first shader program is like this.
///////////
first.program.vs
#version 330
in vec3 position;
uniform mat4 mM;
uniform mat4 mV;
uniform mat4 mP;
void main(){ gl_Position = mP * mV * mM * vec4(position, 1.0);
///////////////
first.program.fs
out vec4 fcolor;
void main() { fcolor = vec4(gl_FragCoord.z);
the second shader program is like the following.
//////////
second.program.vs
#version 330
in vec3 position;
in vec2 UV;
out vec2 uv;
// Matrix to get vertex position to clip space
uniform mat4 mM;
uniform mat4 mV;
uniform mat4 mP;
// Proj-View-Model matrix for Light
uniform mat4 mvp;
out vec4 ShadowCoord;
uniform vec3 lightPos;
out float dis;
void main(){ uv = UV;
ShadowCoord = mvp * vec4(position,1.0f);
gl_Position = mP * mV * mM * vec4(position, 1.0); }
//////
second.program.fs
#version 330
uniform sampler2D tex;
uniform sampler2D shadtex;
in vec2 uv; in vec3 normal;
in vec4 ShadowCoord;
out vec3 fcolor;
void main() {
fcolor = ( (texture(tex,uv).rgb));
float shadow = 1.0;
vec4 shadowcoord = (ShadowCoord / ShadowCoord.w);
shadowcoord = 0.5 * shadowcoord + 0.5;
if ((shadowcoord.x < 0 || shadowcoord.x > 1 || shadowcoord.y < 0 || shadowcoord.y > 1 || shadowcoord.z < 0 || shadowcoord.z > 1)){ shadow = 1.0; }
else { float depth = texture2D(shadtex, vec2(shadowcoord.xy)).x; if ( dis > depth ) shadow = 0;} fcolor *= shadow; }";
///////
in the main loop i draw objects in this way:
1. bind framebuffer
2. use first shader program
3. draw the object that cast shadow
4 bind the default framebuffer
5. use second shader program
6. draw the objects that have the shadow casted on them
But the result is not as expected. Is there something wrong in the second program's shaders? Thanks in advance.
In the picture the red box is the light position. The little screen in upper right is what rendered into the framebuffer, what
light sees.The blue plane in front of it is the shadow caster. I only rendered itto the shadow map framebuffer. I rendered the same blue plane in the exact position of the shadow caster, and ground beneath it. The shadow should be in front of the blue plane, not behind it. Also some online tutorial pointed out that glDrawBuffer(GL_NONE) means opengl will not draw to the color texture of the framebuffer, or similar meaning. So I wrote that.
Advertisement


But the result is not as expected

Well, what is expected and what is the result ? Some hints or a screenshot would be helpful.

why you set gldrawbuffer to gl_none?

screenshot and target platform pls

I've updated the question with the pictures where the problem is.

it doesn't matter if it is gldrawbuffer(gl_none) or whatever, the result is the same. So I don't know what's point of asking about it.

It really doesn't matter. If it does, it will surely change something.

why you set gldrawbuffer to gl_none?

Because that's what the spec says. This dates back to the totally incomprehensible specification of EXT_framebuffer_object1, but can also found in the (slightly less obnoxious) wording of the core specification, which states that the initial value for application-generated framebuffers is COLOR_ATTACHMENT0 (which will write color), and only COLOR_ATTACHMENTi or NONE are allowable, otherwise INVALID_OPERATION is generated.

The OP wants to render depth-only, and the framebuffer has no color attachments, so although it would probably work anyway without that glDrawBuffer(GL_NONE), this is "strictly correct".

Not like it makes any sense that you should have to do this (there's no color attachment after all, so it should be pretty clear to OpenGL that no color writes can possibly, or should happen), but pedantically adhering to the wording of the spec, you must do it.

[hr]

1Why, just why do specifications always have to be written in a way so you need to read them 20 times until you understand them?

it's hard to say for sure, but it looks like your shadowmap mvp may be wrong during the 2nd pass.. the first picture shadow projected on the object looks really suspect.

To debug this, try shifting one of the values, such as adding 0.2 to shadowcoord.x, and see what it does to the shadow.

but pedantically adhering to the wording of the spec, you must do it.

Not even necessarily as a measure of pedenticallity…ious…ness…—if you don’t, it may work on one machine and not another.
This is the true evil of the lax adherence to standards. NVIDIA is the cause of many headaches in the world of OpenGL shaders for the same reason.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Probably, I've missed something, but what does the dis vsoutput variable contain?

change depth tex resolution to 512x512, change projection matrix, allpy that to the world 512 / 512 means aspect ratio 1.0

This topic is closed to new replies.

Advertisement