Added target meshes and eclipse

This commit is contained in:
connor committed 2026-10-14 16:54:11 -04:00
1 parent fd55b369a5
commit da1d41d7f3
12 files changed
+993 -14

No files matched your search

+78 -3
View File
@@ -313,13 +313,45 @@ Picking the exposure time is the same trade a photographer makes. A longer
exposure saturates the sunlit target. A shorter one leaves the side of the
target lit only by Earthshine lost in noise once noise is modeled (M3).
## How shapes become pixels
Two techniques turn 3D shapes into an image. The renderer uses one for the
bodies and the other for the target.
- **Mesh.** A surface approximated by many small flat triangles that share
corners (vertices). A cube needs 12 triangles. A curved surface needs
many more, and it is still faceted up close. Each vertex stores a position
and usually a normal, the direction the surface faces there. STL and glTF
files are meshes, and so is the target spacecraft.
- **Rasterization.** The GPU's built-in way of drawing a mesh. Each
triangle's corners are projected into the image with the pinhole
equations above. The GPU then finds every pixel whose center falls inside
the projected triangle, and runs a small program (a fragment shader) for
each of those pixels to compute its value. It is fast because it only
touches the pixels each triangle covers, and GPUs have dedicated hardware
for it. It can only draw triangles.
- **Ray casting.** The reverse direction: for each pixel, follow the line
of sight from the camera through the pixel center and solve for where it
first meets a surface. For a sphere or an ellipsoid that is a quadratic
equation with an exact answer, so there are no triangles and no facets.
Every pixel does the work, whether or not it ends up seeing the body.
The bodies use ray casting, because their shapes have exact equations and
their edges are what limb-based navigation measures. The target uses
rasterization, because a spacecraft model has no equation, only its mesh.
Both write into the same depth image, so they sort against each other
correctly. Ray casting a mesh is also possible, by testing rays against
its triangles. That is what M5's ray tracer does, because following rays
gives exact shadows and light bouncing between surfaces. Rasterization can
only approximate those, for example with the shadow maps planned for M2.
## Earth, Moon and Sun
Code: `bodies.rs`, `gpu/bodies.rs`, `shaders/bodies.wgsl`.
The three bodies are not drawn as triangle meshes. For every pixel, the
shader sends a ray from the camera through the pixel's center and solves
for where it meets each body's exact shape. The nearest hit wins. This
The three bodies are not drawn as triangle meshes; they are ray cast. For
every pixel, the shader sends a ray from the camera through the pixel's
center and solves for where it meets each body's exact shape. The nearest hit wins. This
gives an exact edge at any zoom, at the cost of a few arithmetic operations
per pixel. A mesh would show its facets along the limb, the edge of the
disk, which is the feature horizon-based navigation measures.
@@ -398,6 +430,49 @@ measured reflectance spectra (M4 adds those, and BRDFs).
STL has no units. CAD tools usually export millimeters, so loading a CAD
model usually needs `scale: 0.001`. glTF is always meters.
## Drawing the target
Code: `gpu/mesh.rs`, `shaders/mesh.wgsl`.
The target's mesh is rasterized after the bodies, into the same radiance
and depth images. Each pixel the target covers is kept only if the target
is nearer than what is already there. That one rule handles a target in
front of Earth, a target behind Earth's limb, and parts of the target
hiding other parts.
Each point on the target is shaded like the bodies: albedo times cos(i)
times the sunlight that reaches it. A panel modeled with no thickness, such
as a solar array, has one surface but two sides. Whichever side faces the
camera is the side that is lit. A closed shape never shows its inside, so
this only matters for thin parts.
### Eclipses
Code: `eclipse.rs`.
The Sun is a disk, not a point. So as a spacecraft passes into Earth's
shadow, the light fades over a few seconds instead of switching off:
- **Umbra.** Earth covers the whole solar disk. No direct sunlight.
- **Penumbra.** Earth covers part of the disk. 7000 km from Earth's
center, on the night side, the penumbra is about 65 km wide; a satellite
crosses it in under 10 seconds.
- **Annular.** A body small enough to sit inside the solar disk blocks a
ring-shaped bite. From orbit this happens with the Moon.
The renderer finds the visible fraction of the solar disk from the overlap
of two circles on the sky. The circles are the Sun's disk and the
occulter's, each with its apparent angular radius. It multiplies the
target's sunlight by that fraction. The model is the standard one for
satellites (Montenbruck and Gill), the same as astrokit's. A test checks it
against tracing lines from the target to thousands of points spread over
the solar disk.
The fraction is computed once per target, at its center. The whole target
dims together, which is accurate unless the target is a sizable fraction of
the penumbra's width. Light reaching the target from Earth itself
(Earthshine), which matters most when the target is in shadow, comes in M2.
## Not modeled yet
| Effect | Where |