PDA

View Full Version : Shadow mapping, need help with framebuffer



sertilou
05-19-2017, 03:47 AM
I'm developing a render engine for a work at the university, I've already implemented rendering, lightning, textures, and now I'm with shadows. To achieve shadows, I'm doing this: (I'm working with C# and OpenTK, which is a wrapper for C#, but the methods are the same)

// AT THE BEGINNING OF MY PROGRAM
// CREATE ANOTHER FRAMEBUFFER FOR DEPTH VALUES




// Framebuffer for shadow mapping
DepthFrameBuffer = GL.GenFramebuffer();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, DepthFrameBuffer);

// texture for that framebuffer
int depthTexture;
depthTexture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, depthTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 1024, 1024, 0, PixelFormat.Rgb, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent16, 1024, 1024, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Nearest);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (float)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (float)TextureWrapMode.ClampToEdge);

// link the texture to the framebuffer
GL.FramebufferTexture(FramebufferTarget.Framebuffe r, FramebufferAttachment.DepthAttachment, depthTexture, 0);

// don't know exactly what this does
GL.DrawBuffer(DrawBufferMode.None);


and the shader for this is:



// VERTEX SHADER
#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;

// Values that stay constant for the whole mesh.
uniform mat4 depthMVP;

void main(){
gl_Position = depthMVP * vec4(vertexPosition_modelspace,1);
}




// FRAGMENT SHADER
#version 330 core

// Ouput data
layout(location = 0) out float fragmentdepth;

void main(){
// Not really needed, OpenGL does it anyway
fragmentdepth = gl_FragCoord.z;
}


// THEN, EVERY FRAME WHEN RENDERING:




public void DrawScene(Scene sc)
{
currentScene = sc;

// Set shader for shadow mapping
DepthShader.Use();
// Set framebuffer for shadow mapping
GL.BindFramebuffer(FramebufferTarget.Framebuffer, DepthFrameBuffer);

// WHAT HERE??

// Set shader to render scene
Shader.Use();
// Set normal framebuffer
GL.BindFramebuffer(FramebufferTarget.Framebuffer, SceneFrameBuffer);

// Calculate camera matrix
mat4 camera = CameraMatrix();
// Set scene background color
SetClearColor(sc.BackgroundColor);
// Draw scene
DrawHierarchy(sc.Root.gameObject, camera.ToMatrix4(), persepctiveMat);*/
}


So the question is: what do I do in (// WHAT HERE), in the code above? I've tried passing the vertices positions just like I do to render the scene normally, using the Ortho matrix instead of the perspective, and the light matrix instead of the camera matrix. But... I can't see anything in the screen. So, I don't know if I'm doing it right.

So three questions:
- Is the code above right?
- What must I do now to continue?
- Once it's done, how can I check if it's right? (for example, rendering the depth map into the screen)

Dark Photon
05-19-2017, 07:12 AM
GL.BindTexture(TextureTarget.Texture2D, depthTexture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, 1024, 1024, 0, PixelFormat.Rgb, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent16, 1024, 1024, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero);



What's going on with that first glTexImage2D? Looks like left-over copy/paste.


So the question is: what do I do in (// WHAT HERE), in the code above? I've tried passing the vertices positions just like I do to render the scene normally, using the Ortho matrix instead of the perspective, and the light matrix instead of the camera matrix. But... I can't see anything in the screen. So, I don't know if I'm doing it right.

So three questions:
- Is the code above right?
- What must I do now to continue?
- Once it's done, how can I check if it's right? (for example, rendering the depth map into the screen)

To address your problem, I would implement the last of your questions first. That is, for now don't do the second pass where you apply the shadow map to the scene in the camera frustum; just cast the scene into the shadow map (the first pass). To help verify that you are getting the shadow map output you want, use a very simple test scene (e.g. one cube in the middle of the light frustum). Then you can either glReadPixels() those depth values back to save to a disk image and view off-line, or even more conveniently do a simple 2nd pass that fills your screen with a single quad textured from your depth map (where you convert the 0..1 depth values into grey-scale color values). Once your reasonable satisfied that the first pass is working properly, add the second pass.