in packages/miew/src/gfx/shaders/Uber.frag [190:237]
bool intersect_ray_cylinder(in vec3 origin, in vec3 ray, out vec3 point, out float frontFaced) {
// intersect XZ-projected ray with circle
float a = dot(ray.xz, ray.xz);
float b = dot(ray.xz, origin.xz);
float c = dot(origin.xz, origin.xz) - 1.0;
float det = b * b - a * c;
if (det < 0.0) return false;
float t1 = (-b - sqrt(det)) / a;
float t2 = (-b + sqrt(det)) / a;
// calculate both intersection points
vec3 p1 = origin + ray * t1;
vec3 p2 = origin + ray * t2;
float halfHeight = 0.5;
// choose nearest point
#ifdef ORTHOGRAPHIC_CAMERA
// orthografic camera is used for dirLight sources. So in it for all cylinders the point with smaller 't' is visible
// if it is not outside of cylinnder (t1 is always smaller than t2).
if (p1.y >= -halfHeight && p1.y <= halfHeight) {
point = p1;
frontFaced = 1.0;
return true;
}
if (p2.y >= -halfHeight && p2.y <= halfHeight) {
point = p2;
frontFaced = -1.0;
return true;
}
#else
// for perspective camera first intersection can be in front of near plane. If not intersection is p1 else - p2
// t* = 0.0 corresponds to point of intersection near plane by the ray from camera to curPixel
if (t1 >= 0.0 && p1.y >= -halfHeight && p1.y <= halfHeight) {
point = p1;
frontFaced = 1.0;
return true;
}
if (t2 >= 0.0 && p2.y >= -halfHeight && p2.y <= halfHeight) {
point = p2;
frontFaced = -1.0;
return true;
}
#endif
return false;
}