Added target meshes and eclipse
This commit is contained in:
1 parent
fd55b369a5
commit
da1d41d7f3
12 files changed
+993
-14
No files matched your search
+78
-3
@@ -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 |
|
||||
|
||||
Reference in new issue
Block a user