• Advertisement
Sign in to follow this  

Math for computing relative sun direction

This topic is 1992 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone!

I'm trying to implement sun shafts in my pixel shader. So I need to compute the sun direction relative to the screen / view direction.

I got the following globals:


L_sun_dir_w // absolute (world coords) sun direction
eye_direction // direction of the camera
eye_position // position of the camera


The latter two I'm not sure whether they are absolute or not. However with the right math it should be easy to find out.

What I'm missing now is the math / formula for getting the view-relative sun direction out of those values. Should be a no-brainer for the experienced guys of you, but for me it's quite hard to figure out.

Who can help me with that math?

Share this post


Link to post
Share on other sites
Advertisement

// Transform sun position to screen space
SunPos = mul( SunPos, ViewProj );


float4x4 TexAdj = { 0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f };

SunPos = mul( SunPos, TexAdj );


// Calculate vector from pixel to light source in screen space.
float2 deltaTex = (TexPos - SunPos);
Edited by SIIYA

Share this post


Link to post
Share on other sites
Ok, that code works, except two things that need to be tweaked:

1. On a certain view angle the calculated sun direction abruptly breaks. Seems like some abs() or similar is required at the -180/+180 degrees border of the player view. Any hint what exactly needs to be altered?

2. I figured out that the sun direction provided by the engine is due to some bug about 40 degrees too high positioned in the sky, meaning I need to recalculate the sun direction to come from a sun standing 40 degrees lower than what my L_sun_dir_w value says. How do I transpose/rotate that vector by 40 degrees? Edited by Meltac

Share this post


Link to post
Share on other sites
Just make sure that sun world position is correct when you send it to the shader. What about sun direction? You get that from sun position as in code above.

Share this post


Link to post
Share on other sites
sun position / direction is set by the game engine I'm using, I'm just trying to fix the game shaders without having access to the engine's functions themselves.

So I have to live with the fact that the engine sends a wrong value for sun position / direction to the shader.

The question how I correct that wrong value within the shader by some math / formula. I just need something like


float3 new_sun_direction = rotate_vector_by_Y_axis(old_sun_direction, 40 /* degrees */ );


Can you help me with that formula?

Share this post


Link to post
Share on other sites
Sure, I'm so free to quote some other guy who has made some screenshots:

Notice how the telephone pole is blocking the sun where I am standing, which logically means I should be standing in its shadow. But notice where the pole's shadow is. Way in front of me! Nowhere near where I am:

http://i19.photobuck...unoutofsync.jpg

Here's the sun behind a tree, blocking the sunlight from my view, so I should be in its shadow, but again, the shadow is way in front of me:

http://i19.photobuck...noutofsync2.jpg

And a graphic to show what's happening:

http://i19.photobuck...67/shadows2.jpg

EDIT:
I know from other source that the reason for this lies in the way the engine calculates the sun's coordinates which are passed to the shader. The geometrical horizonal taken for sun light direction calculation is about 40 degrees below the game world's horizon - meaning I'll need a way to correct this shader-wise. A simple vector shift or rotation with these 40 degrees should be accurate enough to make shadows look acceptable. Edited by Meltac

Share this post


Link to post
Share on other sites
I am not surprised as its stalker engine :)....I cant tell you for sure but you could try something like this:

float l = length(sunpos);
sunpos = normalize(sunpos);
sunpos.x *= cos(Angle);
sunpos.z *= sin(Angle);

sunpos *= l;

(do this before the above code)

I am not sure which component(s) should be modified or whether to use sin or cos. Try all combinations :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement