Sun is not in the right position in the sky!

Started by
6 comments, last by GameDev.net 17 years, 6 months ago
Hello, is this d3d forum question or maths forum! My sun is really misbehaving. I am telling my light to have a direction of ( 0.0f, -1.0, 0.0f ), overhead. Objects are lit correctly, and my shadows are underneath the objects as you would hope. However, my sun and lens flare code is producing some undesirable results. The sun is very low on the horizon, not overhead at all! Heres the sun position updates code:

void cLensFlare::Update()
{
	D3DXVECTOR3 sunPos;
	D3DXVec3Normalize( &sunPos, &( g_lightDirection) );

	// transform to screen coordinates
	D3DXMATRIX viewProj, proj;
	g_device->GetTransform(D3DTS_PROJECTION, &proj);
	D3DXMatrixMultiply( &viewProj, g_camera->GetViewMatrixPtr(), g_simulation->GetProjMatrixPtr() );//&proj );
	D3DXVec3TransformCoord(&m_screenPos, &sunPos, &viewProj);

	// make sure we are in front of the camera
	float dotResult= D3DXVec3Dot( &(-g_lightDirection), &(g_camera->GetForwardVector()) );

	// is the sun in view?
	if (m_screenPos.x > -1.2f 
		&& m_screenPos.x < 1.2f
		&& m_screenPos.y > -1.2f 
		&& m_screenPos.y < 1.2f
		&& dotResult > 0.0f)
	{
		m_isVisible = true;
	}
	else
	{
		m_isVisible = false;
	}


Something to do with my transforming to screen coords I imagine. Advice appreciated. Thanks Si
Advertisement
Thoughts based on first glance:

Quote:
D3DXMATRIX viewProj, proj;
g_device->GetTransform(D3DTS_PROJECTION, &proj);
D3DXMatrixMultiply( &viewProj, g_camera->GetViewMatrixPtr(), g_simulation->GetProjMatrixPtr() );//&proj );
D3DXVec3TransformCoord(&m_screenPos, &sunPos, &viewProj);


So this will give you a position in clip space, and after the homogeneous divide (transformation by the viewport matrix is another implicit step that D3D does for you when rendering)...

In this space, the left edge of the screen (at the view plane) has an x coordinate of -1.0f, and the right edge of the screen has an x coordinate of +1.0f. Likewise with y for bottom and top.

Are you drawing the sun-flare/sun in the same space? or are you using the x,y from this space as 'screen'/'device' coordinates?

If you were passing clip space coordinates to something that expected screen/device space coordinates, I'd imagine it would hover around the horizon/middle of the screen.



Hmm, on second glance, also, if you're going to be using the light direction vector to fudge a sun 'position', surely that should be -g_lightDirection rather than g_lightDirection (assuming it's pointing in the direction from the light).

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

The shader passes the supplied vertex positions straight through, so I gather they are in clip space.

You are right about the -lightdirection, One of those bits i'd fiddled with and not changed back. this just changes whether its slightly above the horizon or slightly below.

Nothing wrong with the actual transformation itself?

hmm
Ok, something has gone awry...

I've noticed that as I turn one way, the sun turns the other!

This didn't used to happen.
Quote:Original post by sipickles
The shader passes the supplied vertex positions straight through, so I gather they are in clip space.

You are right about the -lightdirection, One of those bits i'd fiddled with and not changed back. this just changes whether its slightly above the horizon or slightly below.

Nothing wrong with the actual transformation itself?

hmm



Actually, I knew there was something else bugging me about using the light direction vector as a position...

sunPos will always be 1 unit from the origin (due to being based on a normalised direction). The projection transform scales the space inside the frustum into a 2x2x1 unit box. So that "1 unit from the origin" gets scaled down too. If your unit size is pretty small, the amount 1 unit will move will be too...

So sunPos needs to be scaled up prior to transformation. Multiply it by Zfar (since it kinda is in real life), transform as above and render. If you're using the transformed Z value for the sprite(s), you'll need to fiddle with their Z values so that they appear just inside your sky dome/box for the sun, and in front of other stuff for the flares [or you could just not Z write for them].


As for the directional thing, remember that the viewport transform does flip the Y coordinate (cartesian style to screen/device style).

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Theoretically that makes a lot of sense, now the sun position is ( 0, 2000, 0 ), not ( 0, 1, 0 ).

Unfortunately, theres no difference onscreen :(
curiouser and curiouser...

At this point I'd start making sure the matrices being used to compute viewProj were valid (e.g. not being left at identity or ending up as a 0 matrix). A just-in-case note: if they've come from a GetTransform(), that won't work for a D3DCREATE_PUREDEVICE device.

The next port of call would probably be the sprite drawing routine and the inputs it takes.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Why don't u hardcode a position for the sun, instead of using the lightdirection? This would make testing abit easier i think.

This topic is closed to new replies.

Advertisement