1

I am trying to render and orhto projection of my scenes depth values to a texture inorder to use the texture in a later render cylce to determine what fragments are in shadow. Basically a Shadow Map.

However the texture that I am rendering to ends up being uniformly empty. Given that i can only really test it in a shader i am limited to what output i can generate. However it seems that all my z values in the Texture are 0.

Here is the code that generates the Texture(Width and height are 1024 and pixelFormat is GL_DEPTH_COMPONENT):

this.id = glGenTextures();

glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, pixelFormat, GL_FLOAT, (ByteBuffer) 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);

return id;

Here I create the FrameBuffer and attach the Texture:

// Create a FBO to render the depth
this.depthMapFBO = glGenFramebuffers();
// Create the depth map texture

this.depthMap = new Texture(SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, GL_DEPTH_COMPONENT);

// Attach the the depth map texture to the FBO
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this.depthMap.getId(), 0);

// Set only depth
glDrawBuffer(GL_NONE);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
    throw new Exception("Could not create FrameBuffer" +glCheckFramebufferStatus(GL_FRAMEBUFFER));
}

// Unbind
glBindFramebuffer(GL_FRAMEBUFFER, 0);

Before I render my Scene I call this function to render the depth to the texture:

if(shaderMap.containsKey("shadow")){
    shaderprogram = shaderMap.get("shadow");
}
shaderprogram.bind();

Sun sun = resourceManager.getSun();

Matrix4f LightViewMatrix = transformation.getLightViewMatrix(sun);
Matrix4f modelLightViewMatrix = transformation.getModelViewMatrix(object, LightViewMatrix);
shaderprogram.setUniform("modelLightViewMatrix",modelLightViewMatrix);

glBindFramebuffer(GL_FRAMEBUFFER,this.shadowmap.getDepthMapFBO());
glViewport(0, 0, 1024, 1024);

glClear(GL_DEPTH_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);

this.shadowmap.getDepthMapTexture().bind();

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

glBindVertexArray(object.getMesh().getVaoId());

glEnableVertexAttribArray(0);//Vertex positions
glEnableVertexAttribArray(1);//Color Positions
glEnableVertexAttribArray(2);//Normals

glDrawElements(GL_TRIANGLES, object.getMesh().getVertexcount(),GL_UNSIGNED_INT ,0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

shaderprogram.unbind();

I can post the Matrices for OrthogonalViewMatrix and LightViewMatrix if needed but i did test them and rendered my scene with them and it gives the desired effect of the Camera flying over the Terrain and looking at the center of the map. Basically how you would imagine the scene to look like if the camera was the sun. So I dont think there is anything wrong with them.

This is my second render with normal projections. Basically the normal Camera:

shaderprogram.createUniform("shadowMap");
glActiveTexture(GL_TEXTURE4);
this.shadowmap.getDepthMapTexture().bind();
shaderprogram.setUniform("shadowMap", 4);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

glBindVertexArray(object.getMesh().getVaoId());

glEnableVertexAttribArray(0);//Vertex positions
glEnableVertexAttribArray(1);//Color Positions
glEnableVertexAttribArray(2);//Normals

glDrawElements(GL_TRIANGLES, object.getMesh().getVertexcount(),GL_UNSIGNED_INT ,0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D,0);
shaderprogram.unbind();

Some parts are left out but I think those are the most important Code parts where the Error might be.

Here is the vertex and the fragment shader that is used in the first render cycle for the shadowmap:

#version 330

layout (location=0) in vec3 position;
layout (location=1) in vec2 texCoord;
layout (location=2) in vec3 vertexNormal;

uniform mat4 modelLightViewMatrix;
uniform mat4 orthoProjectionMatrix;

void main()
{
    gl_Position = orthoProjectionMatrix * modelLightViewMatrix * vec4(position, 1.0f);
}

I know i am not using the the texCoords and the vertexNormal. Here the fragment shader:

#version 330

void main()
{
    gl_FragDepth = gl_FragCoord.z;
}

It should just save the Fragments Depth value. And here the part of the normal scenes fragment shader:

float shadowfactor = 0;
vec3 projCoords = mlightviewVertexPos.xyz;
projCoords = projCoords * 0.5 + 0.5;

if (projCoords.z < texture(shadowMap,projCoords.xy).r){
    // Current fragment is not in shade
    shadowfactor = 1;
}else{
    shadowfactor = 0.5;
}

color = color * (vec4(1,1,1,1)* shadowfactor);

fragColor = color;

Im inputing the orthoMatrix and the LightViewMatrix to determine where the fragment would be in the Suns POV and checking the Z Value in that part of the Texture.

The Problem is that shadowfactor seems to be a uniformly black texture. I tried assigning the texture(shadowMap,projCoords.xy).r directly to the fragment to see if there are any differences anywhere but it is all the same black color eg. 0.

I also tried to use the ShadowMap texture directly on the terrain to see if there is anything on there but I also only get a black Texture.

I am aware that this is a very long question but I tried debugging it for the last 2 days and cant find the error. My guess is that I m either not binding the Texture right or that the wrong FrameBuffer is used in the render cycle.

Hopefully someone wants to help and can find the Error.

Thank you for your time in advance, Alex

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Alexander W
  • 55
  • 1
  • 5
  • From the information given so far, I can't say why exactly it fails. Howerver, I have some unrelated issues with your code. Why do you bind the shadow map texture during the shadow map creation pass? That;s useless. Why do you call `glEnable(GL_TEXTURE_2D)`? That enable doesn't even exist in core GL. Why does your shadow map frag shader write `gl_FragDepth`? In the best of all cases, it will just give no benefits at all, but in the worst case, it will disable Hi-Z and early-Z, so completely degrading the performance of your shadow map pass. – derhass May 20 '18 at 18:54
  • @Rabbid76 yes i do bind the program before it set the uniform. mlightviewVertexPos is the vec4 Position of the Fragment mulitplied by the Orthogonal Matrix and the LightViewMatrix.`mlightviewVertexPos = orthoProjectionMatrix * modelLightViewMatrix * vec4(position, 1.0);` That would make it a viewspace coordinate i think but why would that be wrong? – Alexander W May 20 '18 at 19:01
  • @derhass glEnable is in there because I added it trying to fix the problem and probably didnt delete it after no success. Im not sure anymore but I think it was a proposed solution in another question here on stackoverflow. gl_FragDepth doesnt have to be written to but from what i read on the topic it doesnt really matter since that would happen automatically anyway. – Alexander W May 20 '18 at 19:06
  • If I apply the rgb component of shadowMap directly to fragColor its plain white. so i all the rgb values in the texture are 1 I assume. – Alexander W May 20 '18 at 20:29
  • Have you considered using renderdoc to visualize th state of your frame buffer? – Makogan May 21 '18 at 01:28
  • Where do you ever set `orthoProjectionMatrix` for the shadow map shader program? – derhass May 21 '18 at 13:20
  • @Makogan I have not but I will give it a try. – Alexander W May 21 '18 at 13:33
  • @derhass It is set earlier in a init method. Not in the code I provided. – Alexander W May 21 '18 at 13:33
  • A better question methinks, too bad you didnt get a real final answer... – GhostCat Jan 29 '19 at 18:46

0 Answers0