Shadows, self and nearby craft
This commit is contained in:
1 parent
e77d68d0a6
commit
33f986044c
14 files changed
+1273
-37
No files matched your search
+83
-2
@@ -369,7 +369,8 @@ 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.
|
||||
only approximate those, for example with the shadow maps lighting L1 uses
|
||||
(below).
|
||||
|
||||
### One sample per pixel
|
||||
|
||||
@@ -580,6 +581,87 @@ 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.
|
||||
|
||||
### Shadows on the target
|
||||
|
||||
Code: `shadow.rs`, `gpu/shadow.rs`, `shaders/mesh.wgsl`. From lighting L1.
|
||||
|
||||
A solar array shades the bus behind it, an antenna dish shades its feed,
|
||||
and a second spacecraft close by can shade the first. Rasterization draws
|
||||
each triangle on its own, so by itself it cannot know that something else
|
||||
stands between a point and the Sun. The renderer finds out with a shadow
|
||||
map.
|
||||
|
||||
- **Shadow map.** Before the camera's view is drawn, the target is drawn
|
||||
once more as the Sun sees it, looking straight down the Sun's rays. That
|
||||
drawing keeps only depth: for each texel (a pixel of the map), how far
|
||||
along the Sun's direction the first surface is. The Sun is far enough
|
||||
away that its rays are parallel across a spacecraft, so the view has no
|
||||
perspective, and a map 4096 texels across covers the target's bounding
|
||||
sphere. For Landsat 8, whose sphere is 16.6 m across, one texel is 4 mm.
|
||||
- **Lookup.** When the camera's view shades a point, it finds that point
|
||||
in the map. If the map holds a surface nearer the Sun than the point, the
|
||||
point is in shadow.
|
||||
|
||||
Each target gets its own map. Another target is drawn into that map when it
|
||||
is sunward of this one and close enough across the Sun's rays to shade it.
|
||||
A target off to the side is left out, since it cannot cast a shadow here.
|
||||
|
||||
The Sun is a disk half a degree across, so a shadow edge is not sharp. A
|
||||
point near the edge sees part of the disk past the blocker, the same
|
||||
penumbra as in an eclipse. The width of the penumbra is the distance from
|
||||
blocker to surface times the tangent of the Sun's angular diameter, 0.93 %
|
||||
at 1 AU. A solar array 2 m above the bus casts an edge 19 mm wide. One 10 m
|
||||
away casts an edge 9 cm wide. The renderer reproduces this with
|
||||
percentage-closer soft shadows:
|
||||
|
||||
1. Search the map around the point for blockers, and average their depth.
|
||||
That gives the blocker-to-surface distance, and from it the penumbra
|
||||
width.
|
||||
2. Compare the point's depth against a 6 x 6 grid of map texels spread over
|
||||
that width, and take the fraction that are not blocked as the share of
|
||||
the Sun the point sees.
|
||||
|
||||
Both steps use fixed grids rather than random samples, so the image has no
|
||||
noise and the same scene always gives the same pixels.
|
||||
|
||||
A surface can wrongly shadow itself, because the map only stores its depth
|
||||
once per texel. Where the surface is tilted to the Sun, depth changes
|
||||
across a texel, and half of each texel looks like it is behind itself. The
|
||||
result is a pattern of dark stripes called shadow acne. The renderer
|
||||
prevents it three ways. The stored depth is pushed away from the Sun in
|
||||
proportion to the surface's tilt. The lookup is made from a point 1.5
|
||||
texels off the surface, toward the Sun. And a blocker has to be more than 2
|
||||
texels nearer the Sun to count.
|
||||
|
||||
Tests (`tests/shadows.rs`) check, on the GPU and lavapipe:
|
||||
|
||||
- A plate under a 2 m square: the shadow reads zero direct light, and its
|
||||
edge falls where the square's edge projects, to within one texel.
|
||||
- The measured penumbra width is within 2.2 % of 0.93 % of the occluder's
|
||||
height, at heights of 1, 2 and 3 m.
|
||||
- No pixel darkens compared with L0 on a plate tilted 80 and 87 degrees
|
||||
from the Sun, or on a faceted sphere.
|
||||
- A target sunward of another shades it; one to the side does not.
|
||||
|
||||
On the RTX 3060, shadows cost 0.14 ms of GPU time per frame for Landsat 8
|
||||
(85,000 triangles) and 0.34 ms for ICESat-2 (752,000), plus about 0.15 ms
|
||||
in the camera view's lookups. Maps 2048 texels across save about 0.15 ms.
|
||||
|
||||
Limitations:
|
||||
|
||||
- **Penumbra shape.** The grid averages a square of the map, so brightness
|
||||
rises in a straight line across the penumbra. A real disk-shaped Sun
|
||||
rises along an S-shaped curve: the full width is the same, but the middle
|
||||
80 % of the change is 0.69 of the width rather than 0.8.
|
||||
- **Resolution.** A detail smaller than a texel casts no reliable shadow. A
|
||||
gap narrower than about 2 texels between a blocker and the surface it
|
||||
shades (a few mm on Landsat 8) lets light through, because of the acne
|
||||
margins above.
|
||||
- **One sample per pixel.** Shadows are sampled at the pixel center, like
|
||||
everything else, until M2's pixel-area sampling.
|
||||
- **Bodies.** Earth and the Moon do not use shadow maps. Their shadows on
|
||||
the target are the eclipse factor below, applied to the whole target.
|
||||
|
||||
### Eclipses
|
||||
|
||||
Code: `eclipse.rs`.
|
||||
@@ -641,7 +723,6 @@ velocity as an input, which the scene does not carry yet.
|
||||
| Light from Earth and the Moon illuminating the target (Earthshine, Moonshine) | M2 |
|
||||
| Earth's shadow on the Moon (lunar eclipses) | M2 |
|
||||
| Earthshine on the Moon's night side | M4 |
|
||||
| Shadows the target casts on itself | M2 |
|
||||
| The Sun as a disk that is darker toward its edge (limb darkening) | M2 |
|
||||
| Pixel-area sampling (anti-aliasing): graded edges, thin parts | M2 |
|
||||
| Lens distortion | M3 |
|
||||
|
||||
Reference in new issue
Block a user