[lwjgl/joml] shadow mapping and matrices

Hello,

I’m trying to have shadows in my game, I have 2 things that should work quite the same way (in my understanding), one is, but the other is not.

I have a world, with things in it, like a floor, walls, trees etc… and a camera that is flying, looking at the hero, which is on the floor. nothing unusual :slight_smile:
I added a directional light so that i have a sun, and i made it move, and it works great. But during the night, the sun isn’t there, so i added a spotlight on my hero’s belt so that he can see where he walks. And that works great too. But i felt sad because the trees in my world didn’t have shadows, so i wanted shadows.

I could manage a nice shadow for the sun, but it’s been days and days (and nights too ^^), and i can’t do the same for my hero’s spotlight… The way i see it, shadows for a directional light and shadows for a spotlight should work quite the same way, apart from the different projection, but maybe i’m doing a big newbie mistake here.

Here’s the way i do things, i can provide code samples if need be, i hope someone can help me find my mistake.

For the sun’s shadows (the ones that are working) : i have to create a position for the sun, since it’s a directional light, it doesn’t have any. I know the direction, and i known the size of my scene, so i deduce a position somewhere outside the scene, from the direction, not too far away to keep a good resolution in my depth map. Once i have that position and direction (that is my dirlightViewMatrix), i create an orthographic projection, big enough to have all my scene in it (this is my dirlightOrthoProjMatrix). Then i render all my scene into a texture which i call dirlightShadowmap in a dedicated shader program. Then, i have to render my scene to the screen, deciding which position is in shadow and which is not, so in my vertex shader, i do that : mdirlightviewVertexPos = dirlightProjMatrix * dirlightViewMatrix * modelMatrix * vec4(position, 1.0); so that my fragment shader can then knwo the position of a fragment in the sun’s point of view. In my fragment shader, i multiply the color by some constant if the fragment is in shadow (that is, if it’s z position in light view is greater than the corresponding xy position in the depth map). As i understand it, mdirlightVertexPos is in screen coordinates, [-1; 1], so i multiply it by 0.5 and add 0.5 to convert it to texture coordinates (so the values match those in my depth map).

and as i said, it works great.

Now, here’s what i do for my spotlight, which doesn’t work as expected : I already know the position, and direction of my spotlight, so i can use that as spotlightViewMatrix. I also know the cutoff angle of my spotlight, so i can create a perspective with the cutoff angle, a 1:1 aspect ratio, a really near znear and a far enough zfar, this is my spotlightProjMatrix. Then, same as for the sun, i render the scene from that point of view in a second texture, using a dedicated shader program. So i then i render my scene, and i do the same as for the sun : mspotlightviewVertexPos = spotlightProjMatrix * spotlightViewMatrix * modelMatrix * vec4(position, 1.0); so that my fragment shader can know the position of the fragment in the spotlight’s point of view, and decide wether or not the fragment is in shadow.

But it doesn’t work as expected. everything farther than 1 world unit from my hero is in shadow. Between 0 and 1, the shadow works as expected (that is, if i put my hero against a very very thin wall, the light doesn’t go through), but no light farther than 1. If i divide mspotlightviewVertexPos by my perspective’s zfar, the light goes all the way, and there are shadows, but distorted.

So here i am, i think i may have a mistake in my perspective matrix, or the way i compare mspotlightViewVertexPos with the depth map, but i can’t find that mistake.

Hope someone can help =)