CPU raycasting
Open the live demo · Read the source · View on GitHub
Picking by pixel asks the renderer to draw a whole extra frame. Sometimes
that is too slow, or there is no renderer at all: an editor tool measuring a
model, or a game asking "is anything between me and that wall" many times a
step. Raycaster answers that on the CPU, against the geometry directly,
with no frame involved.
Step 1: One raycaster, reused #
A Raycaster holds its own ray and its own scratch state, and is meant to be
kept around and reused rather than built fresh for every question.
final Raycaster _raycaster = Raycaster();
Step 2: Aim it and ask #
setFromNdc points the ray through a spot in normalized device coordinates,
-1 to 1 on each axis with the camera at the centre. intersectScene
walks the scene's meshes and returns the nearest one the ray meets, or null.
void _castAtCentre() {
_raycaster.setFromNdc(_camera, 0.0, 0.0, aspect: 16 / 9);
lastHit = _raycaster.intersectScene(_scene);
}
Note. A skinned mesh is tested where its skeleton actually puts it, not in its rest pose, because
Raycaster.poseddefaults to true. A shot at a running figure hits the raised arm where the arm now is.
Step 3: Read the answer #
The ray in this page always points at the middle of the screen, where the
ball sits, so intersectScene finds it every frame. Move the ball off the
camera's axis and the same ray would return null instead.
void _castAtCentre() {
_raycaster.setFromNdc(_camera, 0.0, 0.0, aspect: 16 / 9);
lastHit = _raycaster.intersectScene(_scene);
}