Archived

This topic is now archived and is closed to further replies.

Determine whether the point is in front of the camera?

This topic is 5149 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

Hello all, I am making a len flare in my game engine. However, I have a problem to determin whether the sun position is in front of the camera. "In front of" in here means the area that the camera can see it. Right now, my only soultion is put the sun position into the viewing frustum and test whether it is within the frustum. However, I wonder whether I can have any faster method to do that. Thank for your help!!! Nachi [edited by - nachilau on November 5, 2003 4:12:11 PM]

Share this post


Link to post
Share on other sites
that would be a for a fast culling.

Another fast reject you be to see if the cosine of the angle between the target vector (sunpos - camerapos) and the camera direction is below a limit. You can take the camera FOV, but be careful with the screen aspect ratio.




const float max_lensflare_angle = 30.0f;
const float max_dist_squared = 100.0f;
const float cos_max_lensflare_angle = Cosine(DegToRad(max_lensflare_angle));

Vector Target = (LightSource.Pos - Camera.Pos);

float cos_angle = Target.Dot(Camera.Dir);

if (cos_angle < 0.0f) // sun is behind the camera

return false;

float Dist2 = Target.Dot(Target);

if (!LightSource.IsSun && Dist2 > max_dist_squared)
return false;

float Dist = SquareRoot(Dist2);

cos_angle /= Dist;

if (cos_angle < cos_max_lensflare_angle)
return false;

return true;



That kind of calculations would be reasonably fast for lens flares.

Also, the cosine of the angle will be used later on for the lens flare effect. So the division and square root are kinda free when the sun is actually in the camera.

You also need to do a raycast from the camera to the sun, to see if something is blocking the view. Note that you don't really need to do a ray-cast every frame, if it's too costly. Do one every 0.1 secs, and smoothly fade it in and out, like over 0.5 secs.

For best results, you ought to calculate the area of the sun that is visible from the camera, but it's kinda hard to achieve. [/source]

[edited by - oliii on November 5, 2003 5:08:52 PM]

Share this post


Link to post
Share on other sites
copy/paste...

First make sure to move the modelview to the position of the lensflare.



//
glRasterPos3f(0,0,0);

// Are we still inside our window?
BOOL b;
glGetIntegerv(GL_CURRENT_RASTER_POSITION_VALID, &b);
if (!b)
{ bVisible = false;
}
else
{
// Get position in window
int ivPos[4];
glGetIntegerv(GL_CURRENT_RASTER_POSITION, ivPos);

// Read z-buffer value by using pos in window
float fDepth;
glReadPixels(ivPos[0],ivPos[1],1,1, GL_DEPTH_COMPONENT, GL_FLOAT, &fDepth);

// Get the floating point value of current depth position
// This ranges from 0..1 so we have to have the floating point value
float fvPos[4];
glGetFloatv(GL_CURRENT_RASTER_POSITION, fvPos);

// THE check
if (fvPos[2] > fDepth)
{ bVisible = false;
}
}

//
// Animate alpha
//
if (bVisible)
{ pFrameLensFlare->fFadeAlpha += (float)(pParams->fDeltaTime * 2);
}
else
{ pFrameLensFlare->fFadeAlpha -= (float)(pParams->fDeltaTime * 2);
}
if (pFrameLensFlare->fFadeAlpha < 0)
{ pFrameLensFlare->fFadeAlpha = 0;
return;
}
if (pFrameLensFlare->fFadeAlpha > 1)
{ pFrameLensFlare->fFadeAlpha = 1;
}



Too much undefined classes used sry bout that. But i think you''ll understand.

Share this post


Link to post
Share on other sites
Sorry,

one thing I don''t understand is why you do

cos_angle /= Dist;

in your code? Why don''t you just use cos_angle to check with the max_lensflare_angle?

Thank for your help!!

Nachi




quote:
Original post by oliii
that would be a for a fast culling.

Another fast reject you be to see if the cosine of the angle between the target vector (sunpos - camerapos) and the camera direction is below a limit. You can take the camera FOV, but be careful with the screen aspect ratio.




const float max_lensflare_angle = 30.0f;
const float max_dist_squared = 100.0f;
const float cos_max_lensflare_angle = Cosine(DegToRad(max_lensflare_angle));

Vector Target = (LightSource.Pos - Camera.Pos);

float cos_angle = Target.Dot(Camera.Dir);

if (cos_angle < 0.0f) // sun is behind the camera

return false;

float Dist2 = Target.Dot(Target);

if (!LightSource.IsSun && Dist2 > max_dist_squared)
return false;

float Dist = SquareRoot(Dist2);

cos_angle /= Dist;

if (cos_angle < cos_max_lensflare_angle)
return false;

return true;



That kind of calculations would be reasonably fast for lens flares.

Also, the cosine of the angle will be used later on for the lens flare effect. So the division and square root are kinda free when the sun is actually in the camera.

You also need to do a raycast from the camera to the sun, to see if something is blocking the view. Note that you don''t really need to do a ray-cast every frame, if it''s too costly. Do one every 0.1 secs, and smoothly fade it in and out, like over 0.5 secs.

For best results, you ought to calculate the area of the sun that is visible from the camera, but it''s kinda hard to achieve. [/source]

[edited by - oliii on November 5, 2003 5:08:52 PM]


Share this post


Link to post
Share on other sites
huh... if your doing a lens flare... arn''t you going to need the angle between where your camera is pointing and the sun anyway? unless your planning on making your lens flare to be just a sprite at the position of the sun?

Share this post


Link to post
Share on other sites
Sorry,

I am not sure what you said too. Right now, what I am doing is just finding the sun position in screen space and draw a sprite on that screen position. Then. I find the vector from the center of screen to that sun screen position. Then... I use this two information to draw the len flare. Is there any other way to do len flare rather than using this method? Or where can I get more informaiton about this?


Thanks!

Nachi


quote:
Original post by SpaceDude
huh... if your doing a lens flare... arn''t you going to need the angle between where your camera is pointing and the sun anyway? unless your planning on making your lens flare to be just a sprite at the position of the sun?


Share this post


Link to post
Share on other sites
quote:
Original post by nachilau
Sorry,

one thing I don't understand is why you do

cos_angle /= Dist;

in your code? Why don't you just use cos_angle to check with the max_lensflare_angle?

Thank for your help!!

Nachi




oh that? that's because the target vector is not normalised (not unit length). To get the cos angle between two directional vectors they have to be normalised.

basically

cos (a, b) = a.dot(b) / (|a| * |b|)

The camera direction is normalised (should be anyway), so you need to divide the dot product by the length of the target vector.

cos (target, dir) = target.dot(dir) / (|target| * |dir|) = target.dot(dir) / |target|;




note that, if your sun is at an infinite distance from the viewer, you can represent the sun as a directional light source, defined by a direction vector. Then you don't need to normalise anything

cos_angle = -(Sun.Dir * Camera.Dir);

if it's easier, consider the Sun.Dir like a position on a compass (north, east, west, south-east, ....).

But that's just really unnecessary

[edited by - oliii on November 6, 2003 5:03:02 AM]

Share this post


Link to post
Share on other sites