Commit graph

438 commits

Author SHA1 Message Date
TotalKrill
5986d5d309
Cosmic text (#10193)
# Replace ab_glyph with the more capable cosmic-text

Fixes #7616.

Cosmic-text is a more mature text-rendering library that handles scripts
and ligatures better than ab_glyph, it can also handle system fonts
which can be implemented in bevy in the future

Rebase of https://github.com/bevyengine/bevy/pull/8808

## Changelog

Replaces text renderer ab_glyph with cosmic-text

The definition of the font size has changed with the migration to cosmic
text. The behavior is now consistent with other platforms (e.g. the
web), where the font size in pixels measures the height of the font (the
distance between the top of the highest ascender and the bottom of the
lowest descender). Font sizes in your app need to be rescaled to
approximately 1.2x smaller; for example, if you were using a font size
of 60.0, you should now use a font size of 50.0.

## Migration guide

- `Text2dBounds` has been replaced with `TextBounds`, and it now accepts
`Option`s to the bounds, instead of using `f32::INFINITY` to inidicate
lack of bounds
- Textsizes should be changed, dividing the current size with 1.2 will
result in the same size as before.
- `TextSettings` struct is removed
- Feature `subpixel_alignment` has been removed since cosmic-text
already does this automatically
- TextBundles and things rendering texts requires the `CosmicBuffer`
Component on them as well

## Suggested followups:

- TextPipeline: reconstruct byte indices for keeping track of eventual
cursors in text input
- TextPipeline: (future work) split text entities into section entities
- TextPipeline: (future work) text editing
- Support line height as an option. Unitless `1.2` is the default used
in browsers (1.2x font size).
- Support System Fonts and font families
- Example showing of animated text styles. Eg. throbbing hyperlinks

---------

Co-authored-by: tigregalis <anak.harimau@gmail.com>
Co-authored-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: sam edelsten <samedelsten1@gmail.com>
Co-authored-by: Dimchikkk <velo.app1@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-07-04 20:41:08 +00:00
Lura
856b39d821
Apply Clippy lints regarding lazy evaluation and closures (#14015)
# Objective

- Lazily evaluate
[default](https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_or_default)~~/[or](https://rust-lang.github.io/rust-clippy/master/index.html#/or_fun_call)~~
values where it makes sense
  - ~~`unwrap_or(foo())` -> `unwrap_or_else(|| foo())`~~
  - `unwrap_or(Default::default())` -> `unwrap_or_default()`
  - etc.
- Avoid creating [redundant
closures](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure),
even for [method
calls](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure_for_method_calls)
  - `map(|something| something.into())` -> `map(Into:into)`

## Solution

- Apply Clippy lints:
-
~~[or_fun_call](https://rust-lang.github.io/rust-clippy/master/index.html#/or_fun_call)~~
-
[unwrap_or_default](https://rust-lang.github.io/rust-clippy/master/index.html#/unwrap_or_default)
-
[redundant_closure_for_method_calls](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure_for_method_calls)
([redundant
closures](https://rust-lang.github.io/rust-clippy/master/index.html#/redundant_closure)
is already enabled)

## Testing

- Tested on Windows 11 (`stable-x86_64-pc-windows-gnu`, 1.79.0)
- Bevy compiles without errors or warnings and examples seem to work as
intended
  - `cargo clippy` 
  - `cargo run -p ci -- compile` 

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-07-01 15:54:40 +00:00
François Mockers
ee63cf45c6
fix examples color_grading and mobile after BackgroundColor changes (#14033)
# Objective

- #14017 changed how `UiImage` and `BackgroundColor` work
- one change was missed in example `color_grading`, another in the
mobile example

## Solution

- Change it in the examples
2024-06-26 12:54:23 +00:00
Alice Cecile
336fddb101
Make default behavior for BackgroundColor and BorderColor more intuitive (#14017)
# Objective

In Bevy 0.13, `BackgroundColor` simply tinted the image of any
`UiImage`. This was confusing: in every other case (e.g. Text), this
added a solid square behind the element. #11165 changed this, but
removed `BackgroundColor` from `ImageBundle` to avoid confusion, since
the semantic meaning had changed.

However, this resulted in a serious UX downgrade / inconsistency, as
this behavior was no longer part of the bundle (unlike for `TextBundle`
or `NodeBundle`), leaving users with a relatively frustrating upgrade
path.

Additionally, adding both `BackgroundColor` and `UiImage` resulted in a
bizarre effect, where the background color was seemingly ignored as it
was covered by a solid white placeholder image.

Fixes #13969.

## Solution

Per @viridia's design:

> - if you don't specify a background color, it's transparent.
> - if you don't specify an image color, it's white (because it's a
multiplier).
> - if you don't specify an image, no image is drawn.
> - if you specify both a background color and an image color, they are
independent.
> - the background color is drawn behind the image (in whatever pixels
are transparent)

As laid out by @benfrankel, this involves:

1. Changing the default `UiImage` to use a transparent texture but a
pure white tint.
2. Adding `UiImage::solid_color` to quickly set placeholder images.
3. Changing the default `BorderColor` and `BackgroundColor` to
transparent.
4. Removing the default overrides for these values in the other assorted
UI bundles.
5. Adding `BackgroundColor` back to `ImageBundle` and `ButtonBundle`.
6. Adding a 1x1 `Image::transparent`, which can be accessed from
`Assets<Image>` via the `TRANSPARENT_IMAGE_HANDLE` constant.

Huge thanks to everyone who helped out with the design in the linked
issue and [the Discord
thread](https://discord.com/channels/691052431525675048/1255209923890118697/1255209999278280844):
this was very much a joint design.

@cart helped me figure out how to set the UiImage's default texture to a
transparent 1x1 image, which is a much nicer fix.

## Testing

I've checked the examples modified by this PR, and the `ui` example as
well just to be sure.

## Migration Guide

- `BackgroundColor` no longer tints the color of images in `ImageBundle`
or `ButtonBundle`. Set `UiImage::color` to tint images instead.
- The default texture for `UiImage` is now a transparent white square.
Use `UiImage::solid_color` to quickly draw debug images.
- The default value for `BackgroundColor` and `BorderColor` is now
transparent. Set the color to white manually to return to previous
behavior.
2024-06-25 21:50:41 +00:00
Rob Parrett
e46e246581
Fix a few "repeated word" typos (#13955)
# Objective

Stumbled on one of these and went digging for more

## Solution

```diff
- word word
+ word
```
2024-06-20 21:35:20 +00:00
Rob Parrett
c66c2c7420
Omit font size where it closely matches the default in examples (#13952)
# Objective

In a few examples, we're specifying a font or font size that is the same
as the current default value. Might as well use the default. That'll be
one less thing to worry about if we ever need to change the default font
size. (wink)

In a few others, we were using a value of `25.0` and it didn't seem like
it was different for an important reason, so I switched to the default
there too.

(There are a bunch of examples that use non-default font sizes for
various reasons. Not trying address them all here.)
2024-06-20 21:01:28 +00:00
Kornel
435d9bc02c
Highlight dependency on shader files in examples (#13824)
The examples won't work when copy-pasted to another project, without
also copying their shader files. This change adds constants at the top
of the files to bring attention to the dependencies.

Follow up to
[#13624](https://github.com/bevyengine/bevy/pull/13624#issuecomment-2143872791)
2024-06-12 14:16:01 +00:00
Lynn
fd82ef8956
Meshable extrusions (#13478)
# Objective

- Implement `Meshable` for `Extrusion<T>`

## Solution

- `Meshable` requires `Meshable::Output: MeshBuilder` now. This means
that all `some_primitive.mesh()` calls now return a `MeshBuilder`. These
were added for primitives that did not have one prior to this.
- A new trait `Extrudable: MeshBuilder` has been added. This trait
allows you to specify the indices of the perimeter of the mesh created
by this `MeshBuilder` and whether they are to be shaded smooth or flat.
- `Extrusion<P: Primitive2d + Meshable>` is now `Meshable` aswell. The
associated `MeshBuilder` is `ExtrusionMeshBuilder` which is generic over
`P` and uses the `MeshBuilder` of its baseshape internally.
- `ExtrusionMeshBuilder` exposes the configuration functions of its
base-shapes builder.
- Updated the `3d_shapes` example to include `Extrusion`s

## Migration Guide

- Depending on the context, you may need to explicitly call
`.mesh().build()` on primitives where you have previously called
`.mesh()`
- The `Output` type of custom `Meshable` implementations must now derive
`MeshBuilder`.

## Additional information
- The extrusions UVs are done so that 
- the front face (`+Z`) is in the area between `(0, 0)` and `(0.5,
0.5)`,
- the back face (`-Z`) is in the area between `(0.5, 0)` and `(1, 0.5)`
- the mantle is in the area between `(0, 0.5)` and `(1, 1)`. Each
`PerimeterSegment` you specified in the `Extrudable` implementation will
be allocated an equal portion of this area.
- The UVs of the base shape are scaled to be in the front/back area so
whatever method of filling the full UV-space the base shape used is how
these areas will be filled.

Here is an example of what that looks like on a capsule:


https://github.com/bevyengine/bevy/assets/62256001/425ad288-fbbc-4634-9d3f-5e846cdce85f

This is the texture used:

![extrusion
uvs](https://github.com/bevyengine/bevy/assets/62256001/4e54e421-bfda-44b9-8571-412525cebddf)

The `3d_shapes` example now looks like this:


![image_2024-05-22_235915753](https://github.com/bevyengine/bevy/assets/62256001/3d8bc86d-9ed1-47f2-899a-27aac0a265dd)

---------

Co-authored-by: Lynn Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
Co-authored-by: Matty <weatherleymatthew@gmail.com>
Co-authored-by: Matty <2975848+mweatherley@users.noreply.github.com>
2024-06-04 17:27:32 +00:00
Patrick Walton
ace4c6023b
Implement subpixel morphological antialiasing, or SMAA. (#13423)
This commit implements a large subset of [*subpixel morphological
antialiasing*], better known as SMAA. SMAA is a 2011 antialiasing
technique that detects jaggies in an aliased image and smooths them out.
Despite its age, it's been a continual staple of games for over a
decade. Four quality presets are available: *low*, *medium*, *high*, and
*ultra*. I set the default to *high*, on account of modern GPUs being
significantly faster than they were in 2011.

Like the already-implemented FXAA, SMAA works on an unaliased image.
Unlike FXAA, it requires three passes: (1) edge detection; (2) blending
weight calculation; (3) neighborhood blending. Each of the first two
passes writes an intermediate texture for use by the next pass. The
first pass also writes to a stencil buffer in order to dramatically
reduce the number of pixels that the second pass has to examine. Also
unlike FXAA, two built-in lookup textures are required; I bundle them
into the library in compressed KTX2 format.

The [reference implementation of SMAA] is in HLSL, with abundant use of
preprocessor macros to achieve GLSL compatibility. Unfortunately, the
reference implementation predates WGSL by over a decade, so I had to
translate the HLSL to WGSL manually. As much as was reasonably possible
without sacrificing readability, I tried to translate line by line,
preserving comments, both to aid reviewing and to allow patches to the
HLSL to more easily apply to the WGSL. Most of SMAA's features are
supported, but in the interests of making this patch somewhat less huge,
I skipped a few of the more exotic ones:

* The temporal variant is currently unsupported. This is and has been
used in shipping games, so supporting temporal SMAA would be useful
follow-up work. It would, however, require some significant work on TAA
to ensure compatibility, so I opted to skip it in this patch.

* Depth- and chroma-based edge detection are unimplemented; only luma
is. Depth is lower-quality, but faster; chroma is higher-quality, but
slower. Luma is the suggested default edge detection algorithm. (Note
that depth-based edge detection wouldn't work on WebGL 2 anyway, because
of the Naga bug whereby depth sampling is miscompiled in GLSL. This is
the same bug that prevents depth of field from working on that
platform.)

* Predicated thresholding is currently unsupported.

* My implementation is incompatible with SSAA and MSAA, unlike the
original; MSAA must be turned off to use SMAA in Bevy. I believe this
feature was rarely used in practice.

The `anti_aliasing` example has been updated to allow experimentation
with and testing of the different SMAA quality presets. Along the way, I
refactored the example's help text rendering code a bit to eliminate
code repetition.

SMAA is fully supported on WebGL 2.

Fixes #9819.

[*subpixel morphological antialiasing*]: https://www.iryoku.com/smaa/

[reference implementation of SMAA]: https://github.com/iryoku/smaa

## Changelog

### Added

* Subpixel morphological antialiasing, or SMAA, is now available. To use
it, add the `SmaaSettings` component to your `Camera`.

![Screenshot 2024-05-18
134311](https://github.com/bevyengine/bevy/assets/157897/ffbd611c-1b32-4491-b2e2-e410688852ee)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-06-04 17:07:34 +00:00
Patrick Walton
df8ccb8735
Implement PBR anisotropy per KHR_materials_anisotropy. (#13450)
This commit implements support for physically-based anisotropy in Bevy's
`StandardMaterial`, following the specification for the
[`KHR_materials_anisotropy`] glTF extension.

[*Anisotropy*] (not to be confused with [anisotropic filtering]) is a
PBR feature that allows roughness to vary along the tangent and
bitangent directions of a mesh. In effect, this causes the specular
light to stretch out into lines instead of a round lobe. This is useful
for modeling brushed metal, hair, and similar surfaces. Support for
anisotropy is a common feature in major game and graphics engines;
Unity, Unreal, Godot, three.js, and Blender all support it to varying
degrees.

Two new parameters have been added to `StandardMaterial`:
`anisotropy_strength` and `anisotropy_rotation`. Anisotropy strength,
which ranges from 0 to 1, represents how much the roughness differs
between the tangent and the bitangent of the mesh. In effect, it
controls how stretched the specular highlight is. Anisotropy rotation
allows the roughness direction to differ from the tangent of the model.

In addition to these two fixed parameters, an *anisotropy texture* can
be supplied. Such a texture should be a 3-channel RGB texture, where the
red and green values specify a direction vector using the same
conventions as a normal map ([0, 1] color values map to [-1, 1] vector
values), and the the blue value represents the strength. This matches
the format that the [`KHR_materials_anisotropy`] specification requires.
Such textures should be loaded as linear and not sRGB. Note that this
texture does consume one additional texture binding in the standard
material shader.

The glTF loader has been updated to properly parse the
`KHR_materials_anisotropy` extension.

A new example, `anisotropy`, has been added. This example loads and
displays the barn lamp example from the [`glTF-Sample-Assets`]
repository. Note that the textures were rather large, so I shrunk them
down and converted them to a mixture of JPEG and KTX2 format, in the
interests of saving space in the Bevy repository.

[*Anisotropy*]:
https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel

[anisotropic filtering]:
https://en.wikipedia.org/wiki/Anisotropic_filtering

[`KHR_materials_anisotropy`]:
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_anisotropy/README.md

[`glTF-Sample-Assets`]:
https://github.com/KhronosGroup/glTF-Sample-Assets/

## Changelog

### Added

* Physically-based anisotropy is now available for materials, which
enhances the look of surfaces such as brushed metal or hair. glTF scenes
can use the new feature with the `KHR_materials_anisotropy` extension.

## Screenshots

With anisotropy:
![Screenshot 2024-05-20
233414](https://github.com/bevyengine/bevy/assets/157897/379f1e42-24e9-40b6-a430-f7d1479d0335)

Without anisotropy:
![Screenshot 2024-05-20
233420](https://github.com/bevyengine/bevy/assets/157897/aa220f05-b8e7-417c-9671-b242d4bf9fc4)
2024-06-03 23:46:06 +00:00
Ricky Taylor
9b9d3d81cb
Normalise matrix naming (#13489)
# Objective
- Fixes #10909
- Fixes #8492

## Solution
- Name all matrices `x_from_y`, for example `world_from_view`.

## Testing
- I've tested most of the 3D examples. The `lighting` example
particularly should hit a lot of the changes and appears to run fine.

---

## Changelog
- Renamed matrices across the engine to follow a `y_from_x` naming,
making the space conversion more obvious.

## Migration Guide
- `Frustum`'s `from_view_projection`, `from_view_projection_custom_far`
and `from_view_projection_no_far` were renamed to
`from_clip_from_world`, `from_clip_from_world_custom_far` and
`from_clip_from_world_no_far`.
- `ComputedCameraValues::projection_matrix` was renamed to
`clip_from_view`.
- `CameraProjection::get_projection_matrix` was renamed to
`get_clip_from_view` (this affects implementations on `Projection`,
`PerspectiveProjection` and `OrthographicProjection`).
- `ViewRangefinder3d::from_view_matrix` was renamed to
`from_world_from_view`.
- `PreviousViewData`'s members were renamed to `view_from_world` and
`clip_from_world`.
- `ExtractedView`'s `projection`, `transform` and `view_projection` were
renamed to `clip_from_view`, `world_from_view` and `clip_from_world`.
- `ViewUniform`'s `view_proj`, `unjittered_view_proj`,
`inverse_view_proj`, `view`, `inverse_view`, `projection` and
`inverse_projection` were renamed to `clip_from_world`,
`unjittered_clip_from_world`, `world_from_clip`, `world_from_view`,
`view_from_world`, `clip_from_view` and `view_from_clip`.
- `GpuDirectionalCascade::view_projection` was renamed to
`clip_from_world`.
- `MeshTransforms`' `transform` and `previous_transform` were renamed to
`world_from_local` and `previous_world_from_local`.
- `MeshUniform`'s `transform`, `previous_transform`,
`inverse_transpose_model_a` and `inverse_transpose_model_b` were renamed
to `world_from_local`, `previous_world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh` type in WGSL mirrors this, however `transform` and
`previous_transform` were named `model` and `previous_model`).
- `Mesh2dTransforms::transform` was renamed to `world_from_local`.
- `Mesh2dUniform`'s `transform`, `inverse_transpose_model_a` and
`inverse_transpose_model_b` were renamed to `world_from_local`,
`local_from_world_transpose_a` and `local_from_world_transpose_b` (the
`Mesh2d` type in WGSL mirrors this).
- In WGSL, in `bevy_pbr::mesh_functions`, `get_model_matrix` and
`get_previous_model_matrix` were renamed to `get_world_from_local` and
`get_previous_world_from_local`.
- In WGSL, `bevy_sprite::mesh2d_functions::get_model_matrix` was renamed
to `get_world_from_local`.
2024-06-03 16:56:53 +00:00
IceSentry
bb51635481
Add subdivisions to PlaneMeshBuilder (#13580)
# Objective

- Plane subdivision was removed without providing an alternative

## Solution

- Add subdivision to the PlaneMeshBuilder

---

## Migration Guide

If you were using `Plane` `subdivisions`, you now need to use
`Plane3d::default().mesh().subdivisions(10)`

fixes https://github.com/bevyengine/bevy/issues/13258
2024-06-03 13:57:07 +00:00
Mark Moissette
d26900a9ea
add handling of all missing gltf extras: scene, mesh & materials (#13453)
# Objective

- fixes #4823 

## Solution

As outlined in the discussion in the linked issue as the best current
solution, this PR adds specific GltfExtras for
 - scenes 
 - meshes
 - materials

- As it is , it is not a breaking change, I hesitated to rename the
current "GltfExtras" component to "PrimitiveGltfExtras", but that would
result in a breaking change and might be a bit confusing as to what
"primitive" that refers to.
 

## Testing

- I included a bare-bones example & asset (exported gltf file from
Blender) with gltf extras at all the relevant levels : scene, mesh,
material

---

## Changelog
- adds "SceneGltfExtras" injected at the scene level if any
- adds "MeshGltfExtras", injected at the mesh level if any
- adds "MaterialGltfExtras", injected at the mesh level if any: ie if a
mesh has a material that has gltf extras, the component will be injected
there.
2024-06-03 13:16:38 +00:00
François Mockers
5559632977
glTF labels: add enum to avoid misspelling and keep up-to-date list documented (#13586)
# Objective

- Followup to #13548
- It added a list of all possible labels to documentation. This seems
hard to keep up and doesn't stop people from making spelling mistake

## Solution

- Add an enum that can create all the labels possible, and encourage its
use rather than manually typed labels

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-05-31 23:25:57 +00:00
Martín Maita
f237cf2441
Updates default Text font size to 24px (#13603)
# Objective

- The default font size is too small to be useful in examples or for
debug text.
- Fixes #13587

## Solution

- Updated the default font size value in `TextStyle` from 12px to 24px.
- Resorted to Text defaults in examples to use the default font size in
most of them.

## Testing

- WIP

---

## Migration Guide

- The default font size has been increased to 24px from 12px. Make sure
you set the font to the appropriate values in places you were using
`Default` text style.
2024-05-31 16:41:27 +00:00
François Mockers
cf7d810980
color_grading: update UI when camera settings changed (#13589)
# Objective

- In #13542 I broke example `color_grading`: the UI is not updated to
reflect changed camera settings
- Fixes #13590.

## Solution

- Update the UI when changing color grading
2024-05-31 06:42:05 +00:00
Rob Parrett
06f733b16f
Use standard instruction text / position in various examples (#13583)
## Objective

Use the "standard" text size / placement for the new text in these
examples.

Continuation of an effort started here:
https://github.com/bevyengine/bevy/pull/8478

This is definitely not comprehensive. I did the ones that were easy to
find and relatively straightforward updates. I meant to just do
`3d_shapes` and `2d_shapes`, but one thing lead to another.

## Solution

Use `font_size: 20.0`, the default (built-in) font, `Color::WHITE`
(default), and `Val::Px(12.)` from the edges of the screen.

There are a few little drive-by cleanups of defaults not being used,
etc.

## Testing

Ran the changed examples, verified that they still look reasonable.
2024-05-30 23:11:23 +00:00
IceSentry
ed042e5f9a
Add wireframe toggle to 2d and 3d shapes example (#13581)
# Objective

- It's nice to be able to see how the mesh look for each primitives

## Solution

- Add a way to toggle wireframes when pressing spacebar
- I also added some text to indicate this is an option


![image](https://github.com/bevyengine/bevy/assets/8348954/d37fe644-65e6-42fa-9420-390150c03c17)

![2d_shapes_GpaCcK3Rek](https://github.com/bevyengine/bevy/assets/8348954/2e977a47-4c3d-44f7-b149-1e67f522f0b6)
2024-05-30 20:00:59 +00:00
Alice Cecile
9d74e16821
Set the default target exposure to the minimum value, not 0 (#13562)
# Objective

- In particularly dark scenes, auto-exposure would lead to an unexpected
darkening of the view.
- Fixes #13446.

## Solution

The average luminance should default to something else than 0.0 instead,
when there are no samples. We set it to `settings.min_log_lum`.

## Testing

I was able to reproduce the problem on the `auto_exposure` example by
setting the point light intensity to 2000 and looking into the
right-hand corner. There was a sudden darkening.

Now, the discontinuity is gone.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Bram Buurlage <brambuurlage@gmail.com>
2024-05-29 22:37:42 +00:00
andristarr
2ac290dd8f
Swapping back to using From<Color> for StandardMaterial in examples (#13566)
# Objective

Fixes #13547
2024-05-29 13:50:28 +00:00
GitGhillie
f45eddfe82
Set ambient_intensity to 0.0 in volumetric_fog example, correct doc comment (#13531)
# Objective

- Fixes #13521

## Solution

Set `ambient_intensity` to 0.0 in volumetric_fog example.

I chose setting it explicitly over changing the default in order to make
it clear that this needs to be set depending on whether you have an
`EnvironmentMapLight`. See documentation for `ambient_intensity` and
related members.

## Testing

- Run the volumetric_fog example and notice how the light shown in
#13521 is not there anymore, as expected.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-28 10:55:29 +00:00
François Mockers
d92b1fcef7
small improvements on the color_grading example (#13542)
# Objective

- Small improvements on the `color_grading` example

## Solution

- Simplify button creation by creating them in the default state, the
selected one is automatically selected
- Don't update the UI if not needed
- Also invert the border of the selected button
- Simplify text update
2024-05-27 22:09:38 +00:00
François Mockers
a8751390aa
revert reflections PR changes to the meshlet example (#13539)
# Objective

- #13418 introduced unwanted changes to the meshlet example

## Solution

- Remove them
2024-05-27 19:48:18 +00:00
Patrick Walton
f398674e51
Implement opt-in sharp screen-space reflections for the deferred renderer, with improved raymarching code. (#13418)
This commit, a revamp of #12959, implements screen-space reflections
(SSR), which approximate real-time reflections based on raymarching
through the depth buffer and copying samples from the final rendered
frame. This patch is a relatively minimal implementation of SSR, so as
to provide a flexible base on which to customize and build in the
future. However, it's based on the production-quality [raymarching code
by Tomasz
Stachowiak](https://gist.github.com/h3r2tic/9c8356bdaefbe80b1a22ae0aaee192db).

For a general basic overview of screen-space reflections, see
[1](https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html).
The raymarching shader uses the basic algorithm of tracing forward in
large steps, refining that trace in smaller increments via binary
search, and then using the secant method. No temporal filtering or
roughness blurring, is performed at all; for this reason, SSR currently
only operates on very shiny surfaces. No acceleration via the
hierarchical Z-buffer is implemented (though note that
https://github.com/bevyengine/bevy/pull/12899 will add the
infrastructure for this). Reflections are traced at full resolution,
which is often considered slow. All of these improvements and more can
be follow-ups.

SSR is built on top of the deferred renderer and is currently only
supported in that mode. Forward screen-space reflections are possible
albeit uncommon (though e.g. *Doom Eternal* uses them); however, they
require tracing from the previous frame, which would add complexity.
This patch leaves the door open to implementing SSR in the forward
rendering path but doesn't itself have such an implementation.
Screen-space reflections aren't supported in WebGL 2, because they
require sampling from the depth buffer, which Naga can't do because of a
bug (`sampler2DShadow` is incorrectly generated instead of `sampler2D`;
this is the same reason why depth of field is disabled on that
platform).

To add screen-space reflections to a camera, use the
`ScreenSpaceReflectionsBundle` bundle or the
`ScreenSpaceReflectionsSettings` component. In addition to
`ScreenSpaceReflectionsSettings`, `DepthPrepass` and `DeferredPrepass`
must also be present for the reflections to show up. The
`ScreenSpaceReflectionsSettings` component contains several settings
that artists can tweak, and also comes with sensible defaults.

A new example, `ssr`, has been added. It's loosely based on the
[three.js ocean
sample](https://threejs.org/examples/webgl_shaders_ocean.html), but all
the assets are original. Note that the three.js demo has no screen-space
reflections and instead renders a mirror world. In contrast to #12959,
this demo tests not only a cube but also a more complex model (the
flight helmet).

## Changelog

### Added

* Screen-space reflections can be enabled for very smooth surfaces by
adding the `ScreenSpaceReflections` component to a camera. Deferred
rendering must be enabled for the reflections to appear.

![Screenshot 2024-05-18
143555](https://github.com/bevyengine/bevy/assets/157897/b8675b39-8a89-433e-a34e-1b9ee1233267)

![Screenshot 2024-05-18
143606](https://github.com/bevyengine/bevy/assets/157897/cc9e1cd0-9951-464a-9a08-e589210e5606)
2024-05-27 13:43:40 +00:00
Joona Aalto
383314ef62
Add meshing for ConicalFrustum (#11819)
# Objective

The `ConicalFrustum` primitive should support meshing.

## Solution

Implement meshing for the `ConicalFrustum` primitive. The implementation
is nearly identical to `Cylinder` meshing, but supports two radii.

The default conical frustum is equivalent to a cone with a height of 1
and a radius of 0.5, truncated at half-height.


![kuva](https://github.com/bevyengine/bevy/assets/57632562/b4cab136-ff55-4056-b818-1218e4f38845)
2024-05-25 21:56:09 +00:00
andristarr
44c0325ecd
Emissive is now LinearRgba on StandardMaterial (#13352)
StandardMaterial stores a LinearRgba instead of a Color for emissive

Fixes #13212
2024-05-24 17:23:35 +00:00
Jiří Švejda
4dbfdcf192
Fix lighting example following emissive material changes in #13350 (#13480)
# Objective

After the emissive material changes in #13350, the red and green point
lights in the `lighting` example turned white.

## Solution

This PR gives the point lights the `emissive_exposure_weight` property
in order for them to appear with correct color again.

## Testing

The `lighting` example before this fix:


![image](https://github.com/bevyengine/bevy/assets/143610747/be31d422-f616-4651-ab63-18ddfdba3773)

After this fix (looks the same as before #13350):


![image](https://github.com/bevyengine/bevy/assets/143610747/e5b5eab3-0588-4f30-bf74-2b52db7345ad)
2024-05-23 00:30:30 +00:00
Matty
c7f7d906ca
Tetrahedron mesh (#13463)
# Objective

Allow the `Tetrahedron` primitive to be used for mesh generation. This
is part of ongoing work to bring unify the capabilities of `bevy_math`
primitives.

## Solution

`Tetrahedron` implements `Meshable`. Essentially, each face is just
meshed as a `Triangle3d`, but first there is an inversion step when the
signed volume of the tetrahedron is negative to ensure that the faces
all actually point outward.

## Testing

I loaded up some examples and hackily exchanged existing meshes with the
new one to see that it works as expected.
2024-05-22 12:22:11 +00:00
Johannes Hackel
1fcf6a444f
Add emissive_exposure_weight to the StandardMaterial (#13350)
# Objective

- The emissive color gets multiplied by the camera exposure value. But
this cancels out almost any emissive effect.
- Fixes #13133
- Closes PR #13337 

## Solution
- Add emissive_exposure_weight to the StandardMaterial
- In the shader this value is stored in the alpha channel of the
emissive color.
- This value defines how much the exposure influences the emissive
color.
- It's equal to Google's Filament:
https://google.github.io/filament/Materials.html#emissive

4f021583f1/shaders/src/shading_lit.fs (L287)

## Testing

- The result of
[EmissiveStrengthTest](https://github.com/KhronosGroup/glTF-Sample-Models/tree/main/2.0/EmissiveStrengthTest)
with the default value of 0.0:

without bloom:

![emissive_fix](https://github.com/bevyengine/bevy/assets/688816/8f8c131a-464a-4d7b-a9e4-4e28d679ee5d)

with bloom:

![emissive_fix_bloom](https://github.com/bevyengine/bevy/assets/688816/89f200ee-3bd5-4daa-bf64-8999b56df3fa)
2024-05-17 13:49:53 +00:00
François Mockers
104dcf5a67
example render_to_texture: remove extra light (#13398)
# Objective

- in example `render_to_texture`, #13317 changed the comment on the
existing light saying lights don't work on multiple layers, then add a
light on multiple layers explaining that it will work. it's confusing

## Solution

- Keep the original light, with the updated comment

## Testing

- Run example `render_to_texture`, lighting is correct
2024-05-16 23:26:55 +00:00
Rob Parrett
7cbc0357be
Use load_with_settings instead of manually overriding srgbness in examples (#13399)
# Objective

`parallax_mapping` and `deferred_rendering` both use a roundabout way of
manually overriding the srgbness of their normal map textures.

This can now be done with `load_with_settings` in one line of code.

## Solution

- Delete the override systems and use `load_with_settings` instead
- Make `deferred_rendering`'s instruction text style consistent with
other examples while I'm in there.
    (see #8478)

## Testing

Tested by running with `load` instead of `load_settings` and confirming
that lighting looks bad when `is_srgb` is not configured, and good when
it is.

## Discussion

It would arguably make more sense to configure this in a `.meta` file,
but I used `load_with_settings` because that's how it was done in the
`clearcoat` example and it does seem nice for documentation purposes to
call this out explicitly in code.
2024-05-16 23:26:22 +00:00
Patrick Walton
19bfa41768
Implement volumetric fog and volumetric lighting, also known as light shafts or god rays. (#13057)
This commit implements a more physically-accurate, but slower, form of
fog than the `bevy_pbr::fog` module does. Notably, this *volumetric fog*
allows for light beams from directional lights to shine through,
creating what is known as *light shafts* or *god rays*.

To add volumetric fog to a scene, add `VolumetricFogSettings` to the
camera, and add `VolumetricLight` to directional lights that you wish to
be volumetric. `VolumetricFogSettings` has numerous settings that allow
you to define the accuracy of the simulation, as well as the look of the
fog. Currently, only interaction with directional lights that have
shadow maps is supported. Note that the overhead of the effect scales
directly with the number of directional lights in use, so apply
`VolumetricLight` sparingly for the best results.

The overall algorithm, which is implemented as a postprocessing effect,
is a combination of the techniques described in [Scratchapixel] and
[this blog post]. It uses raymarching in screen space, transformed into
shadow map space for sampling and combined with physically-based
modeling of absorption and scattering. Bevy employs the widely-used
[Henyey-Greenstein phase function] to model asymmetry; this essentially
allows light shafts to fade into and out of existence as the user views
them.

Volumetric rendering is a huge subject, and I deliberately kept the
scope of this commit small. Possible follow-ups include:

1. Raymarching at a lower resolution.

2. A post-processing blur (especially useful when combined with (1)).

3. Supporting point lights and spot lights.

4. Supporting lights with no shadow maps.

5. Supporting irradiance volumes and reflection probes.

6. Voxel components that reuse the volumetric fog code to create voxel
shapes.

7. *Horizon: Zero Dawn*-style clouds.

These are all useful, but out of scope of this patch for now, to keep
things tidy and easy to review.

A new example, `volumetric_fog`, has been added to demonstrate the
effect.

## Changelog

### Added

* A new component, `VolumetricFog`, is available, to allow for a more
physically-accurate, but more resource-intensive, form of fog.

* A new component, `VolumetricLight`, can be placed on directional
lights to make them interact with `VolumetricFog`. Notably, this allows
such lights to emit light shafts/god rays.

![Screenshot 2024-04-21
162808](https://github.com/bevyengine/bevy/assets/157897/7a1fc81d-eed5-4735-9419-286c496391a9)

![Screenshot 2024-04-21
132005](https://github.com/bevyengine/bevy/assets/157897/e6d3b5ca-8f59-488d-a3de-15e95aaf4995)

[Scratchapixel]:
https://www.scratchapixel.com/lessons/3d-basic-rendering/volume-rendering-for-developers/intro-volume-rendering.html

[this blog post]: https://www.alexandre-pestana.com/volumetric-lights/

[Henyey-Greenstein phase function]:
https://www.pbr-book.org/4ed/Volume_Scattering/Phase_Functions#TheHenyeyndashGreensteinPhaseFunction
2024-05-16 17:13:18 +00:00
charlotte
4c3b7679ec
#12502 Remove limit on RenderLayers. (#13317)
# Objective

Remove the limit of `RenderLayer` by using a growable mask using
`SmallVec`.

Changes adopted from @UkoeHB's initial PR here
https://github.com/bevyengine/bevy/pull/12502 that contained additional
changes related to propagating render layers.

Changes

## Solution

The main thing needed to unblock this is removing `RenderLayers` from
our shader code. This primarily affects `DirectionalLight`. We are now
computing a `skip` field on the CPU that is then used to skip the light
in the shader.

## Testing

Checked a variety of examples and did a quick benchmark on `many_cubes`.
There were some existing problems identified during the development of
the original pr (see:
https://discord.com/channels/691052431525675048/1220477928605749340/1221190112939872347).
This PR shouldn't change any existing behavior besides removing the
layer limit (sans the comment in migration about `all` layers no longer
being possible).

---

## Changelog

Removed the limit on `RenderLayers` by using a growable bitset that only
allocates when layers greater than 64 are used.

## Migration Guide

- `RenderLayers::all()` no longer exists. Entities expecting to be
visible on all layers, e.g. lights, should compute the active layers
that are in use.

---------

Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2024-05-16 16:15:47 +00:00
Patrick Walton
df31b808c3
Implement fast depth of field as a postprocessing effect. (#13009)
This commit implements the [depth of field] effect, simulating the blur
of objects out of focus of the virtual lens. Either the [hexagonal
bokeh] effect or a faster Gaussian blur may be used. In both cases, the
implementation is a simple separable two-pass convolution. This is not
the most physically-accurate real-time bokeh technique that exists;
Unreal Engine has [a more accurate implementation] of "cinematic depth
of field" from 2018. However, it's simple, and most engines provide
something similar as a fast option, often called "mobile" depth of
field.

The general approach is outlined in [a blog post from 2017]. We take
advantage of the fact that both Gaussian blurs and hexagonal bokeh blurs
are *separable*. This means that their 2D kernels can be reduced to a
small number of 1D kernels applied one after another, asymptotically
reducing the amount of work that has to be done. Gaussian blurs can be
accomplished by blurring horizontally and then vertically, while
hexagonal bokeh blurs can be done with a vertical blur plus a diagonal
blur, plus two diagonal blurs. In both cases, only two passes are
needed. Bokeh requires the first pass to have a second render target and
requires two subpasses in the second pass, which decreases its
performance relative to the Gaussian blur.

The bokeh blur is generally more aesthetically pleasing than the
Gaussian blur, as it simulates the effect of a camera more accurately.
The shape of the bokeh circles are determined by the number of blades of
the aperture. In our case, we use a hexagon, which is usually considered
specific to lower-quality cameras. (This is a downside of the fast
hexagon approach compared to the higher-quality approaches.) The blur
amount is generally specified by the [f-number], which we use to compute
the focal length from the film size and FOV. By default, we simulate
standard cinematic cameras of f/1 and [Super 35]. The developer can
customize these values as desired.

A new example has been added to demonstrate depth of field. It allows
customization of the mode (Gaussian vs. bokeh), focal distance and
f-numbers. The test scene is inspired by a [blog post on depth of field
in Unity]; however, the effect is implemented in a completely different
way from that blog post, and all the assets (textures, etc.) are
original.

Bokeh depth of field:
![Screenshot 2024-04-17
152535](https://github.com/bevyengine/bevy/assets/157897/702f0008-1c8a-4cf3-b077-4110f8c46584)

Gaussian depth of field:
![Screenshot 2024-04-17
152542](https://github.com/bevyengine/bevy/assets/157897/f4ece47a-520e-4483-a92d-f4fa760795d3)

No depth of field:
![Screenshot 2024-04-17
152547](https://github.com/bevyengine/bevy/assets/157897/9444e6aa-fcae-446c-b66b-89469f1a1325)

[depth of field]: https://en.wikipedia.org/wiki/Depth_of_field

[hexagonal bokeh]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/

[a more accurate implementation]:
https://epicgames.ent.box.com/s/s86j70iamxvsuu6j35pilypficznec04

[a blog post from 2017]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/

[f-number]: https://en.wikipedia.org/wiki/F-number

[Super 35]: https://en.wikipedia.org/wiki/Super_35

[blog post on depth of field in Unity]:
https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/

## Changelog

### Added

* A depth of field postprocessing effect is now available, to simulate
objects being out of focus of the camera. To use it, add
`DepthOfFieldSettings` to an entity containing a `Camera3d` component.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Bram Buurlage <brambuurlage@gmail.com>
2024-05-13 18:23:56 +00:00
Joona Aalto
ac1f135e20
Add meshing for Cone (#11820)
# Objective

The `Cone` primitive should support meshing.

## Solution

Implement meshing for the `Cone` primitive. The default cone has a
height of 1 and a base radius of 0.5, and is centered at the origin.

An issue with cone meshes is that the tip does not really have a normal
that works, even with duplicated vertices. This PR uses only a single
vertex for the tip, with a normal of zero; this results in an "invalid"
normal that gets ignored by the fragment shader. This seems to be the
only approach we have for perfectly smooth cones. For discussion on the
topic, see #10298 and #5891.

Another thing to note is that the cone uses polar coordinates for the
UVs:

<img
src="https://github.com/bevyengine/bevy/assets/57632562/e101ded9-110a-4ac4-a98d-f1e4d740a24a"
alt="cone" width="400" />

This way, textures are applied as if looking at the cone from above:

<img
src="https://github.com/bevyengine/bevy/assets/57632562/8dea00f1-a283-4bc4-9676-91e8d4adb07a"
alt="texture" width="200" />

<img
src="https://github.com/bevyengine/bevy/assets/57632562/d9d1b5e6-a8ba-4690-b599-904dd85777a1"
alt="cone" width="200" />
2024-05-13 18:00:59 +00:00
Rob Parrett
2fd432c463
Fix motion blur on wasm (#13099)
# Objective

Fixes #13097 and other issues preventing the motion blur example from
working on wasm

## Solution

- Use a vec2 for padding
- Fix error initializing the `MotionBlur` struct on wasm+webgl2
- Disable MSAA on wasm+webgl2
- Fix `GlobalsUniform` padding getting added on the shader side for
webgpu builds

## Notes

The motion blur example now runs, but with artifacts. In addition to the
obvious black artifacts, the motion blur or dithering seem to just look
worse in a way I can't really describe. That may be expected.

```
AdapterInfo { name: "ANGLE (Apple, ANGLE Metal Renderer: Apple M1 Max, Unspecified Version)", vendor: 4203, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Gl }
```
<img width="1276" alt="Screenshot 2024-04-25 at 6 51 21 AM"
src="https://github.com/bevyengine/bevy/assets/200550/65401d4f-92fe-454b-9dbc-a2d89d3ad963">
2024-05-12 21:03:36 +00:00
Fpgu
60a73fa60b
Use Dir3 for local axis methods in GlobalTransform (#13264)
Switched the return type from `Vec3` to `Dir3` for directional axis
methods within the `GlobalTransform` component.

## Migration Guide
The `GlobalTransform` component's directional axis methods (e.g.,
`right()`, `left()`, `up()`, `down()`, `back()`, `forward()`) have been
updated from returning `Vec3` to `Dir3`.
2024-05-06 20:52:05 +00:00
Patrick Walton
77ed72bc16
Implement clearcoat per the Filament and the KHR_materials_clearcoat specifications. (#13031)
Clearcoat is a separate material layer that represents a thin
translucent layer of a material. Examples include (from the [Filament
spec]) car paint, soda cans, and lacquered wood. This commit implements
support for clearcoat following the Filament and Khronos specifications,
marking the beginnings of support for multiple PBR layers in Bevy.

The [`KHR_materials_clearcoat`] specification describes the clearcoat
support in glTF. In Blender, applying a clearcoat to the Principled BSDF
node causes the clearcoat settings to be exported via this extension. As
of this commit, Bevy parses and reads the extension data when present in
glTF. Note that the `gltf` crate has no support for
`KHR_materials_clearcoat`; this patch therefore implements the JSON
semantics manually.

Clearcoat is integrated with `StandardMaterial`, but the code is behind
a series of `#ifdef`s that only activate when clearcoat is present.
Additionally, the `pbr_feature_layer_material_textures` Cargo feature
must be active in order to enable support for clearcoat factor maps,
clearcoat roughness maps, and clearcoat normal maps. This approach
mirrors the same pattern used by the existing transmission feature and
exists to avoid running out of texture bindings on platforms like WebGL
and WebGPU. Note that constant clearcoat factors and roughness values
*are* supported in the browser; only the relatively-less-common maps are
disabled on those platforms.

This patch refactors the lighting code in `StandardMaterial`
significantly in order to better support multiple layers in a natural
way. That code was due for a refactor in any case, so this is a nice
improvement.

A new demo, `clearcoat`, has been added. It's based on [the
corresponding three.js demo], but all the assets (aside from the skybox
and environment map) are my original work.

[Filament spec]:
https://google.github.io/filament/Filament.html#materialsystem/clearcoatmodel

[`KHR_materials_clearcoat`]:
https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_clearcoat/README.md

[the corresponding three.js demo]:
https://threejs.org/examples/webgl_materials_physical_clearcoat.html

![Screenshot 2024-04-19
101143](https://github.com/bevyengine/bevy/assets/157897/3444bcb5-5c20-490c-b0ad-53759bd47ae2)

![Screenshot 2024-04-19
102054](https://github.com/bevyengine/bevy/assets/157897/6e953944-75b8-49ef-bc71-97b0a53b3a27)

## Changelog

### Added

* `StandardMaterial` now supports a clearcoat layer, which represents a
thin translucent layer over an underlying material.
* The glTF loader now supports the `KHR_materials_clearcoat` extension,
representing materials with clearcoat layers.

## Migration Guide

* The lighting functions in the `pbr_lighting` WGSL module now have
clearcoat parameters, if `STANDARD_MATERIAL_CLEARCOAT` is defined.

* The `R` reflection vector parameter has been removed from some
lighting functions, as it was unused.
2024-05-05 22:57:05 +00:00
Bram Buurlage
d390420093
Implement Auto Exposure plugin (#12792)
# Objective

- Add auto exposure/eye adaptation to the bevy render pipeline.
- Support features that users might expect from other engines:
  - Metering masks
  - Compensation curves
  - Smooth exposure transitions 

This PR is based on an implementation I already built for a personal
project before https://github.com/bevyengine/bevy/pull/8809 was
submitted, so I wasn't able to adopt that PR in the proper way. I've
still drawn inspiration from it, so @fintelia should be credited as
well.

## Solution

An auto exposure compute shader builds a 64 bin histogram of the scene's
luminance, and then adjusts the exposure based on that histogram. Using
a histogram allows the system to ignore outliers like shadows and
specular highlights, and it allows to give more weight to certain areas
based on a mask.

---

## Changelog

- Added: AutoExposure plugin that allows to adjust a camera's exposure
based on it's scene's luminance.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-05-03 17:45:17 +00:00
Patrick Walton
31835ff76d
Implement visibility ranges, also known as hierarchical levels of detail (HLODs). (#12916)
Implement visibility ranges, also known as hierarchical levels of detail
(HLODs).

This commit introduces a new component, `VisibilityRange`, which allows
developers to specify camera distances in which meshes are to be shown
and hidden. Hiding meshes happens early in the rendering pipeline, so
this feature can be used for level of detail optimization. Additionally,
this feature is properly evaluated per-view, so different views can show
different levels of detail.

This feature differs from proper mesh LODs, which can be implemented
later. Engines generally implement true mesh LODs later in the pipeline;
they're typically more efficient than HLODs with GPU-driven rendering.
However, mesh LODs are more limited than HLODs, because they require the
lower levels of detail to be meshes with the same vertex layout and
shader (and perhaps the same material) as the original mesh. Games often
want to use objects other than meshes to replace distant models, such as
*octahedral imposters* or *billboard imposters*.

The reason why the feature is called *hierarchical level of detail* is
that HLODs can replace multiple meshes with a single mesh when the
camera is far away. This can be useful for reducing drawcall count. Note
that `VisibilityRange` doesn't automatically propagate down to children;
it must be placed on every mesh.

Crossfading between different levels of detail is supported, using the
standard 4x4 ordered dithering pattern from [1]. The shader code to
compute the dithering patterns should be well-optimized. The dithering
code is only active when visibility ranges are in use for the mesh in
question, so that we don't lose early Z.

Cascaded shadow maps show the HLOD level of the view they're associated
with. Point light and spot light shadow maps, which have no CSMs,
display all HLOD levels that are visible in any view. To support this
efficiently and avoid doing visibility checks multiple times, we
precalculate all visible HLOD levels for each entity with a
`VisibilityRange` during the `check_visibility_range` system.

A new example, `visibility_range`, has been added to the tree, as well
as a new low-poly version of the flight helmet model to go with it. It
demonstrates use of the visibility range feature to provide levels of
detail.

[1]: https://en.wikipedia.org/wiki/Ordered_dithering#Threshold_map

[^1]: Unreal doesn't have a feature that exactly corresponds to
visibility ranges, but Unreal's HLOD system serves roughly the same
purpose.

## Changelog

### Added

* A new `VisibilityRange` component is available to conditionally enable
entity visibility at camera distances, with optional crossfade support.
This can be used to implement different levels of detail (LODs).

## Screenshots

High-poly model:
![Screenshot 2024-04-09
185541](https://github.com/bevyengine/bevy/assets/157897/7e8be017-7187-4471-8866-974e2d8f2623)

Low-poly model up close:
![Screenshot 2024-04-09
185546](https://github.com/bevyengine/bevy/assets/157897/429603fe-6bb7-4246-8b4e-b4888fd1d3a0)

Crossfading between the two:
![Screenshot 2024-04-09
185604](https://github.com/bevyengine/bevy/assets/157897/86d0d543-f8f3-49ec-8fe5-caa4d0784fd4)

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2024-05-03 00:11:35 +00:00
François Mockers
1c15ac647a
Example setup for tooling (#13088)
# Objective

- #12755 introduced the need to download a file to run an example
- This means the example fails to run in CI without downloading that
file

## Solution

- Add a new metadata to examples "setup" that provides setup
instructions
- Replace the URL in the meshlet example to one that can actually be
downloaded
- example-showcase execute the setup before running an example
2024-05-02 20:10:09 +00:00
Alice Cecile
b2123ffa41
Fix CI error on new color grading example (#13180)
# Objective

Fixes https://github.com/bevyengine/bevy/issues/13179

## Solution

Obey clippy.

## Commentary

I'm really confused why CI didn't fail on the initial PR merge here.

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-05-02 13:40:45 +00:00
Patrick Walton
961b24deaf
Implement filmic color grading. (#13121)
This commit expands Bevy's existing tonemapping feature to a complete
set of filmic color grading tools, matching those of engines like Unity,
Unreal, and Godot. The following features are supported:

* White point adjustment. This is inspired by Unity's implementation of
the feature, but simplified and optimized. *Temperature* and *tint*
control the adjustments to the *x* and *y* chromaticity values of [CIE
1931]. Following Unity, the adjustments are made relative to the [D65
standard illuminant] in the [LMS color space].

* Hue rotation. This simply converts the RGB value to [HSV], alters the
hue, and converts back.

* Color correction. This allows the *gamma*, *gain*, and *lift* values
to be adjusted according to the standard [ASC CDL combined function].

* Separate color correction for shadows, midtones, and highlights.
Blender's source code was used as a reference for the implementation of
this. The midtone ranges can be adjusted by the user. To avoid abrupt
color changes, a small crossfade is used between the different sections
of the image, again following Blender's formulas.

A new example, `color_grading`, has been added, offering a GUI to change
all the color grading settings. It uses the same test scene as the
existing `tonemapping` example, which has been factored out into a
shared glTF scene.

[CIE 1931]: https://en.wikipedia.org/wiki/CIE_1931_color_space

[D65 standard illuminant]:
https://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D

[LMS color space]: https://en.wikipedia.org/wiki/LMS_color_space

[HSV]: https://en.wikipedia.org/wiki/HSL_and_HSV

[ASC CDL combined function]:
https://en.wikipedia.org/wiki/ASC_CDL#Combined_Function

## Changelog

### Added

* Many new filmic color grading options have been added to the
`ColorGrading` component.

## Migration Guide

* `ColorGrading::gamma` and `ColorGrading::pre_saturation` are now set
separately for the `shadows`, `midtones`, and `highlights` sections. You
can migrate code with the `ColorGrading::all_sections` and
`ColorGrading::all_sections_mut` functions, which access and/or update
all sections at once.
* `ColorGrading::post_saturation` and `ColorGrading::exposure` are now
fields of `ColorGrading::global`.

## Screenshots

![Screenshot 2024-04-27
143144](https://github.com/bevyengine/bevy/assets/157897/c1de5894-917d-4101-b5c9-e644d141a941)

![Screenshot 2024-04-27
143216](https://github.com/bevyengine/bevy/assets/157897/da393c8a-d747-42f5-b47c-6465044c788d)
2024-05-02 12:18:59 +00:00
Patrick Walton
16531fb3e3
Implement GPU frustum culling. (#12889)
This commit implements opt-in GPU frustum culling, built on top of the
infrastructure in https://github.com/bevyengine/bevy/pull/12773. To
enable it on a camera, add the `GpuCulling` component to it. To
additionally disable CPU frustum culling, add the `NoCpuCulling`
component. Note that adding `GpuCulling` without `NoCpuCulling`
*currently* does nothing useful. The reason why `GpuCulling` doesn't
automatically imply `NoCpuCulling` is that I intend to follow this patch
up with GPU two-phase occlusion culling, and CPU frustum culling plus
GPU occlusion culling seems like a very commonly-desired mode.

Adding the `GpuCulling` component to a view puts that view into
*indirect mode*. This mode makes all drawcalls indirect, relying on the
mesh preprocessing shader to allocate instances dynamically. In indirect
mode, the `PreprocessWorkItem` `output_index` points not to a
`MeshUniform` instance slot but instead to a set of `wgpu`
`IndirectParameters`, from which it allocates an instance slot
dynamically if frustum culling succeeds. Batch building has been updated
to allocate and track indirect parameter slots, and the AABBs are now
supplied to the GPU as `MeshCullingData`.

A small amount of code relating to the frustum culling has been borrowed
from meshlets and moved into `maths.wgsl`. Note that standard Bevy
frustum culling uses AABBs, while meshlets use bounding spheres; this
means that not as much code can be shared as one might think.

This patch doesn't provide any way to perform GPU culling on shadow
maps, to avoid making this patch bigger than it already is. That can be
a followup.

## Changelog

### Added

* Frustum culling can now optionally be done on the GPU. To enable it,
add the `GpuCulling` component to a camera.
* To disable CPU frustum culling, add `NoCpuCulling` to a camera. Note
that `GpuCulling` doesn't automatically imply `NoCpuCulling`.
2024-04-28 12:50:00 +00:00
JMS55
e1a0da0fa6
Meshlet LOD-compatible two-pass occlusion culling (#12898)
Keeping track of explicit visibility per cluster between frames does not
work with LODs, and leads to worse culling (using the final depth buffer
from the previous frame is more accurate).

Instead, we need to generate a second depth pyramid after the second
raster pass, and then use that in the first culling pass in the next
frame to test if a cluster would have been visible last frame or not.

As part of these changes, the write_index_buffer pass has been folded
into the culling pass for a large performance gain, and to avoid
tracking a lot of extra state that would be needed between passes.

Prepass previous model/view stuff was adapted to work with meshlets as
well.

Also fixed a bug with materials, and other misc improvements.

---------

Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
2024-04-28 05:30:20 +00:00
Aevyrie
ade70b3925
Per-Object Motion Blur (#9924)
https://github.com/bevyengine/bevy/assets/2632925/e046205e-3317-47c3-9959-fc94c529f7e0

# Objective

- Adds per-object motion blur to the core 3d pipeline. This is a common
effect used in games and other simulations.
- Partially resolves #4710

## Solution

- This is a post-process effect that uses the depth and motion vector
buffers to estimate per-object motion blur. The implementation is
combined from knowledge from multiple papers and articles. The approach
itself, and the shader are quite simple. Most of the effort was in
wiring up the bevy rendering plumbing, and properly specializing for HDR
and MSAA.
- To work with MSAA, the MULTISAMPLED_SHADING wgpu capability is
required. I've extracted this code from #9000. This is because the
prepass buffers are multisampled, and require accessing with
`textureLoad` as opposed to the widely compatible `textureSample`.
- Added an example to demonstrate the effect of motion blur parameters.

## Future Improvements

- While this approach does have limitations, it's one of the most
commonly used, and is much better than camera motion blur, which does
not consider object velocity. For example, this implementation allows a
dolly to track an object, and that object will remain unblurred while
the background is blurred. The biggest issue with this implementation is
that blur is constrained to the boundaries of objects which results in
hard edges. There are solutions to this by either dilating the object or
the motion vector buffer, or by taking a different approach such as
https://casual-effects.com/research/McGuire2012Blur/index.html
- I'm using a noise PRNG function to jitter samples. This could be
replaced with a blue noise texture lookup or similar, however after
playing with the parameters, it gives quite nice results with 4 samples,
and is significantly better than the artifacts generated when not
jittering.

---

## Changelog

- Added: per-object motion blur. This can be enabled and configured by
adding the `MotionBlurBundle` to a camera entity.

---------

Co-authored-by: Torstein Grindvik <52322338+torsteingrindvik@users.noreply.github.com>
2024-04-25 01:16:02 +00:00
JMS55
6d6810c90d
Meshlet continuous LOD (#12755)
Adds a basic level of detail system to meshlets. An extremely brief
summary is as follows:
* In `from_mesh.rs`, once we've built the first level of clusters, we
group clusters, simplify the new mega-clusters, and then split the
simplified groups back into regular sized clusters. Repeat several times
(ideally until you can't anymore). This forms a directed acyclic graph
(DAG), where the children are the meshlets from the previous level, and
the parents are the more simplified versions of their children. The leaf
nodes are meshlets formed from the original mesh.
* In `cull_meshlets.wgsl`, each cluster selects whether to render or not
based on the LOD bounding sphere (different than the culling bounding
sphere) of the current meshlet, the LOD bounding sphere of its parent
(the meshlet group from simplification), and the simplification error
relative to its children of both the current meshlet and its parent
meshlet. This kind of breaks two pass occlusion culling, which will be
fixed in a future PR by using an HZB from the previous frame to get the
initial list of occluders.

Many, _many_ improvements to be done in the future
https://github.com/bevyengine/bevy/issues/11518, not least of which is
code quality and speed. I don't even expect this to work on many types
of input meshes. This is just a basic implementation/draft for
collaboration.

Arguable how much we want to do in this PR, I'll leave that up to
maintainers. I've erred on the side of "as basic as possible".

References:
* Slides 27-77 (video available on youtube)
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
*
https://blog.traverseresearch.nl/creating-a-directed-acyclic-graph-from-a-mesh-1329e57286e5
*
https://jglrxavpok.github.io/2024/01/19/recreating-nanite-lod-generation.html,
https://jglrxavpok.github.io/2024/03/12/recreating-nanite-faster-lod-generation.html,
https://jglrxavpok.github.io/2024/04/02/recreating-nanite-runtime-lod-selection.html,
and https://github.com/jglrxavpok/Carrot
*
https://github.com/gents83/INOX/tree/master/crates/plugins/binarizer/src
* https://cs418.cs.illinois.edu/website/text/nanite.html


![image](https://github.com/bevyengine/bevy/assets/47158642/e40bff9b-7d0c-4a19-a3cc-2aad24965977)

![image](https://github.com/bevyengine/bevy/assets/47158642/442c7da3-7761-4da7-9acd-37f15dd13e26)

---------

Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
2024-04-23 21:43:53 +00:00
Grey
c593ee1055
Clarify comment about camera coordinate system (#13056)
# Objective

Clarify the comment about the camera's coordinate system in
`examples/3d/generate_custom_mesh.rs` by explicitly stating which axes
point where.
Fixes #13018

## Solution

Copy the wording from #13012 into the example.
2024-04-23 14:58:28 +00:00
IceSentry
8403c41c67
Use WireframeColor to override global color (#13034)
# Objective

- The docs says the WireframeColor is supposed to override the default
global color but it doesn't.

## Solution

- Use WireframeColor to override global color like docs said it was
supposed to do.
- Updated the example to document this feature
- I also took the opportunity to clean up the code a bit

Fixes #13032
2024-04-20 13:59:12 +00:00
andristarr
2b3e3341d6
separating finite and infinite 3d planes (#12426)
# Objective

Fixes #12388

## Solution

- Removing the plane3d and adding rect3d primitive mesh
2024-04-18 14:13:22 +00:00
Emily Selwood
da2ba8a43c
Add comment to example about coordinate system (#12991)
# Objective

When learning about creating meshes in bevy using this example I
couldn't tell which coordinate system bevy uses, which caused confusion
and having to look it up else where.

## Solution

Add a comment that says what coordinate system bevy uses.
2024-04-16 12:01:48 +00:00
Patrick Walton
1141e731ff
Implement alpha to coverage (A2C) support. (#12970)
[Alpha to coverage] (A2C) replaces alpha blending with a
hardware-specific multisample coverage mask when multisample
antialiasing is in use. It's a simple form of [order-independent
transparency] that relies on MSAA. ["Anti-aliased Alpha Test: The
Esoteric Alpha To Coverage"] is a good summary of the motivation for and
best practices relating to A2C.

This commit implements alpha to coverage support as a new variant for
`AlphaMode`. You can supply `AlphaMode::AlphaToCoverage` as the
`alpha_mode` field in `StandardMaterial` to use it. When in use, the
standard material shader automatically applies the texture filtering
method from ["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"].
Objects with alpha-to-coverage materials are binned in the opaque pass,
as they're fully order-independent.

The `transparency_3d` example has been updated to feature an object with
alpha to coverage. Happily, the example was already using MSAA.

This is part of #2223, as far as I can tell.

[Alpha to coverage]: https://en.wikipedia.org/wiki/Alpha_to_coverage

[order-independent transparency]:
https://en.wikipedia.org/wiki/Order-independent_transparency

["Anti-aliased Alpha Test: The Esoteric Alpha To Coverage"]:
https://bgolus.medium.com/anti-aliased-alpha-test-the-esoteric-alpha-to-coverage-8b177335ae4f

---

## Changelog

### Added

* The `AlphaMode` enum now supports `AlphaToCoverage`, to provide
limited order-independent transparency when multisample antialiasing is
in use.
2024-04-15 20:37:52 +00:00
Patrick Walton
d59b1e71ef
Implement percentage-closer filtering (PCF) for point lights. (#12910)
I ported the two existing PCF techniques to the cubemap domain as best I
could. Generally, the technique is to create a 2D orthonormal basis
using Gram-Schmidt normalization, then apply the technique over that
basis. The results look fine, though the shadow bias often needs
adjusting.

For comparison, Unity uses a 4-tap pattern for PCF on point lights of
(1, 1, 1), (-1, -1, 1), (-1, 1, -1), (1, -1, -1). I tried this but
didn't like the look, so I went with the design above, which ports the
2D techniques to the 3D domain. There's surprisingly little material on
point light PCF.

I've gone through every example using point lights and verified that the
shadow maps look fine, adjusting biases as necessary.

Fixes #3628.

---

## Changelog

### Added
* Shadows from point lights now support percentage-closer filtering
(PCF), and as a result look less aliased.

### Changed
* `ShadowFilteringMethod::Castano13` and
`ShadowFilteringMethod::Jimenez14` have been renamed to
`ShadowFilteringMethod::Gaussian` and `ShadowFilteringMethod::Temporal`
respectively.

## Migration Guide

* `ShadowFilteringMethod::Castano13` and
`ShadowFilteringMethod::Jimenez14` have been renamed to
`ShadowFilteringMethod::Gaussian` and `ShadowFilteringMethod::Temporal`
respectively.
2024-04-10 20:16:08 +00:00
BD103
97131e1909
Move close_on_esc to bevy_dev_tools (#12855)
# Objective

- As @james7132 said [on
Discord](https://discord.com/channels/691052431525675048/692572690833473578/1224626740773523536),
the `close_on_esc` system is forcing `bevy_window` to depend on
`bevy_input`.
- `close_on_esc` is not likely to be used in production, so it arguably
does not have a place in `bevy_window`.

## Solution

- As suggested by @afonsolage, move `close_on_esc` into
`bevy_dev_tools`.
  - Add an example to the documentation too.
- Remove `bevy_window`'s dependency on `bevy_input`.
- Add `bevy_reflect`'s `smol_str` feature to `bevy_window` because it
was implicitly depended upon with `bevy_input` before it was removed.
- Remove any usage of `close_on_esc` from the examples.
- `bevy_dev_tools` is not enabled by default. I personally find it
frustrating to run examples with additional features, so I opted to
remove it entirely.
  - This is up for discussion if you have an alternate solution.

---

## Changelog

- Moved `bevy_window::close_on_esc` to `bevy_dev_tools::close_on_esc`.
- Removed usage of `bevy_dev_tools::close_on_esc` from all examples.

## Migration Guide

`bevy_window::close_on_esc` has been moved to
`bevy_dev_tools::close_on_esc`. You will first need to enable
`bevy_dev_tools` as a feature in your `Cargo.toml`:

```toml
[dependencies]
bevy = { version = "0.14", features = ["bevy_dev_tools"] }
```

Finally, modify any imports to use `bevy_dev_tools` instead:

```rust
// Old:
// use bevy:🪟:close_on_esc;

// New:
use bevy::dev_tools::close_on_esc;

App::new()
    .add_systems(Update, close_on_esc)
    // ...
    .run();
```
2024-04-03 01:29:06 +00:00
Jake
7618884b2f
Fix UV coords in generate_custom_mesh example (#12826)
# Objective
Fix the last coordinate of the top side in the `generate_custom_mesh`
example.
Fixes #12822

## Images
Added a yellow square to the texture to demonstrate as suggested in [the
issue](https://github.com/bevyengine/bevy/issues/12822).

<details>
  <summary>Texture:</summary>
<img
src="https://github.com/bevyengine/bevy/assets/70668395/c605e916-bb02-4247-bf24-2f033c650419"
/>
</details>

<details>
  <summary>Before:</summary>
<img
src="https://github.com/bevyengine/bevy/assets/70668395/e67b592b-8001-42e3-a6ce-7d62ad59bf81"
/>
</details>

<details>
  <summary>After:</summary>
<img
src="https://github.com/bevyengine/bevy/assets/70668395/e9194784-ee4a-4848-87c2-0eb54e05236c"
/>
</details>

## Solution
Change the coordinate from 0.25 to 0.2.
2024-04-01 20:00:45 +00:00
BD103
84363f2fab
Remove redundant imports (#12817)
# Objective

- There are several redundant imports in the tests and examples that are
not caught by CI because additional flags need to be passed.

## Solution

- Run `cargo check --workspace --tests` and `cargo check --workspace
--examples`, then fix all warnings.
- Add `test-check` to CI, which will be run in the check-compiles job.
This should catch future warnings for tests. Examples are already
checked, but I'm not yet sure why they weren't caught.

## Discussion

- Should the `--tests` and `--examples` flags be added to CI, so this is
caught in the future?
- If so, #12818 will need to be merged first. It was also a warning
raised by checking the examples, but I chose to split off into a
separate PR.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
2024-04-01 19:59:08 +00:00
François Mockers
93fd02e8ea
remove DeterministicRenderingConfig (#12811)
# Objective

- Since #12453, `DeterministicRenderingConfig` doesn't do anything

## Solution

- Remove it

---

## Migration Guide

- Removed `DeterministicRenderingConfig`. There shouldn't be any z
fighting anymore in the rendering even without setting
`stable_sort_z_fighting`
2024-04-01 09:32:47 +00:00
andristarr
d39ab55b61
Adding explanation to seeded rng used in examples (#12593)
# Objective

- Fixes #12544

## Solution

- Added/updated a universally worded comment to all seeded rng instances
in our examples.
2024-03-26 19:40:18 +00:00
JMS55
4f20faaa43
Meshlet rendering (initial feature) (#10164)
# Objective
- Implements a more efficient, GPU-driven
(https://github.com/bevyengine/bevy/issues/1342) rendering pipeline
based on meshlets.
- Meshes are split into small clusters of triangles called meshlets,
each of which acts as a mini index buffer into the larger mesh data.
Meshlets can be compressed, streamed, culled, and batched much more
efficiently than monolithic meshes.


![image](https://github.com/bevyengine/bevy/assets/47158642/cb2aaad0-7a9a-4e14-93b0-15d4e895b26a)

![image](https://github.com/bevyengine/bevy/assets/47158642/7534035b-1eb7-4278-9b99-5322e4401715)

# Misc
* Future work: https://github.com/bevyengine/bevy/issues/11518
* Nanite reference:
https://advances.realtimerendering.com/s2021/Karis_Nanite_SIGGRAPH_Advances_2021_final.pdf
Two pass occlusion culling explained very well:
https://medium.com/@mil_kru/two-pass-occlusion-culling-4100edcad501

---------

Co-authored-by: Ricky Taylor <rickytaylor26@gmail.com>
Co-authored-by: vero <email@atlasdostal.com>
Co-authored-by: François <mockersf@gmail.com>
Co-authored-by: atlas dostal <rodol@rivalrebels.com>
2024-03-25 19:08:27 +00:00
Tim Leach
b09f3bdfe6
Switch to portable RNG in examples (#12644)
# Objective

Fixes issue #12613 - the RNG used in examples is _deterministic_, but
its implementation is not _portable_ across platforms. We want to switch
to using a portable RNG that does not vary across platforms, to ensure
certain examples play out the same way every time.

## Solution

Replace all occurences of `rand::rngs::StdRng` with
`rand_chacha::ChaCha8Rng`, as recommended in issue #12613

---

## Changelog

- Add `rand_chacha` as a new dependency (controversial?)
- Replace all occurences of `rand::rngs::StdRng` with
`rand_chacha::ChaCha8Rng`
2024-03-22 20:25:49 +00:00
oyasumi731
0950348916
Add hue traits (#12399)
# Objective

Fixes #12200 .

## Solution

I added a Hue Trait with the rotate_hue method to enable hue rotation.
Additionally, I modified the implementation of animations in the
animated_material sample.

---

## Changelog

- Added a  `Hue` trait to `bevy_color/src/color_ops.rs`.
- Added the `Hue` trait implementation to `Hsla`, `Hsva`, `Hwba`,
`Lcha`, and `Oklcha`.
- Updated animated_material sample.

## Migration Guide

Users of Oklcha need to change their usage to use the with_hue method
instead of the with_h method.

---------

Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-03-22 00:36:46 +00:00
Rob Parrett
3549ae9e37
Fix pink colors in examples (#12451)
# Objective

I was wondering why the `lighting` example was still looking quite
different lately (specifically, the intensity of the green light on the
cube) and noticed that we had one more color change I didn't catch
before.

Prior to the `bevy_color` port, `PINK` was actually "deep pink" from the
css4 spec.

`palettes::css::PINK` is now correctly a lighter pink color defined by
the same spec.

```rust
// Bevy 0.13
pub const PINK: Color = Color::rgb(1.0, 0.08, 0.58);
// Bevy 0.14-dev
pub const PINK: Srgba = Srgba::new(1.0, 0.753, 0.796, 1.0);
pub const DEEP_PINK: Srgba = Srgba::new(1.0, 0.078, 0.576, 1.0);
```

## Solution

Change usages of `css::PINK` to `DEEP_PINK` to restore the examples to
their former colors.
2024-03-18 17:44:46 +00:00
andristarr
432a4f1d85
Fix dim emissive values in lighting example (#12343)
# Objective

- Fixes #12330 

## Solution

- Increasing the emissive of the objects representing the lights.
2024-03-07 22:12:57 +00:00
Patrick Walton
dfdf2b9ea4
Implement the AnimationGraph, allowing for multiple animations to be blended together. (#11989)
This is an implementation of RFC #51:
https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md

Note that the implementation strategy is different from the one outlined
in that RFC, because two-phase animation has now landed.

# Objective

Bevy needs animation blending. The RFC for this is [RFC 51].

## Solution

This is an implementation of the RFC. Note that the implementation
strategy is different from the one outlined there, because two-phase
animation has now landed.

This is just a draft to get the conversation started. Currently we're
missing a few things:

- [x] A fully-fleshed-out mechanism for transitions
- [x] A serialization format for `AnimationGraph`s
- [x] Examples are broken, other than `animated_fox`
- [x] Documentation

---

## Changelog

### Added

* The `AnimationPlayer` has been reworked to support blending multiple
animations together through an `AnimationGraph`, and as such will no
longer function unless a `Handle<AnimationGraph>` has been added to the
entity containing the player. See [RFC 51] for more details.

* Transition functionality has moved from the `AnimationPlayer` to a new
component, `AnimationTransitions`, which works in tandem with the
`AnimationGraph`.

## Migration Guide

* `AnimationPlayer`s can no longer play animations by themselves and
need to be paired with a `Handle<AnimationGraph>`. Code that was using
`AnimationPlayer` to play animations will need to create an
`AnimationGraph` asset first, add a node for the clip (or clips) you
want to play, and then supply the index of that node to the
`AnimationPlayer`'s `play` method.

* The `AnimationPlayer::play_with_transition()` method has been removed
and replaced with the `AnimationTransitions` component. If you were
previously using `AnimationPlayer::play_with_transition()`, add all
animations that you were playing to the `AnimationGraph`, and create an
`AnimationTransitions` component to manage the blending between them.

[RFC 51]:
https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-03-07 20:22:42 +00:00
BD103
713d91b721
Improve Bloom 3D lighting (#11981)
# Objective

- With the recent lighting changes, the default configuration in the
`bloom_3d` example is less clear what bloom actually does
- See [this
screenshot](4fdb1455d5 (r1494648414))
for a comparison.
- `bloom_3d` additionally uses a for-loop to spawn the spheres, which
can be turned into `commands::spawn_batch` call.
- The text is black, which is difficult to see on the gray background.

## Solution

- Increase emmisive values of materials.
- Set text to white.

## Showcase

Before:

<img width="1392" alt="before"
src="https://github.com/bevyengine/bevy/assets/59022059/757057ad-ed9f-4eed-b135-8e2032fcdeb5">

After:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/3f9dc7a8-94b2-44b9-8ac3-deef1905221b">

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-03-07 15:20:38 +00:00
Rob Parrett
d56e16754c
Fix "dark grey" colors becoming lighter in various examples (#12333)
# Objective

Fixes #12226

Prior to the `bevy_color` port, `DARK GRAY` used to mean "dark grey."
But it is now lighter than `GRAY`, matching the css4 spec.

## Solution

Change usages of `css::DARK_GRAY` to `Color::srgb(0.25, 0.25, 0.25)` to
restore the examples to their former colors.

With one exception: `display_and_visibility`. I think the new color is
an improvement.

## Note

A lot of these examples could use nicer colors. I'm not trying to revamp
everything here.

The css4 palette is truly a horror. See #12176 and #12080 for some
discussion about alternatives.
2024-03-06 05:19:59 +00:00
Rob Parrett
0746b8eb4c
Fix green colors becoming darker in various examples (#12328)
# Objective

Fixes #12225

Prior to the `bevy_color` port, `GREEN` used to mean "full green." But
it is now a much darker color matching the css1 spec.

## Solution

Change usages of `basic::GREEN` or `css::GREEN` to `LIME` to restore the
examples to their former colors.

This also removes the duplicate definition of `GREEN` from `css`. (it
was already re-exported from `basic`)

## Note

A lot of these examples could use nicer colors. I'm not trying to do
that here.

"Dark Grey" will be tackled separately and has its own tracking issue.
2024-03-05 23:42:03 +00:00
François
faa2ce4d55
fix example lightmaps after color migration (#12265)
# Objective

- Since #12163 example lightmaps is more dull
<img width="1280" alt="Screenshot 2024-03-02 at 23 04 36"
src="https://github.com/bevyengine/bevy/assets/8672791/7736f420-b9c5-4870-93f6-b5b992c4768a">


## Solution

- Use a srgba color, as it was before:

b24ab2e9fb/examples/3d/lightmaps.rs (L39)

b24ab2e9fb/crates/bevy_render/src/color/mod.rs (L132)

<img width="1280" alt="Screenshot 2024-03-02 at 23 05 09"
src="https://github.com/bevyengine/bevy/assets/8672791/451187ed-8612-456f-ad25-180d5f774188">
2024-03-03 21:36:11 +00:00
Ben Frankel
e8ae0d6c49
Decouple BackgroundColor from UiImage (#11165)
# Objective

Fixes https://github.com/bevyengine/bevy/issues/11157.

## Solution

Stop using `BackgroundColor` as a color tint for `UiImage`. Add a
`UiImage::color` field for color tint instead. Allow a UI node to
simultaneously include a solid-color background and an image, with the
image rendered on top of the background (this is already how it works
for e.g. text).


![2024-02-29_1709239666_563x520](https://github.com/bevyengine/bevy/assets/12173779/ec50c9ef-4c7f-4ab8-a457-d086ce5b3425)

---

## Changelog

- The `BackgroundColor` component now renders a solid-color background
behind `UiImage` instead of tinting its color.
- Removed `BackgroundColor` from `ImageBundle`, `AtlasImageBundle`, and
`ButtonBundle`.
- Added `UiImage::color`.
- Expanded `RenderUiSystem` variants.
- Renamed `bevy_ui::extract_text_uinodes` to `extract_uinodes_text` for
consistency.

## Migration Guide

- `BackgroundColor` no longer tints the color of UI images. Use
`UiImage::color` for that instead.
- For solid color buttons, replace `ButtonBundle { background_color:
my_color.into(), ... }` with `ButtonBundle { image:
UiImage::default().with_color(my_color), ... }`, and update button
interaction systems to use `UiImage::color` instead of `BackgroundColor`
as well.
- `bevy_ui::RenderUiSystem::ExtractNode` has been split into
`ExtractBackgrounds`, `ExtractImages`, `ExtractBorders`, and
`ExtractText`.
- `bevy_ui::extract_uinodes` has been split into
`bevy_ui::extract_uinode_background_colors` and
`bevy_ui::extract_uinode_images`.
- `bevy_ui::extract_text_uinodes` has been renamed to
`extract_uinode_text`.
2024-03-03 21:35:50 +00:00
Natalie Soltis
cc32610543
Add size and physical_size to window (#12238)
This is an implementation within `bevy_window::window` that fixes
#12229.

# Objective

Fixes #12229, allow users to retrieve the window's size and physical
size as Vectors without having to manually construct them using
`height()` and `width()` or `physical_height()` and `physical_width()`

## Solution

As suggested in #12229, created two public functions within `window`:
`size() -> Vec` and `physical_size() -> UVec` that return the needed
Vectors ready-to-go.

### Discussion

My first FOSS PRQ ever, so bear with me a bit. I'm new to this.

- I replaced instances of ```Vec2::new(window.width(),
window.height());``` or `UVec2::new(window.physical_width(),
window.physical_height());` within bevy examples be replaced with their
`size()`/`physical_size()` counterparts?
- Discussion within #12229 still holds: should these also be added to
WindowResolution?
2024-03-01 22:28:37 +00:00
Patrick Walton
f9cc91d5a1
Intern mesh vertex buffer layouts so that we don't have to compare them over and over. (#12216)
Although we cached hashes of `MeshVertexBufferLayout`, we were paying
the cost of `PartialEq` on `InnerMeshVertexBufferLayout` for every
entity, every frame. This patch changes that logic to place
`MeshVertexBufferLayout`s in `Arc`s so that they can be compared and
hashed by pointer. This results in a 28% speedup in the
`queue_material_meshes` phase of `many_cubes`, with frustum culling
disabled.

Additionally, this patch contains two minor changes:

1. This commit flattens the specialized mesh pipeline cache to one level
of hash tables instead of two. This saves a hash lookup.

2. The example `many_cubes` has been given a `--no-frustum-culling`
flag, to aid in benchmarking.

See the Tracy profile:

<img width="1064" alt="Screenshot 2024-02-29 144406"
src="https://github.com/bevyengine/bevy/assets/157897/18632f1d-1fdd-4ac7-90ed-2d10306b2a1e">

## Migration guide

* Duplicate `MeshVertexBufferLayout`s are now combined into a single
object, `MeshVertexBufferLayoutRef`, which contains an
atomically-reference-counted pointer to the layout. Code that was using
`MeshVertexBufferLayout` may need to be updated to use
`MeshVertexBufferLayoutRef` instead.
2024-03-01 20:56:21 +00:00
Alice Cecile
599e5e4e76
Migrate from LegacyColor to bevy_color::Color (#12163)
# Objective

- As part of the migration process we need to a) see the end effect of
the migration on user ergonomics b) check for serious perf regressions
c) actually migrate the code
- To accomplish this, I'm going to attempt to migrate all of the
remaining user-facing usages of `LegacyColor` in one PR, being careful
to keep a clean commit history.
- Fixes #12056.

## Solution

I've chosen to use the polymorphic `Color` type as our standard
user-facing API.

- [x] Migrate `bevy_gizmos`.
- [x] Take `impl Into<Color>` in all `bevy_gizmos` APIs
- [x] Migrate sprites
- [x] Migrate UI
- [x] Migrate `ColorMaterial`
- [x] Migrate `MaterialMesh2D`
- [x] Migrate fog
- [x] Migrate lights
- [x] Migrate StandardMaterial
- [x] Migrate wireframes
- [x] Migrate clear color
- [x] Migrate text
- [x] Migrate gltf loader
- [x] Register color types for reflection
- [x] Remove `LegacyColor`
- [x] Make sure CI passes

Incidental improvements to ease migration:

- added `Color::srgba_u8`, `Color::srgba_from_array` and friends
- added `set_alpha`, `is_fully_transparent` and `is_fully_opaque` to the
`Alpha` trait
- add and immediately deprecate (lol) `Color::rgb` and friends in favor
of more explicit and consistent `Color::srgb`
- standardized on white and black for most example text colors
- added vector field traits to `LinearRgba`: ~~`Add`, `Sub`,
`AddAssign`, `SubAssign`,~~ `Mul<f32>` and `Div<f32>`. Multiplications
and divisions do not scale alpha. `Add` and `Sub` have been cut from
this PR.
- added `LinearRgba` and `Srgba` `RED/GREEN/BLUE`
- added `LinearRgba_to_f32_array` and `LinearRgba::to_u32`

## Migration Guide

Bevy's color types have changed! Wherever you used a
`bevy::render::Color`, a `bevy::color::Color` is used instead.

These are quite similar! Both are enums storing a color in a specific
color space (or to be more precise, using a specific color model).
However, each of the different color models now has its own type.

TODO...

- `Color::rgba`, `Color::rgb`, `Color::rbga_u8`, `Color::rgb_u8`,
`Color::rgb_from_array` are now `Color::srgba`, `Color::srgb`,
`Color::srgba_u8`, `Color::srgb_u8` and `Color::srgb_from_array`.
- `Color::set_a` and `Color::a` is now `Color::set_alpha` and
`Color::alpha`. These are part of the `Alpha` trait in `bevy_color`.
- `Color::is_fully_transparent` is now part of the `Alpha` trait in
`bevy_color`
- `Color::r`, `Color::set_r`, `Color::with_r` and the equivalents for
`g`, `b` `h`, `s` and `l` have been removed due to causing silent
relatively expensive conversions. Convert your `Color` into the desired
color space, perform your operations there, and then convert it back
into a polymorphic `Color` enum.
- `Color::hex` is now `Srgba::hex`. Call `.into` or construct a
`Color::Srgba` variant manually to convert it.
- `WireframeMaterial`, `ExtractedUiNode`, `ExtractedDirectionalLight`,
`ExtractedPointLight`, `ExtractedSpotLight` and `ExtractedSprite` now
store a `LinearRgba`, rather than a polymorphic `Color`
- `Color::rgb_linear` and `Color::rgba_linear` are now
`Color::linear_rgb` and `Color::linear_rgba`
- The various CSS color constants are no longer stored directly on
`Color`. Instead, they're defined in the `Srgba` color space, and
accessed via `bevy::color::palettes::css`. Call `.into()` on them to
convert them into a `Color` for quick debugging use, and consider using
the much prettier `tailwind` palette for prototyping.
- The `LIME_GREEN` color has been renamed to `LIMEGREEN` to comply with
the standard naming.
- Vector field arithmetic operations on `Color` (add, subtract, multiply
and divide by a f32) have been removed. Instead, convert your colors
into `LinearRgba` space, and perform your operations explicitly there.
This is particularly relevant when working with emissive or HDR colors,
whose color channel values are routinely outside of the ordinary 0 to 1
range.
- `Color::as_linear_rgba_f32` has been removed. Call
`LinearRgba::to_f32_array` instead, converting if needed.
- `Color::as_linear_rgba_u32` has been removed. Call
`LinearRgba::to_u32` instead, converting if needed.
- Several other color conversion methods to transform LCH or HSL colors
into float arrays or `Vec` types have been removed. Please reimplement
these externally or open a PR to re-add them if you found them
particularly useful.
- Various methods on `Color` such as `rgb` or `hsl` to convert the color
into a specific color space have been removed. Convert into
`LinearRgba`, then to the color space of your choice.
- Various implicitly-converting color value methods on `Color` such as
`r`, `g`, `b` or `h` have been removed. Please convert it into the color
space of your choice, then check these properties.
- `Color` no longer implements `AsBindGroup`. Store a `LinearRgba`
internally instead to avoid conversion costs.

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Afonso Lage <lage.afonso@gmail.com>
Co-authored-by: Rob Parrett <robparrett@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-02-29 19:35:12 +00:00
Joona Aalto
f418de8eb6
Rename Direction2d/3d to Dir2/3 (#12189)
# Objective

Split up from #12017, rename Bevy's direction types.

Currently, Bevy has the `Direction2d`, `Direction3d`, and `Direction3dA`
types, which provide a type-level guarantee that their contained vectors
remain normalized. They can be very useful for a lot of APIs for safety,
explicitness, and in some cases performance, as they can sometimes avoid
unnecessary normalizations.

However, many consider them to be inconvenient to use, and opt for
standard vector types like `Vec3` because of this. One reason is that
the direction type names are a bit long and can be annoying to write (of
course you can use autocomplete, but just typing `Vec3` is still nicer),
and in some intances, the extra characters can make formatting worse.
The naming is also inconsistent with Glam's shorter type names, and
results in names like `Direction3dA`, which (in my opinion) are
difficult to read and even a bit ugly.

This PR proposes renaming the types to `Dir2`, `Dir3`, and `Dir3A`.
These names are nice and easy to write, consistent with Glam, and work
well for variants like the SIMD aligned `Dir3A`. As a bonus, it can also
result in nicer formatting in a lot of cases, which can be seen from the
diff of this PR.

Some examples of what it looks like: (copied from #12017)

```rust
// Before
let ray_cast = RayCast2d::new(Vec2::ZERO, Direction2d::X, 5.0);

// After
let ray_cast = RayCast2d::new(Vec2::ZERO, Dir2::X, 5.0);
```

```rust
// Before (an example using Bevy XPBD)
let hit = spatial_query.cast_ray(
    Vec3::ZERO,
    Direction3d::X,
    f32::MAX,
    true,
    SpatialQueryFilter::default(),
);

// After
let hit = spatial_query.cast_ray(
    Vec3::ZERO,
    Dir3::X,
    f32::MAX,
    true,
    SpatialQueryFilter::default(),
);
```

```rust
// Before
self.circle(
    Vec3::new(0.0, -2.0, 0.0),
    Direction3d::Y,
    5.0,
    Color::TURQUOISE,
);

// After (formatting is collapsed in this case)
self.circle(Vec3::new(0.0, -2.0, 0.0), Dir3::Y, 5.0, Color::TURQUOISE);
```

## Solution

Rename `Direction2d`, `Direction3d`, and `Direction3dA` to `Dir2`,
`Dir3`, and `Dir3A`.

---

## Migration Guide

The `Direction2d` and `Direction3d` types have been renamed to `Dir2`
and `Dir3`.

## Additional Context

This has been brought up on the Discord a few times, and we had a small
[poll](https://discord.com/channels/691052431525675048/1203087353850364004/1212465038711984158)
on this. `Dir2`/`Dir3`/`Dir3A` was quite unanimously chosen as the best
option, but of course it was a very small poll and inconclusive, so
other opinions are certainly welcome too.

---------

Co-authored-by: IceSentry <c.giguere42@gmail.com>
2024-02-28 22:48:43 +00:00
Nicola Papale
f7f7e326e5
Add methods to directly load assets from World (#12023)
# Objective

`FromWorld` is often used to group loading and creation of assets for
resources.

With this setup, users often end up repetitively calling
`.resource::<AssetServer>` and `.resource_mut::<Assets<T>>`, and may
have difficulties handling lifetimes of the returned references.

## Solution

Add extension methods to `World` to add and load assets, through a new
extension trait defined in `bevy_asset`.

### Other considerations

* This might be a bit too "magic", as it makes implicit the resource
access.
* We could also implement `DirectAssetAccessExt` on `App`, but it didn't
feel necessary, as `FromWorld` is the principal use-case here.

---

## Changelog

* Add the `DirectAssetAccessExt` trait, which adds the `add_asset`,
`load_asset` and `load_asset_with_settings` method to the `World` type.
2024-02-27 00:28:26 +00:00
BD103
b96193e6ca
Improve lighting in more examples (#12021)
# Objective

- #11868 changed the lighting system, forcing lights to increase their
intensity. The PR fixed most examples, but missed a few. These I later
caught in https://github.com/bevyengine/bevy-website/pull/1023.
- Related: #11982, #11981.
- While there, I noticed that the spotlight example could use a few easy
improvements.

## Solution

- Increase lighting in `skybox`, `spotlight`, `animated_transform`, and
`gltf_skinned_mesh`.
- Improve spotlight example.
- Make ground plane move with cubes, so they don't phase into each
other.
  - Batch spawn cubes.
  - Add controls text.
  - Change controls to allow rotating around spotlights.

## Showcase

### Skybox

Before:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/8ba00d74-6d68-4414-97a8-28afb8305570">

After:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/ad15c471-6979-4dda-9889-9189136d8404">

### Spotlight

Before:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/53f966de-acf3-46b8-8299-0005c4cb8da0">

After:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/05c73c1e-0739-4226-83d6-e4249a9105e0">

### Animated Transform

Before:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/6d7d4ea0-e22e-42a5-9905-ea1731d474cf">

After:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/f1ee08d6-d17a-4391-91a6-d903b9fbdc3c">

### gLTF Skinned Mesh

Before:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/547569a6-d13b-4fe0-a8c1-e11f02c4f9a2">

After:

<img width="1392" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/34517aba-09e4-4e9b-982a-a4a8b893c48a">

---

## Changelog

- Increased lighting in `skybox`, `spotlight`, `animated_transform`, and
`gltf_skinned_mesh` examples.
- Improved usability of `spotlight` example.
2024-02-26 17:32:23 +00:00
Joona Aalto
9bd6cc0a5e
Add Direction3dA and move direction types out of primitives (#12018)
# Objective

Split up from #12017, add an aligned version of `Direction3d` for SIMD,
and move direction types out of `primitives`.

## Solution

Add `Direction3dA` and move direction types into a new `direction`
module.

---

## Migration Guide

The `Direction2d`, `Direction3d`, and `InvalidDirectionError` types have
been moved out of `bevy::math::primitives`.

Before:

```rust
use bevy::math::primitives::Direction3d;
```

After:

```rust
use bevy::math::Direction3d;
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-02-26 13:57:49 +00:00
BD103
ff29c43916
Increase 3D Lighting example's light intensity (#11982)
# Objective

- The 3D Lighting example is meant to show using multiple lights in the
same scene.
- It currently looks very dark. (See [this
image](4fdb1455d5 (r1494653511)).)
- Resetting the physical camera properties sets the shutter speed to 1 /
125, even though it initially starts at 1 / 100.

## Solution

- Increase the intensity of all 3 lights in the example.
  - Now it is much closer to the example in Bevy 0.12.
- I had to remove the comment explaining the lightbulb equivalent of the
intensities because I don't know how it was calculated. Does anyone know
what light emits 100,000 lumens?
- Set the initial shutter speed to 1 / 125.

## Showcase

Before:

<img width="1392" alt="before"
src="https://github.com/bevyengine/bevy/assets/59022059/ac353e02-58e9-4661-aa6d-e5fdf0dcd2f6">

After:

<img width="1392" alt="after"
src="https://github.com/bevyengine/bevy/assets/59022059/4ff0beb6-0ced-4fb2-a953-04be2c77f437">

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-02-25 19:18:56 +00:00
Alice Cecile
de004da8d5
Rename bevy_render::Color to LegacyColor (#12069)
# Objective

The migration process for `bevy_color` (#12013) will be fairly involved:
there will be hundreds of affected files, and a large number of APIs.

## Solution

To allow us to proceed granularly, we're going to keep both
`bevy_color::Color` (new) and `bevy_render::Color` (old) around until
the migration is complete.

However, simply doing this directly is confusing! They're both called
`Color`, making it very hard to tell when a portion of the code has been
ported.

As discussed in #12056, by renaming the old `Color` type, we can make it
easier to gradually migrate over, one API at a time.

## Migration Guide

THIS MIGRATION GUIDE INTENTIONALLY LEFT BLANK.

This change should not be shipped to end users: delete this section in
the final migration guide!

---------

Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
2024-02-24 21:35:32 +00:00
François
dc696c0e11
make reflection probe example frame rate independent (#12065)
# Objective

- Example reflection_probe is not frame rate independent

## Solution

- Use time delta to rotate the camera, use the same rotation speed as
the load_gltf example
31d7fcd9cb/examples/3d/load_gltf.rs (L63)

---
2024-02-24 06:02:12 +00:00
Evgeny Kropotin
d3e839a8e5
Move gizmos examples in the separate folder (#11916)
# Objective

Move Gizmo examples into the separate directory

Fixes #11899

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-02-21 20:16:25 +00:00
Jerome Humbert
5a74ff6f5e
Update split_screen example with 4 cameras (#12010)
# Objective

Improve `split_screen` example to use 4 cameras.

This serves as a visual regression test for #12006.

## Solution

With the fix of #11968:


![image](https://github.com/bevyengine/bevy/assets/6532395/57e9e013-7d23-429f-98ac-c6542d6b4bea)

Without (current `main`):


![image](https://github.com/bevyengine/bevy/assets/6532395/0b2a88a4-97f8-408d-8a0e-ce917efc668d)
2024-02-20 22:15:44 +00:00
Carter Anderson
8127d44daa
Irradiance volume example tweaks (#11911)
# Objective

Fixes two small quality issues:

1. With the new default ev100 exposure value, the irradiance intensity
was too low
2. The camera was rotating at a fixed speed (instead of a speed
multiplied by delta time), resulting in frame-rate dependent rotation
speed.
2024-02-17 01:24:50 +00:00
Rob Parrett
ebaa347afe
Add configuration for async pipeline creation on RenderPlugin (#11847)
# Objective

Fixes #11846

## Solution

Add a `synchronous_pipeline_compilation ` field to `RenderPlugin`,
defaulting to `false`.

Most of the diff is whitespace.

## Changelog

Added `synchronous_pipeline_compilation ` to `RenderPlugin` for
disabling async pipeline creation.

## Migration Guide

TODO: consider combining this with the guide for #11846

`RenderPlugin` has a new `synchronous_pipeline_compilation ` property.
The default value is `false`. Set this to `true` if you want to retain
the previous synchronous behavior.

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Co-authored-by: François <mockersf@gmail.com>
2024-02-16 13:35:47 +00:00
Carter Anderson
dd619a1087
New Exposure and Lighting Defaults (and calibrate examples) (#11868)
# Objective

After adding configurable exposure, we set the default ev100 value to
`7` (indoor). This brought us out of sync with Blender's configuration
and defaults. This PR changes the default to `9.7` (bright indoor or
very overcast outdoors), as I calibrated in #11577. This feels like a
very reasonable default.

The other changes generally center around tweaking Bevy's lighting
defaults and examples to play nicely with this number, alongside a few
other tweaks and improvements.

Note that for artistic reasons I have reverted some examples, which
changed to directional lights in #11581, back to point lights.
 
Fixes #11577 

---

## Changelog

- Changed `Exposure::ev100` from `7` to `9.7` to better match Blender
- Renamed `ExposureSettings` to `Exposure`
- `Camera3dBundle` now includes `Exposure` for discoverability
- Bumped `FULL_DAYLIGHT ` and `DIRECT_SUNLIGHT` to represent the
middle-to-top of those ranges instead of near the bottom
- Added new `AMBIENT_DAYLIGHT` constant and set that as the new
`DirectionalLight` default illuminance.
- `PointLight` and `SpotLight` now have a default `intensity` of
1,000,000 lumens. This makes them actually useful in the context of the
new "semi-outdoor" exposure and puts them in the "cinema lighting"
category instead of the "common household light" category. They are also
reasonably close to the Blender default.
- `AmbientLight` default has been bumped from `20` to `80`.

## Migration Guide

- The increased `Exposure::ev100` means that all existing 3D lighting
will need to be adjusted to match (DirectionalLights, PointLights,
SpotLights, EnvironmentMapLights, etc). Or alternatively, you can adjust
the `Exposure::ev100` on your cameras to work nicely with your current
lighting values. If you are currently relying on default intensity
values, you might need to change the intensity to achieve the same
effect. Note that in Bevy 0.12, point/spot lights had a different hard
coded ev100 value than directional lights. In Bevy 0.13, they use the
same ev100, so if you have both in your scene, the _scale_ between these
light types has changed and you will likely need to adjust one or both
of them.
2024-02-15 20:42:48 +00:00
Doonv
dc9b486650
Change light defaults & fix light examples (#11581)
# Objective

Fix https://github.com/bevyengine/bevy/issues/11577.

## Solution

Fix the examples, add a few constants to make setting light values
easier, and change the default lighting settings to be more realistic.
(Now designed for an overcast day instead of an indoor environment)

---

I did not include any example-related changes in here.

## Changelogs (not including breaking changes)

### bevy_pbr

- Added `light_consts` module (included in prelude), which contains
common lux and lumen values for lights.
- Added `AmbientLight::NONE` constant, which is an ambient light with a
brightness of 0.
- Added non-EV100 variants for `ExposureSettings`'s EV100 constants,
which allow easier construction of an `ExposureSettings` from a EV100
constant.

## Breaking changes

### bevy_pbr

The several default lighting values were changed:

- `PointLight`'s default `intensity` is now `2000.0`
- `SpotLight`'s default `intensity` is now `2000.0`
- `DirectionalLight`'s default `illuminance` is now
`light_consts::lux::OVERCAST_DAY` (`1000.`)
- `AmbientLight`'s default `brightness` is now `20.0`
2024-02-14 20:43:10 +00:00
Robert Walter
b446374392
Dedicated primitive example (#11697)
I just implemented this to record a video for the new blog post, but I
figured it would also make a good dedicated example. This also allows us
to remove a lot of code from the 2d/3d gizmo examples since it
supersedes this portion of code.

Depends on: https://github.com/bevyengine/bevy/pull/11699
2024-02-14 16:55:44 +00:00
Joona Aalto
0166db33f7
Deprecate shapes in bevy_render::mesh::shape (#11773)
# Objective

#11431 and #11688 implemented meshing support for Bevy's new geometric
primitives. The next step is to deprecate the shapes in
`bevy_render::mesh::shape` and to later remove them completely for 0.14.

## Solution

Deprecate the shapes and reduce code duplication by utilizing the
primitive meshing API for the old shapes where possible.

Note that some shapes have behavior that can't be exactly reproduced
with the new primitives yet:

- `Box` is more of an AABB with min/max extents
- `Plane` supports a subdivision count
- `Quad` has a `flipped` property

These types have not been changed to utilize the new primitives yet.

---

## Changelog

- Deprecated all shapes in `bevy_render::mesh::shape`
- Changed all examples to use new primitives for meshing

## Migration Guide

Bevy has previously used rendering-specific types like `UVSphere` and
`Quad` for primitive mesh shapes. These have now been deprecated to use
the geometric primitives newly introduced in version 0.13.

Some examples:

```rust
let before = meshes.add(shape::Box::new(5.0, 0.15, 5.0));
let after = meshes.add(Cuboid::new(5.0, 0.15, 5.0));

let before = meshes.add(shape::Quad::default());
let after = meshes.add(Rectangle::default());

let before = meshes.add(shape::Plane::from_size(5.0));
// The surface normal can now also be specified when using `new`
let after = meshes.add(Plane3d::default().mesh().size(5.0, 5.0));

let before = meshes.add(
    Mesh::try_from(shape::Icosphere {
        radius: 0.5,
        subdivisions: 5,
    })
    .unwrap(),
);
let after = meshes.add(Sphere::new(0.5).mesh().ico(5).unwrap());
```
2024-02-08 18:01:34 +00:00
Lynn
4c86ad6aed
Mesh insert indices (#11745)
# Objective

- Fixes #11740 

## Solution

- Turned `Mesh::set_indices` into `Mesh::insert_indices` and added
related methods for completeness.

---

## Changelog

- Replaced `Mesh::set_indices(indices: Option<Indices>)` with
`Mesh::insert_indices(indices: Indices)`
- Replaced `Mesh::with_indices(indices: Option<Indices>)` with
`Mesh::with_inserted_indices(indices: Indices)` and
`Mesh::with_removed_indices()` mirroring the API for inserting /
removing attributes.
- Updated the examples and internal uses of the APIs described above.

## Migration Guide

- Use `Mesh::insert_indices` or `Mesh::with_inserted_indices` instead of
`Mesh::set_indices` / `Mesh::with_indices`.
- If you have passed `None` to `Mesh::set_indices` or
`Mesh::with_indices` you should use `Mesh::remove_indices` or
`Mesh::with_removed_indices` instead.

---------

Co-authored-by: François <mockersf@gmail.com>
2024-02-06 23:31:48 +00:00
Patrick Walton
4c15dd0fc5
Implement irradiance volumes. (#10268)
# Objective

Bevy could benefit from *irradiance volumes*, also known as *voxel
global illumination* or simply as light probes (though this term is not
preferred, as multiple techniques can be called light probes).
Irradiance volumes are a form of baked global illumination; they work by
sampling the light at the centers of each voxel within a cuboid. At
runtime, the voxels surrounding the fragment center are sampled and
interpolated to produce indirect diffuse illumination.

## Solution

This is divided into two sections. The first is copied and pasted from
the irradiance volume module documentation and describes the technique.
The second part consists of notes on the implementation.

### Overview

An *irradiance volume* is a cuboid voxel region consisting of
regularly-spaced precomputed samples of diffuse indirect light. They're
ideal if you have a dynamic object such as a character that can move
about
static non-moving geometry such as a level in a game, and you want that
dynamic object to be affected by the light bouncing off that static
geometry.

To use irradiance volumes, you need to precompute, or *bake*, the
indirect
light in your scene. Bevy doesn't currently come with a way to do this.
Fortunately, [Blender] provides a [baking tool] as part of the Eevee
renderer, and its irradiance volumes are compatible with those used by
Bevy.
The [`bevy-baked-gi`] project provides a tool, `export-blender-gi`, that
can
extract the baked irradiance volumes from the Blender `.blend` file and
package them up into a `.ktx2` texture for use by the engine. See the
documentation in the `bevy-baked-gi` project for more details as to this
workflow.

Like all light probes in Bevy, irradiance volumes are 1×1×1 cubes that
can
be arbitrarily scaled, rotated, and positioned in a scene with the
[`bevy_transform::components::Transform`] component. The 3D voxel grid
will
be stretched to fill the interior of the cube, and the illumination from
the
irradiance volume will apply to all fragments within that bounding
region.

Bevy's irradiance volumes are based on Valve's [*ambient cubes*] as used
in
*Half-Life 2* ([Mitchell 2006], slide 27). These encode a single color
of
light from the six 3D cardinal directions and blend the sides together
according to the surface normal.

The primary reason for choosing ambient cubes is to match Blender, so
that
its Eevee renderer can be used for baking. However, they also have some
advantages over the common second-order spherical harmonics approach:
ambient cubes don't suffer from ringing artifacts, they are smaller (6
colors for ambient cubes as opposed to 9 for spherical harmonics), and
evaluation is faster. A smaller basis allows for a denser grid of voxels
with the same storage requirements.

If you wish to use a tool other than `export-blender-gi` to produce the
irradiance volumes, you'll need to pack the irradiance volumes in the
following format. The irradiance volume of resolution *(Rx, Ry, Rz)* is
expected to be a 3D texture of dimensions *(Rx, 2Ry, 3Rz)*. The
unnormalized
texture coordinate *(s, t, p)* of the voxel at coordinate *(x, y, z)*
with
side *S* ∈ *{-X, +X, -Y, +Y, -Z, +Z}* is as follows:

```text
s = x

t = y + ⎰  0 if S ∈ {-X, -Y, -Z}
        ⎱ Ry if S ∈ {+X, +Y, +Z}

        ⎧   0 if S ∈ {-X, +X}
p = z + ⎨  Rz if S ∈ {-Y, +Y}
        ⎩ 2Rz if S ∈ {-Z, +Z}
```

Visually, in a left-handed coordinate system with Y up, viewed from the
right, the 3D texture looks like a stacked series of voxel grids, one
for
each cube side, in this order:

| **+X** | **+Y** | **+Z** |
| ------ | ------ | ------ |
| **-X** | **-Y** | **-Z** |

A terminology note: Other engines may refer to irradiance volumes as
*voxel
global illumination*, *VXGI*, or simply as *light probes*. Sometimes
*light
probe* refers to what Bevy calls a reflection probe. In Bevy, *light
probe*
is a generic term that encompasses all cuboid bounding regions that
capture
indirect illumination, whether based on voxels or not.

Note that, if binding arrays aren't supported (e.g. on WebGPU or WebGL
2),
then only the closest irradiance volume to the view will be taken into
account during rendering.

[*ambient cubes*]:
https://advances.realtimerendering.com/s2006/Mitchell-ShadingInValvesSourceEngine.pdf

[Mitchell 2006]:
https://advances.realtimerendering.com/s2006/Mitchell-ShadingInValvesSourceEngine.pdf

[Blender]: http://blender.org/

[baking tool]:
https://docs.blender.org/manual/en/latest/render/eevee/render_settings/indirect_lighting.html

[`bevy-baked-gi`]: https://github.com/pcwalton/bevy-baked-gi

### Implementation notes

This patch generalizes light probes so as to reuse as much code as
possible between irradiance volumes and the existing reflection probes.
This approach was chosen because both techniques share numerous
similarities:

1. Both irradiance volumes and reflection probes are cuboid bounding
regions.
2. Both are responsible for providing baked indirect light.
3. Both techniques involve presenting a variable number of textures to
the shader from which indirect light is sampled. (In the current
implementation, this uses binding arrays.)
4. Both irradiance volumes and reflection probes require gathering and
sorting probes by distance on CPU.
5. Both techniques require the GPU to search through a list of bounding
regions.
6. Both will eventually want to have falloff so that we can smoothly
blend as objects enter and exit the probes' influence ranges. (This is
not implemented yet to keep this patch relatively small and reviewable.)

To do this, we generalize most of the methods in the reflection probes
patch #11366 to be generic over a trait, `LightProbeComponent`. This
trait is implemented by both `EnvironmentMapLight` (for reflection
probes) and `IrradianceVolume` (for irradiance volumes). Using a trait
will allow us to add more types of light probes in the future. In
particular, I highly suspect we will want real-time reflection planes
for mirrors in the future, which can be easily slotted into this
framework.

## Changelog

> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.

### Added
* A new `IrradianceVolume` asset type is available for baked voxelized
light probes. You can bake the global illumination using Blender or
another tool of your choice and use it in Bevy to apply indirect
illumination to dynamic objects.
2024-02-06 23:23:20 +00:00
Joona Aalto
cf15e6bba3
Implement Meshable for some 3D primitives (#11688)
# Objective

Split up from #11007, fixing most of the remaining work for #10569.

Implement `Meshable` for `Cuboid`, `Sphere`, `Cylinder`, `Capsule`,
`Torus`, and `Plane3d`. This covers all shapes that Bevy has mesh
structs for in `bevy_render::mesh::shapes`.

`Cone` and `ConicalFrustum` are new shapes, so I can add them in a
follow-up, or I could just add them here directly if that's preferrable.

## Solution

Implement `Meshable` for `Cuboid`, `Sphere`, `Cylinder`, `Capsule`,
`Torus`, and `Plane3d`.

The logic is mostly just a copy of the the existing `bevy_render`
shapes, but `Plane3d` has a configurable surface normal that affects the
orientation. Some property names have also been changed to be more
consistent.

The default values differ from the old shapes to make them a bit more
logical:

- Spheres now have a radius of 0.5 instead of 1.0. The default capsule
is equivalent to the default cylinder with the sphere's halves glued on.
- The inner and outer radius of the torus are now 0.5 and 1.0 instead of
0.5 and 1.5 (i.e. the new minor and major radii are 0.25 and 0.75). It's
double the width of the default cuboid, half of its height, and the
default sphere matches the size of the hole.
- `Cuboid` is 1x1x1 by default unlike the dreaded `Box` which is 2x1x1.

Before, with "old" shapes:


![old](https://github.com/bevyengine/bevy/assets/57632562/733f3dda-258c-4491-8152-9829e056a1a3)

Now, with primitive meshing:


![new](https://github.com/bevyengine/bevy/assets/57632562/5a1af14f-bb98-401d-82cf-de8072fea4ec)

I only changed the `3d_shapes` example to use primitives for now. I can
change them all in this PR or a follow-up though, whichever way is
preferrable.

### Sphere API

Spheres have had separate `Icosphere` and `UVSphere` structs, but with
primitives we only have one `Sphere`.

We need to handle this with builders:

```rust
// Existing structs
let ico = Mesh::try_from(Icophere::default()).unwrap();
let uv = Mesh::from(UVSphere::default());

// Primitives
let ico = Sphere::default().mesh().ico(5).unwrap();
let uv = Sphere::default().mesh().uv(32, 18);
```

We could add methods on `Sphere` directly to skip calling `.mesh()`.

I also added a `SphereKind` enum that can be used with the `kind`
method:

```rust
let ico = Sphere::default()
    .mesh()
    .kind(SphereKind::Ico { subdivisions: 8 })
    .build();
```

The default mesh for a `Sphere` is an icosphere with 5 subdivisions
(like the default `Icosphere`).

---

## Changelog

- Implement `Meshable` and `Default` for `Cuboid`, `Sphere`, `Cylinder`,
`Capsule`, `Torus`, and `Plane3d`
- Use primitives in `3d_shapes` example

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-02-06 21:44:13 +00:00
Tristan Guichaoua
694c06f3d0
Inverse missing_docs logic (#11676)
# Objective

Currently the `missing_docs` lint is allowed-by-default and enabled at
crate level when their documentations is complete (see #3492).
This PR proposes to inverse this logic by making `missing_docs`
warn-by-default and mark crates with imcomplete docs allowed.

## Solution

Makes `missing_docs` warn at workspace level and allowed at crate level
when the docs is imcomplete.
2024-02-03 21:40:55 +00:00
Robert Walter
041731b7e0
Drawing Primitives with Gizmos (#11072)
The PR is in a reviewable state now in the sense that the basic
implementations are there. There are still some ToDos that I'm aware of:

- [x] docs for all the new structs and traits
- [x] implement `Default` and derive other useful traits for the new
structs
- [x] Take a look at the notes again (Do this after a first round of
reviews)
- [x] Take care of the repetition in the circle drawing functions

---

# Objective

- TLDR: This PR enables us to quickly draw all the newly added
primitives from `bevy_math` in immediate mode with gizmos
- Addresses #10571

## Solution

- This implements the first design idea I had that covered everything
that was mentioned in the Issue
https://github.com/bevyengine/bevy/issues/10571#issuecomment-1863646197

--- 

## Caveats

- I added the `Primitive(2/3)d` impls for `Direction(2/3)d` to make them
work with the current solution. We could impose less strict requirements
for the gizmoable objects and remove the impls afterwards if the
community doesn't like the current approach.

---

## Changelog

- implement capabilities to draw ellipses on the gizmo in general (this
was required to have some code which is able to draw the ellipse
primitive)
- refactored circle drawing code to use the more general ellipse drawing
code to keep code duplication low
- implement `Primitive2d` for `Direction2d` and impl `Primitive3d` for
`Direction3d`
- implement trait to draw primitives with specialized details with
gizmos
  - `GizmoPrimitive2d` for all the 2D primitives
  - `GizmoPrimitive3d` for all the 3D primitives
- (question while writing this: Does it actually matter if we split this
in 2D and 3D? I guess it could be useful in the future if we do
something based on the main rendering mode even though atm it's kinda
useless)

---

---------

Co-authored-by: nothendev <borodinov.ilya@gmail.com>
2024-02-02 21:13:03 +00:00
Rose Hudson
d6f1649646
return Direction3d from Transform::up and friends (#11604)
# Objective
Drawing a `Gizmos::circle` whose normal is derived from a Transform's
local axes now requires converting a Vec3 to a Direction3d and
unwrapping the result, and I think we shold move the conversion into
Bevy.

## Solution
We can make
`Transform::{left,right,up,down,forward,back,local_x,local_y,local_z}`
return a Direction3d, because they know that their results will be of
finite non-zero length (roughly 1.0).

---

## Changelog
`Transform::up()` and similar functions now return `Direction3d` instead
of `Vec3`.

## Migration Guide
Callers of `Transform::up()` and similar functions may have to
dereference the returned `Direction3d` to get to the inner `Vec3`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-02-02 15:05:35 +00:00
Brian Reavis
6b40b6749e
RenderAssetPersistencePolicy → RenderAssetUsages (#11399)
# Objective

Right now, all assets in the main world get extracted and prepared in
the render world (if the asset's using the RenderAssetPlugin). This is
unfortunate for two cases:

1. **TextureAtlas** / **FontAtlas**: This one's huge. The individual
`Image` assets that make up the atlas are cloned and prepared
individually when there's no reason for them to be. The atlas textures
are built on the CPU in the main world. *There can be hundreds of images
that get prepared for rendering only not to be used.*
2. If one loads an Image and needs to transform it in a system before
rendering it, kind of like the [decompression
example](https://github.com/bevyengine/bevy/blob/main/examples/asset/asset_decompression.rs#L120),
there's a price paid for extracting & preparing the asset that's not
intended to be rendered yet.

------

* References #10520
* References #1782

## Solution

This changes the `RenderAssetPersistencePolicy` enum to bitflags. I felt
that the objective with the parameter is so similar in nature to wgpu's
[`TextureUsages`](https://docs.rs/wgpu/latest/wgpu/struct.TextureUsages.html)
and
[`BufferUsages`](https://docs.rs/wgpu/latest/wgpu/struct.BufferUsages.html),
that it may as well be just like that.

```rust
// This asset only needs to be in the main world. Don't extract and prepare it.
RenderAssetUsages::MAIN_WORLD

// Keep this asset in the main world and  
RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD

// This asset is only needed in the render world. Remove it from the asset server once extracted.
RenderAssetUsages::RENDER_WORLD
```

### Alternate Solution

I considered introducing a third field to `RenderAssetPersistencePolicy`
enum:
```rust
enum RenderAssetPersistencePolicy {
    /// Keep the asset in the main world after extracting to the render world.
    Keep,
    /// Remove the asset from the main world after extracting to the render world.
    Unload,
    /// This doesn't need to be in the render world at all.
    NoExtract, // <-----
}
```
Functional, but this seemed like shoehorning. Another option is renaming
the enum to something like:
```rust
enum RenderAssetExtractionPolicy {
    /// Extract the asset and keep it in the main world.
    Extract,
    /// Remove the asset from the main world after extracting to the render world.
    ExtractAndUnload,
    /// This doesn't need to be in the render world at all.
    NoExtract,
}
```
I think this last one could be a good option if the bitflags are too
clunky.

## Migration Guide

* `RenderAssetPersistencePolicy::Keep` → `RenderAssetUsage::MAIN_WORLD |
RenderAssetUsage::RENDER_WORLD` (or `RenderAssetUsage::default()`)
* `RenderAssetPersistencePolicy::Unload` →
`RenderAssetUsage::RENDER_WORLD`
* For types implementing the `RenderAsset` trait, change `fn
persistence_policy(&self) -> RenderAssetPersistencePolicy` to `fn
asset_usage(&self) -> RenderAssetUsages`.
* Change any references to `cpu_persistent_access`
(`RenderAssetPersistencePolicy`) to `asset_usage` (`RenderAssetUsage`).
This applies to `Image`, `Mesh`, and a few other types.
2024-01-30 13:22:10 +00:00
François
79a2e5eb63
simplify animated_material example (#11576)
# Objective

- example `animated_material` is more complex that needed to show how to
animate materials
- it makes CI crash because it uses too much memory

## Solution

- Simplify the example
2024-01-28 21:58:05 +00:00
Robert Walter
bcae8e9a8b
Implement Arc3D for Gizmos (#11540)
# Objective

- Implement an arc3d API for gizmos
- Solves #11536

## Solution

### `arc_3d`

- The current `arc3d` method on gizmos only takes an angle
- It draws an "standard arc" by default, this is an arc starting at
`Vec3::X`, in the XZ plane, in counter clockwise direction with a normal
that is facing up
- The "standard arc" can be customized with the usual gizmo builder
pattern. This way you'll be able to draw arbitrary arcs

### `short/long_arc_3d_between`

- Given `center`, `from`, `to` draws an arc between `from` and `to`

---

## Changelog

> This section is optional. If this was a trivial fix, or has no
externally-visible impact, you can delete this section.

- Added: `Gizmos::arc3d(&mut self, angle)` method
- Added: `Gizmos::long_arc_3d_between(&mut self, center, from, to)`
method
- Added: `Gizmos::short_arc_3d_between(&mut self, center, from, to)`
method

---

This PR factors out an orthogonal part of another PR as mentioned in
[this
comment](https://github.com/bevyengine/bevy/pull/11072#issuecomment-1883859573)
2024-01-28 02:13:17 +00:00
Rob Parrett
7da144bc3d
Refactor tonemapping example's image viewer update into two systems (#11519)
# Objective

Alternative to #11515.

Fixes change detection being triggered on the "image viewer image
material" every frame.

## Solution

- Split the megasystem into two separate systems: one to handle drop
events, and one to handle asset change events.
- Move the event reader iteration "outside." so that we're only doing
stuff when there are events.
- Flatten some of the more extreme nesting
- Other bits of cleanup, removing an unnecessary clone and unused
variable.

I think these systems can even run in parallel now, not that it
particularly matters.
2024-01-27 16:06:34 +00:00
vero
fb367dac72
Add Animated Material example (#11524)
# Objective

- Fixes #11516

## Solution

- Add Animated Material example (colors are hue-cycling smoothly
per-mesh)


![image](https://github.com/bevyengine/bevy/assets/11307157/c75b9e66-0019-41b8-85ec-647559c6ba01)

Note: this example reproduces the perf issue found in #10610 pretty
consistently, with and without the changes from that PR included. Frame
time is sometimes around 4.3ms, other times around 12-14ms. Its pretty
random per run. I think this clears #10610 for merge.
2024-01-26 13:34:46 +00:00
JMS55
a796d53a05
Meshlet prep (#11442)
# Objective

- Prep for https://github.com/bevyengine/bevy/pull/10164
- Make deferred_lighting_pass_id a ColorAttachment
- Correctly extract shadow view frusta so that the view uniforms get
populated
- Make some needed things public
- Misc formatting
2024-01-22 15:28:33 +00:00
Arthur Brussee
ffb6faafc2
Use Direction3d for gizmos.circle normal (#11422)
# Objective

Fix weird visuals when drawing a gizmo with a non-normed normal.

Fixes #11401

## Solution
Just normalize right before we draw. Could do it when constructing the
builder but that seems less consistent.

## Changelog
- gizmos.circle normal is now a Direction3d instead of a Vec3.

## Migration Guide
- Pass a Direction3d for gizmos.circle normal, eg.
`Direction3d::new(vec).unwrap_or(default)` or potentially
`Direction3d::new_unchecked(vec)` if you know your vec is definitely
normalized.
2024-01-21 18:03:26 +00:00