EEVEE: Add Support for Panoramic Camera View

# Implemented

- Panoramic camera types: equirectangular,
equiangular cubemap face, fisheye equidistant,
fisheye equisolid, fisheye lens polynomial,
central cylindrical, mirror ball.
- Render 6 subviews (fixed 90° FOV each, 5% overscan).
- Subview enable/disable masking (PanoramicViewBits)
to skip faces not needed for narrow FOV.
- Accumulate radial depth for panoramic projections.
- Film accumulation per owning face per pixel.

# Future tasks

### Turned off for now

- Depth of Field
- Volume temporal reprojection history state is shared
across all 6 subviews instead of per-view, so it's disabled
for now. Per-view history would be the real fix.

### Optimizations

- Per-face render resolution: scale each cubeface's resolution
to its actual angle contribution instead of a fixed size.
- Clip each subview's projection matrix to its actual visible FOV
instead of always rendering the full 90°. Needs care to clip to
exact pixel borders, or reprojection onto the film breaks.
- Stencil mask per subview to avoid computing weights.
(currently: pixels not owned by a face just copy their existing
value and return early).

### Known limitations

- Film sampling use nearest-texel only, not a proper filter kernel
(a 3x3 or plus-shaped 5-sample kernel would reduce
 aliasing/banding)
- No antialiasing at boundaries.
- Screen-space raytracing hits subview boundaries and
creates artifacts. Possible fix: overscan parameter and make a
blend between the cubefaces.

Pull Request: https://projects.blender.org/blender/blender/pulls/159474
This commit is contained in:
Le Gia Bao 2026-09-03 14:47:04 +02:00 • committed by Clément Foucault
parent c85babd2e5
commit fb61ad85d0
43 changed files with 1005 additions and 228 deletions

View file

@ -67,6 +67,8 @@ BLOCKLIST = [
"light_path_is_camera_ray.blend",
# Exhibit non-deterministic (to be fixed).
"background_scene.blend",
# EEVEE doesnt have adaptive dicing.
"panorama_dicing.blend",
# Currently, the only image_mipmap test enabled for EEVEE is image_mipmap_large_tex.blend.
"image_cache_evict.blend",
"image_mipmap_area_light.blend",
@ -403,7 +405,8 @@ def main():
report.set_fail_threshold(6.0 / 255.0)
elif test_dir_name.startswith('camera'):
# camera_stereo_panoramic have some platform specific small differences
report.set_fail_percent(0.14)
# Fix back to 0.14 once eevee panorama has proper filtering.
report.set_fail_percent(1.5)
report.set_fail_threshold(6.0 / 255.0)
elif test_dir_name.startswith('image_colorspace'):
# image_log has hot pixels that result in platform differences.