Last active
October 28, 2024 11:04
-
-
Save hasenbanck/d2304aa683aff82b11c88b78cc9183b7 to your computer and use it in GitHub Desktop.
very fast cone / sphere intersection test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// While implementing a tile based light culling shader, I stumbled uppon the bachelor thesis from Jonathan W. Hale: | |
/// "Dual-Cone View Culling for Virtual Reality Applications" (2018). While lookin at his final version, I | |
/// realized that his code could be even further simplified, if the cone's tip is the origin of the coordinate system. | |
/// By creating a "world to cone view space" transformation matrix, that aligns the code to the positive +Z axis and | |
/// also set's the cone's tip as the origin, this matrix can then be used to transform the world coordinates into the | |
/// "cone view space". The following code uses a left handed coordinate system. | |
/// The test itself only uses 10 instructions: | |
/// | |
/// - 2 scalar multiplications | |
/// - 2 additions | |
/// - 2 comparisons | |
/// - 1 negation | |
/// - 1 square root | |
/// - 1 logical AND | |
/// - 1 MAX operation | |
/// Tests if a sphere intersects with a cone that is aligned to the +Z axis with its tip at the origin. | |
/// The spheres we test must be inside the cone's view space. This is an optimized version that takes | |
/// advantage of the special case where the cone is Z-aligned. | |
/// | |
/// # How it works | |
/// | |
/// The test is split into two parts: | |
/// | |
/// 1. `extends_past_cone_tip`: Checks if any part of the sphere extends past z=0 (the cone's tip) | |
/// - A sphere extends past z=0 if its closest point to the XY plane is at or behind z=0 | |
/// - This occurs when: sphere_center.z > -sphere_radius | |
/// | |
/// 2. `intersects_cone`: Tests if the sphere intersects the cone's surface at the sphere's Z position | |
/// - At any Z position, the cone forms a circular cross-section | |
/// - The radius of this cross-section is: max(cone_angle_tan * sphere_center.z, 0.0) | |
/// - length(sphere_center.xy) gives the distance from sphere center to cone's axis | |
/// - For intersection, this distance must be <= cone_radius + sphere_radius | |
/// | |
/// Based on an original idea from Jonathan W. Hale's bachelor thesis | |
/// "Dual-Cone View Culling for Virtual Reality Applications" (2018). | |
fn intersect_cone_sphere_aligned( | |
sphere_center: vec3<f32>, | |
sphere_radius: f32, | |
cone_angle_tan: f32 | |
) -> bool { | |
let cone_radius = max(cone_angle_tan * sphere_center.z, 0.0); | |
let extends_past_cone_tip = sphere_center.z > -sphere_radius; | |
let intersects_cone = length(sphere_center.xy) <= cone_radius + sphere_radius; | |
return extends_past_cone_tip && intersects_cone; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment