Frustum-Culling

Started by
11 comments, last by JustJim 9 years, 7 months ago

Hey!

I need to know how to calculate which Vertex lies in the Frustum and which does not, as I am loading Primitives into the Buffer and do not want to have more than nedded.

My current technique does it like that


 bool inFrustum(Vector3 point,Vector3 relativeCam)
        {
            Vector3 camToPoint = relativeCam - point;
            camToPoint.Normalize();
            lookAt -= camPos;
            lookAt.Normalize();
            float angle = MathHelper.ToDegrees(Math.Abs((float)Math.Acos(Vector3.Dot(lookAt, camToPoint))));
            if (Math.Abs(angle)>50f/2)
                return false;
            else return true;

RelativeCam means it is the Cam relativ to the Center of the Sphere.

It gets the Vektor of the Camera to the Vertex and the Vektor of the Camera where it is pointing to.

Then it calculates the Angle between them and checks if it is inside the 50° (45° + 5° safety).

But I got a big issue. If I go too close to the object (and while itself is rotating) I get positions where no vertex is getting through this function resulting in an empty window for short times.

Is there any better way for calculating this? Or do I have a calculation-mistake?

I tried to use this :

If

distance to middle < -radius

but it won't work at all Oo.

Advertisement

It appears you're testing only for the points being within the view angle of the frustum. It may be that the points, although within the view angle, are not within the near and far planes of the projection frustum. Check your near- and far-plane settings.

EDIT: You might have to consider the aspect ratio of the frustum, also. Normally the fov is applied to just one axis (vertical), and the width (included angle) along the other axis is adjusted accordingly.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Ah yeah. It was a rather simple approach. As my Farplane and Near-Plane are really long / short (0.01f to 10000000f as it is in Space) i do not care about them.

I have a function, testing if a point is behind another (Z-Buffering) so only half the sphere will be drawn.

The aspect-Ratio is also not that important as I give the Degree of the biggest size ( the width) so the height won't clip that much away but that's okay.

My Problem is, that if the sphere rotates and I am and a close distance, at some degree, the whole sphere disappears and pops up again after rotating on.

If I would check 4 Points of the Frustum Plane, I have another Problem :/

, What if the Cam changes? Z Won't be the Depth anymore and X the Width.

Perhaps not related to the problem you're having, but..


my Farplane and Near-Plane are really long / short (0.01f to 10000000f as it is in Space) i do not care about them

You should care about them! wink.png If your depth buffer is, say, 16 bits, a near- to far-plane ratio of 1 billion means there will be no difference in depth value for objects at 100 units and 110 units. Beyond that distance, resolution becomes exponentially worse and you'll likely get z-fighting issues.

That being said..

How have you determined that the problem lies in the code posted? What values (actual data) have you examined under the conditions you describe?

If problem is reproducible: set a breakpoint for the "return false" condition and examine actual values. Following actual data is often a better troubleshooting technique than staring at code.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

I did pause whenever it blacked out for a moment. And when this happens all the angles are bigger than 50/2


And when this happens all the angles are bigger than 50/2

.. and?

Were the angles supposed to be > 25? Is that an appropriate value for the input values to the calculations? If so, are the inputs themselves correct?

The troubleshooting method I'm suggesting is to determine where the error occurs. At some point, you'll find input values to a code sequence are correct, but the output is incorrect. You have to look at both input and output (not just the output) - normally a section of code and then line by line.

Start by finding a point in your code where the input and output values are correct, and follow the data until you find an incorrect output value. Or, start with an incorrect output and work backwards to the point where the input values are correct. If necessary, examine input and output values for the functions/calcs within a single line of code.

EDIT: You may be mixing vector spaces. RelativeCam-point is a vector in sphere-space. camPos (I assume) is in world-space. I think you're trying to find the angle between the look-at direction of the camera and the direction of the point (vertex) relative to the camera, not the center of the sphere.

That is, Vector3 camToPoint = relativeCam - point; should be camPos-point., if the point is in world-space.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Well it is really confusing when, if the sphere stands still, everything works and it won't disappear compleatly but when the planet is rotating at some angles it disappear.

Thats whats going wrong.

I checked the length of each vertex and they are all almost 1 (because of normalisation) so there can't be an intersection with the nearplane.

I stay the same distance from the sphere but as it rotates it disappears at some angles.

Everything else is finde. At non-Movement it clipps all vertices out that I don't need. (Well it does go for it in a weird way. Somehow..)

Edit: That I tried to.

But there is a problem then. It shows nothing.

The Point is a relative-Point, meaning it is relative to its center. Maybe this is another error

Well, the problem may be revealed by staring at pictures and code (the "Ah-Hah!" principle), but I'm still suggesting you determine by actual value where the problem is (the "There it is!" principle).

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.


private bool checkForClipping(Quad currentQuad, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
        {
            Vector3 currentPos = Vector3.Transform(new Vector3(0, 0, 0), world);
            Vector3 relativeCamPos = currentPos - camPos;
            Vector3 rP1 = currentPos - p1; Vector3 rP2 = currentPos - p2;
            Vector3 rP3 = currentPos - p3; Vector3 rP4 = currentPos - p4;
            if(!inFrustum(rP1,relativeCamPos) && !inFrustum(rP2,relativeCamPos) && !inFrustum(rP3,relativeCamPos) && !inFrustum(rP4,relativeCamPos))
            {
                return true;
            }
            rP1.Normalize(); rP2.Normalize(); rP3.Normalize(); rP4.Normalize();
            relativeCamPos.Normalize();
            float angle1 = MathHelper.ToDegrees(Math.Abs((float)Math.Acos(Vector3.Dot(relativeCamPos, rP1))));
            float angle2 = MathHelper.ToDegrees(Math.Abs((float)Math.Acos(Vector3.Dot(relativeCamPos, rP2))));
            float angle3 = MathHelper.ToDegrees(Math.Abs((float)Math.Acos(Vector3.Dot(relativeCamPos, rP3))));
            float angle4 = MathHelper.ToDegrees(Math.Abs((float)Math.Acos(Vector3.Dot(relativeCamPos, rP4))));
            if (angle1 > 95 && angle2 > 95 && angle3 > 95 && angle4 > 95)
            {
                return true;
            }
            
            return false;
        }
        bool inFrustum(Vector3 point, Vector3 relativeCam)
        {
            Vector3 camToPoint = camPos - point;
            camToPoint.Normalize();
            lookAt -= camPos;
            lookAt.Normalize();
            float angle = MathHelper.ToDegrees(Math.Abs((float)Math.Acos(Vector3.Dot(lookAt,camPos))));
            if (angle > 80f / 2)
                return false;
            else return true;
        }

This is the code ATM

This topic is closed to new replies.

Advertisement