Skip to content

Instantly share code, notes, and snippets.

@paniq
Last active October 23, 2025 15:19
Show Gist options
  • Select an option

  • Save paniq/6c7a465b841dc2c87294c61108370389 to your computer and use it in GitHub Desktop.

Select an option

Save paniq/6c7a465b841dc2c87294c61108370389 to your computer and use it in GitHub Desktop.

Revisions

  1. paniq revised this gist Sep 11, 2017. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -35,6 +35,8 @@ Let's drop from 3D space to 2D space and attempt to solve the problem there. Now

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge, but in ellipse-space. We'll need to save our skew matrix for later so we can transform our solution lines back to world space.

    We can simplify our problem further by making use of the fact that the circle is invariant to rotation, and rotate the space so that our screen line is axis-aligned (in 2D, I pick a vertical alignment). This saves us a line/line intersection test and allows us to drop the orientation component of our line vector, because we only need its size scalar.

    We end up with four possible arrangements of circle and wedge:

    A. A circle that crosses both boundary lines - contained, occluding.
    @@ -45,13 +47,12 @@ C. A circle that crosses no boundary line and is left of one line and right of t

    D. A circle that crosses no boundary line and is either left or right of both boundary lines - not contained, not occluding.

    To resolve these predicates we need seveal analytical equations, which are readily available:
    To resolve these predicates we need several analytical equations, which are readily available:

    * A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width) if there is an intersection, and for any case tells us if the circle's center is left or right of the line.
    * A line / line intersection test that gives us the intersection point. Two lines will never be parallel in our problem, so this case does not have to be tested.
    * Given a line and a circle, compute two lines parallel to the original line that bound the circle and the contact points where lines and circle touch.

    With these two equations we can deduce our near and far lines (which are parallel to the screen line).
    With these equations we can deduce our near and far lines (which are parallel to the screen line).

    * For case C, our near and far line are simply the ones that bound the circle. Done.
    * For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise it intersects with near or far intersection points of circle and wall line.
    @@ -65,6 +66,8 @@ After this, we transform the lines back to world space, and that is the 2D case

    Let's add one more dimension and observe. Analog to the 2D case, we can rotate and scale the ellipsoid into a unit sphere. Our wall planes, edge lines and screen plane will be transformed to ellipsoid-space, and we will simply transform our solution back later on.

    We also make use of the fact that the sphere is invariant to rotation as well, and rotate the space so that our screen plane is axis-aligned (aligning it to Z seems the obvious choice). This saves us a line/plane intersection test and allows us to drop the normal component of our plane, because we only need its `w` scalar.

    These are our possible cases in 3-space:

    A. A sphere that intersects all wall edges - contained, occluding.
    @@ -79,7 +82,6 @@ These are the analytical equations we need to solve all predicates, and again, t

    * A sphere / plane intersection test that gives us the parameters of the resulting circle embedded in 3-space, and for any case tells us in which half-space the sphere's center is in.
    * A ray / sphere intersection test that gives us entry and exit point if there is an intersection.
    * A ray / plane intersection test that gives us the intersection point. Ray and plane will never be parallel, so this case does not have to be tested.
    * Given a plane and a sphere, compute two planes parallel to the original plane that bound the sphere, and the two contact points where planes and sphere touch.
    * Given a plane and a circle, compute two planes parallel to the original plane that bound the circle and the contact point where plane and circle touch. Our screen planes will never be parallel to the circle's plane, so this case does not have to be tested.

  2. paniq revised this gist Sep 10, 2017. 1 changed file with 46 additions and 11 deletions.
    57 changes: 46 additions & 11 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,11 @@
    Ellipsoid Frustum Intersection
    ==============================

    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothered me for a while now, and right after I've had a few exchanges on Twitter that inspired me to attempt a solution.
    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothered me for a while now, and right after I've had a few exchanges on Twitter, I got inspired to attempt a solution.

    The problem is about a form of refining raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen, _without any precalculated accelleration structure_. How does it work? Well, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could
    Here it goes. It's 100% untested but I'm fairly certain that it will work.

    The problem is about a form of refining raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen or a shadow map, _without any prebuilt accelleration structure_. How does it work? Well, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could

    1. Start with a very low resolution
    2. Collect a list of ellipsoids contained in each tile, culling the ones not contained or fully occluded
    @@ -17,19 +19,19 @@ And this brings us to the problem: we want to solve for a tile on screen
    3. Whether the ellipsoid covers the tile fully (occludes its background completely, also important for culling)
    4. What the near and far depth range of the portion is that fully covers the tile (so we can also cull overlapping ellipsoids)

    You see that the problem is analog to raytracing, but we are frustum tracing: instead of a ray, we extrude and expand a rectangle which forms a 4-sided open-faced pyramid in space, or simpler yet, four planes. The depth values that we are interested in are represented by planes parallel to the screen plane. These planes intersect in each corner of the rectangle to form lines. So the participants in this problem are:
    You see that the problem is analog to raytracing, but we are frustum tracing: instead of a ray, we extrude and expand a rectangle which forms a 4-sided open-faced pyramid in space, or simpler yet, four planes. The depth values that we are interested in are represented by planes parallel to the screen plane. These planes intersect in each corner of the rectangle to form edge lines. So the participants in this problem are:

    * An ellipsoid
    * Four wall planes of our frustum
    * Four corner lines of our frustum
    * Four edge lines of our frustum
    * A screen plane - whose positions we want to find (outer near/far, inner near/far)

    Now the screen plane and the wall and corner planes are not necessarily arranged symmetrically and orthogonally, but can be skewed due to the position of the screen tile we are interested in. In the beginning, this sounds like an added complication, but it will be helpful that we don't have an invariant here that we might feel must be protected (and instead get another one that we will profit from)
    Now the screen plane and the wall plane and edge lines are not necessarily arranged symmetrically and orthogonally, but can be skewed due to the position of the screen tile we are interested in. In the beginning, this sounds like an added complication, but it will be helpful that we don't have an invariant here that we might feel must be protected (and instead get another one that we will profit from)

    2D Case
    -------

    Let's drop from 3D space to 2D space and attempt to solve the problem there. Now our ellipsoid is just an ellipse, and our frustum is simply a wedge formed by two lines originating from an eye point (analog to our four planes or four corner lines - here they collapse to the same thing) and a screen line (analog to our screen plane) arranged semi-orthogonally to the eye point.
    Let's drop from 3D space to 2D space and attempt to solve the problem there. Now our ellipsoid is just an ellipse, and our frustum is simply a wedge formed by two lines originating from an eye point (analog to our four planes or four edge lines - here they collapse to the same thing) and a screen line (analog to our screen plane) arranged semi-orthogonally to the eye point.

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge, but in ellipse-space. We'll need to save our skew matrix for later so we can transform our solution lines back to world space.

    @@ -43,28 +45,29 @@ C. A circle that crosses no boundary line and is left of one line and right of t

    D. A circle that crosses no boundary line and is either left or right of both boundary lines - not contained, not occluding.

    To resolve these predicates we need two kinds of analytical equations, which are both readily available:
    To resolve these predicates we need seveal analytical equations, which are readily available:

    * A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width) if there is an intersection, and for any case tells us if the circle's center is left or right of the line.
    * A line / line intersection test that gives us the intersection point. Two lines will never be parallel in our problem, so this case does not have to be tested.
    * Given a line and a circle, compute two lines parallel to the original line that bound the circle and the contact points where lines and circle touch.

    With these two equations we can deduce our near and far lines (which are parallel to the screen line).

    * For case C, our near and far line are simply the ones that bound the circle. All done.
    * For case C, our near and far line are simply the ones that bound the circle. Done.
    * For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise it intersects with near or far intersection points of circle and wall line.
    * Case A is analog to case B, except we now have two intersection points to consider per line if the contact point is outside the wedge. In this case we pick the nearest or farthest intersection point among each pair.
    * Also, for case A, we also need to compute the fully covered range, formed by two screen lines overlapping with the inner intersection points. Both intersections of each screen line with the wall lines must be inside the circle, or we don't have a fully covered range.
    * For case A, we also need to compute the fully covered range, formed by two screen lines overlapping with the inner intersection points. Both intersections of each screen line with the wall lines must be inside the circle, or we don't have a fully covered range.

    After this, we transform the lines back to world space, and that is the 2D case handled.

    3D Case
    -------

    Let's add one more dimension and observe. Analog to the 2D case, we can rotate and scale the ellipsoid into a unit sphere. Our wall planes, corner lines and screen plane will be transformed to ellipsoid-space, and we will simply transform our solution back later on.
    Let's add one more dimension and observe. Analog to the 2D case, we can rotate and scale the ellipsoid into a unit sphere. Our wall planes, edge lines and screen plane will be transformed to ellipsoid-space, and we will simply transform our solution back later on.

    These are our possible cases in 3-space:

    A. A sphere that intersects all wall corners - contained, occluding.
    A. A sphere that intersects all wall edges - contained, occluding.

    B. A sphere that intersects one or more wall planes and is inside the frustum - contained, not occluding.

    @@ -76,6 +79,38 @@ These are the analytical equations we need to solve all predicates, and again, t

    * A sphere / plane intersection test that gives us the parameters of the resulting circle embedded in 3-space, and for any case tells us in which half-space the sphere's center is in.
    * A ray / sphere intersection test that gives us entry and exit point if there is an intersection.
    * A ray / plane intersection test that gives us the intersection point. Ray and plane will never be parallel, so this case does not have to be tested.
    * Given a plane and a sphere, compute two planes parallel to the original plane that bound the sphere, and the two contact points where planes and sphere touch.
    * Given a plane and a circle, compute two planes parallel to the original plane that bound the circle and the contact point where plane and circle touch. Our screen planes will never be parallel to the circle's plane, so this case does not have to be tested.

    With these equations we can deduce our near and far planes (which are parallel to the screen plane).

    * For case C, our near and far planes are simply the ones that bound the sphere. Done.
    * For case A and B, the near or far plane only bounds the sphere if the contact point is inside the frustum. Otherwise it bounds the circle if the contact point is inside the wedge. Otherwise the plane intersects with near or far intersection points of sphere and edge ray. We need to collect all valid intersections inside the frustum and pick the nearest / farthest to get our final range.
    * For case A, we also need to compute the fully covered range, formed by two screen planes overlapping with the inner edge intersection points. All four intersections of each screen plane with the edge rays must be inside the sphere, or we don't have a fully covered range.

    After this, we transform the planes back to world space, and are all done.

    Limitations and Caveats
    -----------------------

    The solution won't work for ellipsoids with a zero (disc) or infinite component (cylinder of infinite length) because we can't transform those back to unit spheres (discs will cause frustum walls to become parallel, cylinders will cause them to collapse to a single plane). I guess one could design more robust tests for those cases, or attempt a solution for quadrics in general.

    I also didn't cover any tests for ellipsoids behind the screen plane at eye coordinate or for the case when the eye coordinate is inside the ellipsoid. Those need to be handled as well.

    Optimization
    ------------

    Once the algorithm is written down, there are a lot of opportunities to zero or fold duplicate/unused element computations, so I'm fairly certain that it can be crunched down to a small solution that is completely incomprehensible without this document. What I like about this solution is that we get a perfect analytical result without any iterations, and that should translate to potentially hundred thousands if not millions of ellipsoid brushes per frame.

    Generalization
    --------------

    This technique is also valid for orthogonal projection without any changes.

    Nothing speaks against following this approach with convex non-uniformly scaled primitives other than ellipsoids, as long as ray and plane intersection/bounding tests are available for the primitive or a slice of it. Spheres are particularly convenient because they are invariant to rotation and their slices are always circles. Cubes produce triangular, quadliteral and hexagonal slices. Tetrahedra produce triangular and quadliteral slices. Cylinders and cones produce circles and capped hyperbolic slices.

    It nevertheless helps to know that slices of a convex primitive are also always convex.

    Could this be done with signed distance estimators? Since our primitive is convex, we can use faster newton-raphson to converge a ray to the surface, in my experience that's under 7 iterations on average. But one has to come up with new plane bounding estimators that also work with 2D slices of a 3D field, which is just a big question mark to me. On the upside, this technique would also work with non-uniformly scaled distance fields.

  3. paniq revised this gist Sep 10, 2017. 1 changed file with 14 additions and 7 deletions.
    21 changes: 14 additions & 7 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -46,12 +46,12 @@ D. A circle that crosses no boundary line and is either left or right of both bo
    To resolve these predicates we need two kinds of analytical equations, which are both readily available:

    * A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width) if there is an intersection, and for any case tells us if the circle's center is left or right of the line.
    * Given a line and a circle, compute a line parallel to the original line that bounds the circle and the contact point where line and circle touch.
    * Given a line and a circle, compute two lines parallel to the original line that bound the circle and the contact points where lines and circle touch.

    With these two equations we can deduce our near and far lines (which are parallel to the screen line).

    * For case C, our near and far line are simply the ones that bounds the circle. All done.
    * For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise they intersect with near or far intersection points of circle and wall line.
    * For case C, our near and far line are simply the ones that bound the circle. All done.
    * For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise it intersects with near or far intersection points of circle and wall line.
    * Case A is analog to case B, except we now have two intersection points to consider per line if the contact point is outside the wedge. In this case we pick the nearest or farthest intersection point among each pair.
    * Also, for case A, we also need to compute the fully covered range, formed by two screen lines overlapping with the inner intersection points. Both intersections of each screen line with the wall lines must be inside the circle, or we don't have a fully covered range.

    @@ -60,15 +60,22 @@ After this, we transform the lines back to world space, and that is the 2D case
    3D Case
    -------

    Let's add one more dimension and observe. Analog to the 2D case, we can rotate and scale the ellipsoid into a unit sphere.



    Let's add one more dimension and observe. Analog to the 2D case, we can rotate and scale the ellipsoid into a unit sphere. Our wall planes, corner lines and screen plane will be transformed to ellipsoid-space, and we will simply transform our solution back later on.

    These are our possible cases in 3-space:

    A. A sphere that intersects all wall corners - contained, occluding.

    B. A sphere that intersects one or more wall planes and is inside the frustum - contained, not occluding.

    C. A sphere that intersects no wall planes and is inside the frustum - contained, not occluding.

    D. A sphere that intersects no wall planes and is outside the frustum - not contained, not occluding.

    These are the analytical equations we need to solve all predicates, and again, this is all standard stuff:

    * A sphere / plane intersection test that gives us the parameters of the resulting circle embedded in 3-space, and for any case tells us in which half-space the sphere's center is in.
    * A ray / sphere intersection test that gives us entry and exit point if there is an intersection.
    * Given a plane and a sphere, compute two planes parallel to the original plane that bound the sphere, and the two contact points where planes and sphere touch.
    * Given a plane and a circle, compute two planes parallel to the original plane that bound the circle and the contact point where plane and circle touch. Our screen planes will never be parallel to the circle's plane, so this case does not have to be tested.

  4. paniq revised this gist Sep 10, 2017. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -36,8 +36,11 @@ The first thing we can do to considerably simplify the problem is to non-uniform
    We end up with four possible arrangements of circle and wedge:

    A. A circle that crosses both boundary lines - contained, occluding.

    B. A circle that crosses only one boundary line - contained, not occluding.

    C. A circle that crosses no boundary line and is left of one line and right of the other - contained, not occluding.

    D. A circle that crosses no boundary line and is either left or right of both boundary lines - not contained, not occluding.

    To resolve these predicates we need two kinds of analytical equations, which are both readily available:
  5. paniq revised this gist Sep 10, 2017. 1 changed file with 7 additions and 9 deletions.
    16 changes: 7 additions & 9 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ Now the screen plane and the wall and corner planes are not necessarily arranged

    Let's drop from 3D space to 2D space and attempt to solve the problem there. Now our ellipsoid is just an ellipse, and our frustum is simply a wedge formed by two lines originating from an eye point (analog to our four planes or four corner lines - here they collapse to the same thing) and a screen line (analog to our screen plane) arranged semi-orthogonally to the eye point.

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge. We'll need to save our skew matrix for later so we can unskew our solution lines.
    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge, but in ellipse-space. We'll need to save our skew matrix for later so we can transform our solution lines back to world space.

    We end up with four possible arrangements of circle and wedge:

    @@ -47,19 +47,17 @@ To resolve these predicates we need two kinds of analytical equations, which are

    With these two equations we can deduce our near and far lines (which are parallel to the screen line).

    For case C, our near and far line are simply the ones that bounds the circle. All done.
    For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise they intersect with near or far intersection points of circle and wall line.
    Case A is analog to case B, except we now have two intersection points to consider per line if the contact point is outside the wedge. In this case we pick the nearest or farthest intersection point among each pair.
    Also, for case A, we also need to compute the fully covered range, formed by two screen lines overlapping with the inner intersection points. Both intersections of each screen line with the wall lines must be inside the circle, or we don't have a fully covered range.
    * For case C, our near and far line are simply the ones that bounds the circle. All done.
    * For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise they intersect with near or far intersection points of circle and wall line.
    * Case A is analog to case B, except we now have two intersection points to consider per line if the contact point is outside the wedge. In this case we pick the nearest or farthest intersection point among each pair.
    * Also, for case A, we also need to compute the fully covered range, formed by two screen lines overlapping with the inner intersection points. Both intersections of each screen line with the wall lines must be inside the circle, or we don't have a fully covered range.

    And that is the 2D case handled.
    After this, we transform the lines back to world space, and that is the 2D case handled.

    3D Case
    -------

    Let's add one more dimension and observe what changes.


    Let's add one more dimension and observe. Analog to the 2D case, we can rotate and scale the ellipsoid into a unit sphere.



  6. paniq revised this gist Sep 10, 2017. 1 changed file with 16 additions and 6 deletions.
    22 changes: 16 additions & 6 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,9 @@
    Ellipsoid Frustum Intersection
    ------------------------------
    ==============================

    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothers me for a while now, and right after I've had a few exchanges on Twitter that inspired me to attempt a solution.
    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothered me for a while now, and right after I've had a few exchanges on Twitter that inspired me to attempt a solution.

    Basically, the problem is about a form of refined raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen, _without any precalculated accelleration structure_. How does it work? Basically, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could
    The problem is about a form of refining raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen, _without any precalculated accelleration structure_. How does it work? Well, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could

    1. Start with a very low resolution
    2. Collect a list of ellipsoids contained in each tile, culling the ones not contained or fully occluded
    @@ -26,6 +26,9 @@ You see that the problem is analog to raytracing, but we are frustum tracing: in

    Now the screen plane and the wall and corner planes are not necessarily arranged symmetrically and orthogonally, but can be skewed due to the position of the screen tile we are interested in. In the beginning, this sounds like an added complication, but it will be helpful that we don't have an invariant here that we might feel must be protected (and instead get another one that we will profit from)

    2D Case
    -------

    Let's drop from 3D space to 2D space and attempt to solve the problem there. Now our ellipsoid is just an ellipse, and our frustum is simply a wedge formed by two lines originating from an eye point (analog to our four planes or four corner lines - here they collapse to the same thing) and a screen line (analog to our screen plane) arranged semi-orthogonally to the eye point.

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge. We'll need to save our skew matrix for later so we can unskew our solution lines.
    @@ -40,14 +43,21 @@ D. A circle that crosses no boundary line and is either left or right of both bo
    To resolve these predicates we need two kinds of analytical equations, which are both readily available:

    * A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width) if there is an intersection, and for any case tells us if the circle's center is left or right of the line.
    * Given a line and a circle, compute a line parallel to the original line that bounds the circle.
    * Given a line and a circle, compute a line parallel to the original line that bounds the circle and the contact point where line and circle touch.

    With these two equations we can deduce our near and far lines (which are parallel to the screen line).

    For case C, our near and far line is simply the one that bounds the circle. All done.
    For case B, the near and far line only bound the circle if the wedge contains the circle's center.
    For case C, our near and far line are simply the ones that bounds the circle. All done.
    For case B, the near or far line only bounds the circle if the contact point is inside the wedge. Otherwise they intersect with near or far intersection points of circle and wall line.
    Case A is analog to case B, except we now have two intersection points to consider per line if the contact point is outside the wedge. In this case we pick the nearest or farthest intersection point among each pair.
    Also, for case A, we also need to compute the fully covered range, formed by two screen lines overlapping with the inner intersection points. Both intersections of each screen line with the wall lines must be inside the circle, or we don't have a fully covered range.

    And that is the 2D case handled.

    3D Case
    -------

    Let's add one more dimension and observe what changes.



  7. paniq revised this gist Sep 10, 2017. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,6 @@
    Ellipsoid Frustum Intersection
    ------------------------------

    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothers me for a while now, and right after I've had a few exchanges on Twitter that inspired me to attempt a solution.

    Basically, the problem is about a form of refined raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen, _without any precalculated accelleration structure_. How does it work? Basically, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could
  8. paniq revised this gist Sep 10, 2017. 1 changed file with 10 additions and 7 deletions.
    17 changes: 10 additions & 7 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -27,19 +27,22 @@ Let's drop from 3D space to 2D space and attempt to solve the problem there. Now

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge. We'll need to save our skew matrix for later so we can unskew our solution lines.

    We end up with four possibly arrangements of circle and wedge:
    We end up with four possible arrangements of circle and wedge:

    * A circle that crosses both boundary lines - contained.
    * A circle that crosses only one boundary line - contained.
    * A circle that crosses no boundary line but is either left or right of both boundary lines - not contained.
    * A circle that crosses no boundary line but is left of one line and right of the other - contained.
    A. A circle that crosses both boundary lines - contained, occluding.
    B. A circle that crosses only one boundary line - contained, not occluding.
    C. A circle that crosses no boundary line and is left of one line and right of the other - contained, not occluding.
    D. A circle that crosses no boundary line and is either left or right of both boundary lines - not contained, not occluding.

    To resolve all these predicates we need two kinds of analytical equations, which are both readily available:
    To resolve these predicates we need two kinds of analytical equations, which are both readily available:

    * A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width) if there is an intersection, and for any case tells us if the circle's center is left or right of the line.
    * Given a line and a circle, compute a line parallel to the original line that bounds the circle.

    With these two equations
    With these two equations we can deduce our near and far lines (which are parallel to the screen line).

    For case C, our near and far line is simply the one that bounds the circle. All done.
    For case B, the near and far line only bound the circle if the wedge contains the circle's center.



  9. paniq revised this gist Sep 10, 2017. 1 changed file with 16 additions and 9 deletions.
    25 changes: 16 additions & 9 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -16,23 +16,30 @@ And this brings us to the problem: we want to solve for a tile on screen

    You see that the problem is analog to raytracing, but we are frustum tracing: instead of a ray, we extrude and expand a rectangle which forms a 4-sided open-faced pyramid in space, or simpler yet, four planes. The depth values that we are interested in are represented by planes parallel to the screen plane. These planes intersect in each corner of the rectangle to form lines. So the participants in this problem are:

    1. An ellipsoid
    2. Four wall planes of our frustum
    3. Four corner lines of our frustum
    4. A screen plane - whose positions we want to find (outer near/far, inner near/far)
    * An ellipsoid
    * Four wall planes of our frustum
    * Four corner lines of our frustum
    * A screen plane - whose positions we want to find (outer near/far, inner near/far)

    Now the screen plane and the wall and corner planes are not necessarily arranged symmetrically and orthogonally, but can be skewed due to the position of the screen tile we are interested in. In the beginning, this sounds like an added complication, but it will be helpful that we don't have an invariant here that we might feel must be protected (and instead get another one that we will profit from)

    Let's drop from 3D space to 2D space and attempt to solve the problem there. Now our ellipsoid is just an ellipse, and our frustum is simply a wedge formed by two lines originating from an eye point (analog to our four planes or four corner lines - here they collapse to the same thing) and a screen line (analog to our screen plane) arranged semi-orthogonally to the eye point.

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle. This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge. We'll need to save our skew matrix for later so we can unskew our solution lines.
    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle (analog to the 3D raytracing solution which does the same thing). This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge. We'll need to save our skew matrix for later so we can unskew our solution lines.

    Now we need two kinds of analytical equations, which are both readily available:
    We end up with four possibly arrangements of circle and wedge:

    1. A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width)
    2. Given a line and a circle, compute a line parallel to ours that bounds the circle
    * A circle that crosses both boundary lines - contained.
    * A circle that crosses only one boundary line - contained.
    * A circle that crosses no boundary line but is either left or right of both boundary lines - not contained.
    * A circle that crosses no boundary line but is left of one line and right of the other - contained.

    With these two equations
    To resolve all these predicates we need two kinds of analytical equations, which are both readily available:

    * A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width) if there is an intersection, and for any case tells us if the circle's center is left or right of the line.
    * Given a line and a circle, compute a line parallel to the original line that bounds the circle.

    With these two equations



  10. paniq revised this gist Sep 10, 2017. 1 changed file with 39 additions and 4 deletions.
    43 changes: 39 additions & 4 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -3,13 +3,48 @@ Yesterday I posted a problem to [math stack exchange](https://math.stackexchange
    Basically, the problem is about a form of refined raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen, _without any precalculated accelleration structure_. How does it work? Basically, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could

    1. Start with a very low resolution
    2. Collect a list of ellipsoids contained in each tile, culling the ones we don't need
    3. Then subdivide each tile into four smaller tiles and repeat
    2. Collect a list of ellipsoids contained in each tile, culling the ones not contained or fully occluded
    3. Then subdivide each tile into smaller tiles and repeat
    4. Until we hit per-pixel resolution, then we are done.

    And this brings us to the problem: we want to solve for a tile on screen

    1. Whether an ellipsoid arbitrarily parametrized in world space is overlapping this tile
    2. What the near and far depth range of the overlapping portion is (important for culling, but also ray-space CSG)
    2. What the near and far depth range of the overlapping portion is (important for culling)
    3. Whether the ellipsoid covers the tile fully (occludes its background completely, also important for culling)
    4. At which depth range the occlusion is 100% (so we can also cull overlapping ellipsoids)
    4. What the near and far depth range of the portion is that fully covers the tile (so we can also cull overlapping ellipsoids)

    You see that the problem is analog to raytracing, but we are frustum tracing: instead of a ray, we extrude and expand a rectangle which forms a 4-sided open-faced pyramid in space, or simpler yet, four planes. The depth values that we are interested in are represented by planes parallel to the screen plane. These planes intersect in each corner of the rectangle to form lines. So the participants in this problem are:

    1. An ellipsoid
    2. Four wall planes of our frustum
    3. Four corner lines of our frustum
    4. A screen plane - whose positions we want to find (outer near/far, inner near/far)

    Now the screen plane and the wall and corner planes are not necessarily arranged symmetrically and orthogonally, but can be skewed due to the position of the screen tile we are interested in. In the beginning, this sounds like an added complication, but it will be helpful that we don't have an invariant here that we might feel must be protected (and instead get another one that we will profit from)

    Let's drop from 3D space to 2D space and attempt to solve the problem there. Now our ellipsoid is just an ellipse, and our frustum is simply a wedge formed by two lines originating from an eye point (analog to our four planes or four corner lines - here they collapse to the same thing) and a screen line (analog to our screen plane) arranged semi-orthogonally to the eye point.

    The first thing we can do to considerably simplify the problem is to non-uniformly scale and rotate our problem space to turn the ellipsoid into a unit circle. This will skew our wedge further, but since it was already skewed to begin with, nothing really changed for us. This was the invariant I talked about earlier. Now we're solving the problem for a unit circle, and our wedge still is a wedge. We'll need to save our skew matrix for later so we can unskew our solution lines.

    Now we need two kinds of analytical equations, which are both readily available:

    1. A line / circe intersection test that gives us an entry and exit point (usually parametrized as center and width)
    2. Given a line and a circle, compute a line parallel to ours that bounds the circle

    With these two equations















  11. paniq revised this gist Sep 10, 2017. 1 changed file with 11 additions and 2 deletions.
    13 changes: 11 additions & 2 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,15 @@
    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothers me for a while now, and right after I've had a few exchanges on Twitter that inspired me to attempt a solution.

    The basic challenge is this: we want to solve for a pixel or tile on screen
    Basically, the problem is about a form of refined raytracing where we render a big list of convex 3D brushes (and I decided to start with Ellipsoids, since they're so useful) to the screen, _without any precalculated accelleration structure_. How does it work? Basically, if we had a way to figure out for a portion of the frustum whether it contained a brush, we could

    1. Whether an ellipsoid arbitrarily parametrized in world space is overlapping this pixel
    1. Start with a very low resolution
    2. Collect a list of ellipsoids contained in each tile, culling the ones we don't need
    3. Then subdivide each tile into four smaller tiles and repeat
    4. Until we hit per-pixel resolution, then we are done.

    And this brings us to the problem: we want to solve for a tile on screen

    1. Whether an ellipsoid arbitrarily parametrized in world space is overlapping this tile
    2. What the near and far depth range of the overlapping portion is (important for culling, but also ray-space CSG)
    3. Whether the ellipsoid covers the tile fully (occludes its background completely, also important for culling)
    4. At which depth range the occlusion is 100% (so we can also cull overlapping ellipsoids)
  12. paniq created this gist Sep 10, 2017.
    6 changes: 6 additions & 0 deletions ellipsoid_frustum.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    Yesterday I posted a problem to [math stack exchange](https://math.stackexchange.com/questions/2422620/bounding-plane-and-projective-occlusion-of-cone-and-ellipsoid-intersection) that bothers me for a while now, and right after I've had a few exchanges on Twitter that inspired me to attempt a solution.

    The basic challenge is this: we want to solve for a pixel or tile on screen

    1. Whether an ellipsoid arbitrarily parametrized in world space is overlapping this pixel
    2. What the near and far depth range of the overlapping portion is (important for culling, but also ray-space CSG)