Struggling to Convert Global Position to Shadow Map position

I am trying to get a global position to the shadow map uv position for a ShadowGenerator Texture.

float sampleSunShadow(vec3 pos){		
		vec4 posFromSun = vec4(pos, distance(sunPosition, pos));		
		vec3 clipSpace = posFromSun.xyz / posFromSun.w;		
		vec2 uv = 0.5 * clipSpace.xy + vec2(0.5);
        if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
        {
            return 1.0;
        }		
	    return texture2D(sunShadowMap, uv).x;
	}

This is what I am currently doing, but it seems to not really work, I have also tried quite a few other methods… figure it just getting the correct combo of matrices.

1 Like

Did you check the shader we use for PBR or stdMat?

yeah, and when I try to duplicate it I seem to still have a sample issue.
Maybe it’s the global position that I am messing up.

Ill check if the PBR example helps me.

hmm its the same function, and as far as I can tell I am using the same process… dang gotta figure this out.

Maybe the position or the light matrix?

Im super close, let me see if I can post a PG for it. Somebody might see what’s good right away.

https://playground.babylonjs.com/#21FNQE#10

its on line 565 where I am sampling the shadowmap, I have a sneaking suspicion I am just sampling the wrong global point or the incorrect perspective amount.

1 Like

why this:

length(pos+sunPosition)+50./600.)
1 Like

I am assuming that is the way to convert the depth of the rayPosition to the Light, but might be wrong.

My shadowMin and max is 50 and 600 units

Ive tried

vec4(pos, distance(pos,sunPosition));

as well.

1 Like

Just to be sure I understand what you want to do:

You want to shadow the clouds that are hidden (blocked by geometries) from the point of view of the sun?

If yes, what I don’t understand is that you take the value from the shadow map (return texture2D(sunShadowMap, uv).x;) as the light attenuation in your lighting equation.

However, the value in the shadow map is a depth from the light point of view (the depth of the geometry nearest to the light). So, in your code, it means the farther the point is from the light, the darker it is, being in shadow or not (meaning no geometry blocking the path of light).

What you need to do is to transform your point into the light (sun) coordinate system and get the depth of this point in this system (the z value). If the depth is less than the one in the shadow map for this location, then the point is not in shadow (so the factor in your lighting equation is 1.), else it is (use whatever factor you want to darken the point).

Going to give a try to do this, but don’t hold your breath…

2 Likes

if we can figure this out then I will optimize the whole system to run at 60 fps, and then introduce simulation shaders to make it so we can have some real volumetric smoke and other things.

I think I know what you are saying, I was mistaken about what the shadowmaps data had on it! I did not realise it was a depth value, now that I know that though we might be able to make this happen.

1 Like

wow I was doing a bunch wrong now that I am looking at it with fresh eyes.

This is the closest I have gotten now.

https://playground.babylonjs.com/#21FNQE#15

And that is still off… I have tried using the lights matrix, the shadowGenerators Matrix hmmm there is gonna be an answer and once its figured out this is gonna look cool…

I think it might be I am sampling the wrong position still, which I am troubleshooting now as I drink me coffeeeee…

1 Like

I think DepthMetric should not be 1.0 in the sampleSunShadow function.

It should be the depth of your point (pos) in the light coordinate system (LCS), meaning the z value after pos is transformed into the LCS. For this you need the light matrix.

Also I don’t really understand the calculation with the sun and point positions, being normalized (?)

1 Like

I don’t either, I’m just guessing at this point… I’ve tried like every combination I can think of.

I’m thinking my sample position was off so I am going back and checking that I am feeling the correct global position in then I am going to try to multiply it by the shadowGenerators TransformMatrix agian and see if I am just being dumb.

Im convinced that this:

vec4 p = shadowMapTransformMatrix * vec4(pos+boxOffset, 1.0);
float depthMetric = 1.0;
vec3 clipSpace = p.xyz / p.w;
vec2 uv = 0.5 * clipSpace.xy + vec2(0.5);

Should work… but maybe I am just using the wrong matrix?

1 Like


Ok so the output position is correct.

...
if (density > 0.0) {			
return vec4(rayPos+boxOffset, 1.0);
...

If I apply a matrix like view I get the expected results.

...
if (density > 0.0) {			
return view*vec4(rayPos+boxOffset, 1.0);
...

Then if I apply the shadowGens Transform Matrix all the “clouds” disapear…

...
if (density > 0.0) {			
return shadowMapTransformMatrix*vec4(rayPos+boxOffset, 1.0);
...

Maybe thats correct? Not sure… I am about to contimplate a different maching method if I have time here before I gotta get on other things.

1 Like

Here it is: https://playground.babylonjs.com/#21FNQE#16

Note that shadowMapTransformMatrix was not in the uniform list passed to BABYLON.PostProcess, so you ended up with an all-0 matrix in the shader.

I mostly copied what is done in the computeShadow method used by the shadow fragment shader used by Babylon.

2 Likes

GOD I LOVE YOU! This is amazing, now to optimize.

I knew it was something stupid…

1 Like

Calling sampleSunShadow is killing perf: I’m at 60fps in fullscreen without it, 20fps else…

1 Like

Fixing all that now!
I’ve got it performing fairly well now considering its procedural noise.

1 Like

@Pryme8 - RayMarcher code is such a GREAT read.

> vec2 cloudMarchSunLight(vec2 rayData, float depth, vec3 offsetDir){

So elegant.

And references: nice!

LIKE the header references: GOOD-PRACTICE, good~links:

// Cloud FX
// Pryme8
// refrencing https://www.youtube.com/watch?v=4QOcCGI6xOU
// and
// Post Page

//WIll do that too.

Hello PERLIN Noise Shadertoy. : )

And the FIX??? Was?

REDCORNER: POSTPROCESSES!

AND BLUECORNER: uniform mat4 shadowMapTransformMatrix!

And that’s what I got from that.


This is getting good…

Can’t wait for next round.

:eagle: : )

It ended up being that I was not passing the Matrix to the shader >_< missed one tiny line of code… hahaha

1 Like