I am trying to do shadow mapping for my renderer. I followed this video (I can’t not post link QAQ) and tried basically any code I can find.
First, I tried to renderer the depth to a color(GL_RGB) texture and it worked. Then, I tried to do the same to a depth(GL_DEPTH_COMPONENT) texture and it failed, I tried to check the depth texture and it seemed that it don’t hold any data(all 0).
There is the steps I did to render depth to textures(only the first step is a little different(the set-ups for textures)):
Step1. Creating a FrameBuffer and a color texture:
public unsafe void Create_Texture_OK()//Not using DepthBuffer
{
FrameBufferID = glGenFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferID);
TexID = glGenTexture();
glBindTexture(GL_TEXTURE_2D, TexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, GL_RGB, 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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TexID, 0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
Debug.LogError("Something went wrong!: Code" + glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Step2. Then I render the scene normally but bind the framebuffer with FrameBufferID
void Render_ShadowMap()
{
Matrix4 _LightSpace = Matrix4.PerspectiveProjection(Core.MainCamera.zNear, Core.MainCamera.zFar, Core.MainCamera.Width, Core.MainCamera.Height, Core.MainCamera.fov) * Matrix4.GetCameraTransform() * Attaching_GameObject.transform.GetTransform(OffSet);
ShadowShader.SetUniform("LightSpace", _LightSpace);
Debug.Log_Once(glGetProgramInfoLog(ShadowShader.Program));
glViewport(0, 0, ShadowMap.Width, ShadowMap.Height);
glBindFramebuffer(GL_FRAMEBUFFER, ShadowMap.FrameBufferID);
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //enable to see the outcome on screen
glBindVertexArray(RenderMesh.Vao);
Draw();
}
And this is the shader I used here to render depth to the texture.
#version 330 core
out vec4 FragColor;
float near = 0.1;
float far = 100.0;
float LinearizeDepth(float depth)
{
float z = depth * 2.0 - 1.0; // back to NDC
return (2.0 * near * far) / (far + near - z * (far - near));
}
void main()
{
float depth = LinearizeDepth(gl_FragCoord.z) / far; // divide by far for demonstration
gl_FragDepth = depth;
FragColor = vec4(vec3(depth), 1.0);
}
In this step I also check the outcome on screen, it looks right.
Step3. Use the texture as a sampler to see if the depth mapping works.
public unsafe static void Show_ShadowMap()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, Core.Width, Core.Height);
glClearColor(0, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ShadowMap.TexID);
glUseProgram(DebugShader.Program);
glBindVertexArray(DebugMesh.Vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, DebugMesh.Indices.Length, GL_UNSIGNED_INT, NULL);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
This is the step where thing goes wrong, in this step, If I use a color texture, it will work(sort of, except the image is upside down and some object is covered by others), but if I use a depth texture instead, it won’t work.
There is the code I used to set up the depth texture, basically the same architecture as Step1 but I changed the texture set-up.
public unsafe void Create_Texture_Testing()
{
TexID = glGenTexture();
glBindTexture(GL_TEXTURE_2D, TexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
FrameBufferID = glGenFramebuffer();
glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, TexID, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
Debug.LogError("Something went wrong!: Code" + glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
I am quite sure the problem is in the set-up for depth texture but I have tried everything and none of them work. Sorry if my question is stupid, I am new to OpenGL. Thanks for your time.