starplast.lighting
Soft interactive lighting and ray-marched shadows for a point cloud.
What this is, and what it is not
soft uses broad diffuse/specular illumination while ray traced additionally marches one
shadow ray from every gene to the active light through the point-density volume. This is real
volumetric shadow-ray tracing: occluding clusters attenuate the ray. It is deliberately not called
hardware path tracing--there are no triangle surfaces, reflections or Vulkan renderer here.
The controls describe independent questions: which interaction places the light, which color mood it has, how points themselves are drawn, and whether shadow rays are traced. The point modes are few because a rendering choice that cannot be distinguished on the fixed comparison scene is not a choice worth presenting.
Translate old saved finish names and refuse unknown render modes safely.
Translate the old mouse label and discard removed orbit/corner sources.
The RGB illumination for a named mood, with neutral as the safe fallback.
Where each light is at time t, and what colour it is.
Lissajous paths with incommensurable frequencies, so the lights never fall into a repeating formation -- three lights orbiting in step read as one light, and the point of several is that the shading changes as they pass each other. Position is a function of the clock for the same reason the blobs are: any frame can be drawn at any time, and a dropped frame costs nothing.
The curve gives the DIRECTION and the radius is fixed, which it was not at first. Taken as a position, a Lissajous figure ranges over the whole cube it is inscribed in: measured, the lights swung between 0.2 and 1.7 times the intended radius and spent about 4% of frames inside the cloud itself. That reads as the map pulsing -- overall brightness pumping up and down, and every so often a light surfacing among the genes to blow out its neighbours and leave the rest dark. Which is what "the orbit looks strange" was describing. On a shell, only the direction changes.
One light, far away in a given direction -- the corner presets and the pointer both use this.
Far away rather than at the point: a light placed among the genes lights the near side of a few and leaves the rest black, which reads as data missing rather than as a light.
Lights drifting through the interior of the cloud, lighting whatever they pass.
Positioned against the cloud's own extent rather than a fixed radius, so the light stays among the genes at any zoom and in any embedding -- a map twice the size gets a light that wanders twice as far rather than one that leaves through the side.
Lights bouncing off the walls of the map's own bounding box.
Each axis runs at its own rate, and the rates share no common multiple, so the ball crosses the volume on a path that does not close -- one that repeated would sweep the same corridor forever and leave most of the map permanently dark.
Bouncing off the GENES themselves is not what this does, and the difference is worth stating:
an elastic collision with a cluster needs the path integrated forward from a start, which is the
state this deliberately avoids. What reads as a bounce off the data is the density shadowing
already in rays -- the ball dims as it passes behind a cluster and brightens as it clears it.
A light sitting on each of the given genes.
Used for "light the gene I clicked" and "light it and everything it is connected to", where the light IS the answer to a question about those genes -- so it goes where they are rather than outside the cloud, and its falloff does the rest.
Point colours under a set of lights. Returns RGBA in the shape it was given.
The normal is the outward direction from the centre of the cloud, because a point has no surface of its own. Distance falloff is gentle -- inverse linear rather than inverse square -- since the map is not a physical scene and a physically correct falloff makes everything past the first light black.
A light placed relative to the CAMERA rather than to the data.
where is (x, y, z) in the screen's own frame: x right, y up, z toward the viewer. basis is
(eye, right, up, forward) from the renderer. This is what makes "top left" mean the top left of
the picture and keep meaning it while the map is orbited -- placed in world coordinates instead,
a corner light drifts to the other side of the cloud as soon as anything moves, which looks like
a light that does not work rather than one that is somewhere else.
A light hanging just in front of a given gene, between it and the viewer.
This is what "point at it and it lights up" has to mean once the map has depth. A light placed outside the cloud on the viewer's side can only ever light the near face -- it is behind everything else -- so pointing into a cluster deep in the map lit the front of the map instead, which is what was reported. Anchored on the gene under the pointer, the light is IN the cloud at that depth and its falloff does the rest: the genes around it are lit whether they are at the front or the back.
Held off the gene rather than sitting on it, because a light exactly on a point makes that point a white dot and its neighbours a hard black shell. The stand-off is a fraction of the map's own radius, so the pool of light stays the same size relative to the data at any zoom.
A camera-origin spotlight following continuous screen coordinates.
No gene is queried here. The cursor defines one ray through the camera frustum, so crossing two overlapping points at different depths does not change either the origin or direction. The light target is the intersection with the plane through the cloud center, used only for drawing an optional marker.
The lights for one frame, for whichever source was chosen.
The screen-relative sources need basis -- the camera's own axes -- because "top left" and
"where the pointer is" are statements about the picture, not about the data. anchor is the
anchor remains accepted for saved callers but is deliberately ignored: mouse illumination
is a continuous camera ray, never the identity or depth of the nearest gene.