bevy/examples/3d
m-edlund c323db02e0
Add sub_camera_view, enabling sheared projection (#15537)
# Objective

- This PR fixes #12488

## Solution

- This PR adds a new property to `Camera` that emulates the
functionality of the
[setViewOffset()](https://threejs.org/docs/#api/en/cameras/PerspectiveCamera.setViewOffset)
API in three.js.
- When set, the perspective and orthographic projections will restrict
the visible area of the camera to a part of the view frustum defined by
`offset` and `size`.

## Testing

- In the new `camera_sub_view` example, a fixed, moving and control sub
view is created for both perspective and orthographic projection
- Run the example with `cargo run --example camera_sub_view`
- The code can be tested by adding a `SubCameraView` to a camera

---

## Showcase


![image](https://github.com/user-attachments/assets/75ac45fc-d75d-4664-8ef6-ff7865297c25)

- Left Half: Perspective Projection
- Right Half: Orthographic Projection
- Small boxes in order:
  - Sub view of the left half of the full image
- Sub view moving from the top left to the bottom right of the full
image
  - Sub view of the full image (acting as a control)
- Large box: No sub view

<details>
  <summary>Shortened camera setup of `camera_sub_view` example</summary>

```rust
    // Main perspective Camera
    commands.spawn(Camera3dBundle {
        transform,
        ..default()
    });

    // Perspective camera left half
    commands.spawn(Camera3dBundle {
        camera: Camera {
            sub_camera_view: Some(SubCameraView {
                // Set the sub view camera to the left half of the full image
                full_size: uvec2(500, 500),
                offset: ivec2(0, 0),
                size: uvec2(250, 500),
            }),
            order: 1,
            ..default()
        },
        transform,
        ..default()
    });

    // Perspective camera moving
    commands.spawn((
        Camera3dBundle {
            camera: Camera {
                sub_camera_view: Some(SubCameraView {
                    // Set the sub view camera to a fifth of the full view and
                    // move it in another system
                    full_size: uvec2(500, 500),
                    offset: ivec2(0, 0),
                    size: uvec2(100, 100),
                }),
                order: 2,
                ..default()
            },
            transform,
            ..default()
        },
        MovingCameraMarker,
    ));

    // Perspective camera control
    commands.spawn(Camera3dBundle {
        camera: Camera {
            sub_camera_view: Some(SubCameraView {
                // Set the sub view to the full image, to ensure that it matches
                // the projection without sub view
                full_size: uvec2(450, 450),
                offset: ivec2(0, 0),
                size: uvec2(450, 450),
            }),
            order: 3,
            ..default()
        },
        transform,
        ..default()
    });

    // Main orthographic camera
    commands.spawn(Camera3dBundle {
        projection: OrthographicProjection {
          ...
        }
        .into(),
        camera: Camera {
            order: 4,
            ..default()
        },
        transform,
        ..default()
    });

    // Orthographic camera left half
    commands.spawn(Camera3dBundle {
        projection: OrthographicProjection {
          ...
        }
        .into(),
        camera: Camera {
            sub_camera_view: Some(SubCameraView {
                // Set the sub view camera to the left half of the full image
                full_size: uvec2(500, 500),
                offset: ivec2(0, 0),
                size: uvec2(250, 500),
            }),
            order: 5,
            ..default()
        },
        transform,
        ..default()
    });

    // Orthographic camera moving
    commands.spawn((
        Camera3dBundle {
            projection: OrthographicProjection {
              ...
            }
            .into(),
            camera: Camera {
                sub_camera_view: Some(SubCameraView {
                    // Set the sub view camera to a fifth of the full view and
                    // move it in another system
                    full_size: uvec2(500, 500),
                    offset: ivec2(0, 0),
                    size: uvec2(100, 100),
                }),
                order: 6,
                ..default()
            },
            transform,
            ..default()
        },
        MovingCameraMarker,
    ));

    // Orthographic camera control
    commands.spawn(Camera3dBundle {
        projection: OrthographicProjection {
          ...
        }
        .into(),
        camera: Camera {
            sub_camera_view: Some(SubCameraView {
                // Set the sub view to the full image, to ensure that it matches
                // the projection without sub view
                full_size: uvec2(450, 450),
                offset: ivec2(0, 0),
                size: uvec2(450, 450),
            }),
            order: 7,
            ..default()
        },
        transform,
        ..default()
    });
```

</details>
2024-10-01 14:11:24 +00:00
..
3d_scene.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
3d_shapes.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
3d_viewport_to_world.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
animated_material.rs Add support for environment map transformation (#14290) 2024-07-19 15:00:50 +00:00
anisotropy.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
anti_aliasing.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
atmospheric_fog.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
auto_exposure.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
blend_modes.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
bloom_3d.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
camera_sub_view.rs Add sub_camera_view, enabling sheared projection (#15537) 2024-10-01 14:11:24 +00:00
clearcoat.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
color_grading.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
deferred_rendering.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
depth_of_field.rs Rename rendering components for improved consistency and clarity (#15035) 2024-09-10 01:11:46 +00:00
fog_volumes.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
fog.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
generate_custom_mesh.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
irradiance_volumes.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
lighting.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
lightmaps.rs Simpler lint fixes: makes ci lints work but disables a lint for now (#15376) 2024-09-24 11:42:59 +00:00
lines.rs Highlight dependency on shader files in examples (#13824) 2024-06-12 14:16:01 +00:00
load_gltf_extras.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
load_gltf.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
meshlet.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
motion_blur.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
orthographic.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
parallax_mapping.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
parenting.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
pbr.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
pcss.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
post_processing.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
query_gltf_primitives.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
reflection_probes.rs Simpler lint fixes: makes ci lints work but disables a lint for now (#15376) 2024-09-24 11:42:59 +00:00
render_to_texture.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
rotate_environment_map.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
scrolling_fog.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
shadow_biases.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
shadow_caster_receiver.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
skybox.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
spherical_area_lights.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
split_screen.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
spotlight.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
ssao.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
ssr.rs Rename rendering components for improved consistency and clarity (#15035) 2024-09-10 01:11:46 +00:00
texture.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
tonemapping.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
transmission.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
transparency_3d.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
two_passes.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
update_gltf_scene.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
vertex_colors.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
visibility_range.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
volumetric_fog.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00
wireframe.rs Migrate lights to required components (#15554) 2024-10-01 03:20:43 +00:00