# Firefly 0.18.1 Release Notes
## HDR, Tonemapping, Msaa
Firefly is now fully compatible with HDR, Tonemapping and Msaa. This offers a lot more depth to lights.
Before, lights could have an intensity that goes up to 1. Now, intensity can be arbitrarily high.
| Intensity: 1 | Intensity: 3 |
| ------------- | ------------- |
| <img width="1600" height="900" alt="0eef4d05-4ea3-4596-a368-70029bace276" src="https://github.com/user-attachments/assets/baed4d85-f571-4bb6-8e27-a897e5477521" /> | <img width="1600" height="900" alt="c5973646-3104-4129-8152-675994de11fe" src="https://github.com/user-attachments/assets/63aecdd0-5d28-4656-838a-fb06ce81b37e" /> |
| <img width="1600" height="900" alt="76ce2ae2-ebd2-4188-9847-43f09651ad84" src="https://github.com/user-attachments/assets/fd2fac98-c6a0-4e7a-8158-459c67c7175d" /> | <img width="1600" height="900" alt="ad521f08-38cc-4980-a1e5-8a93c086bf16" src="https://github.com/user-attachments/assets/f730d745-8c29-43a0-a526-49d881180fda" /> |
Note that using HDR requires inserting the [`Hdr`](https://docs.rs/bevy/latest/bevy/render/view/struct.Hdr.html) Bevy component on the camera. Same for non-default Tonemapping and Msaa.
## Changes to Light Banding
Firefly previously allowed users to set a number of bands that the lightmap is divided into. This was no longer possible with HDR, since there wasn't a clear way to decide
how high color channels could be in order to divide them by a set number.
Instead, you now have an option to set the size of a light band. For instance, setting light bands to 0.3 will turn all values in the interval `[0-0.3]` to a single value, 1.5, all values in `[0.3-0.6]` to 4.5, and so on.
If you were setting the light bands to 4 before, you can now set them to 0.25 to achieve the same effect, but keep in mind that using HDR might create more than 4 channels if a light's intensity goes higher than 1, so you may need to adjust it accordingly.
| (Old) Light Bands: 4 | HDR: on, Light Bands: 0.25 | HDR: on, Light Bands: 0.7|
| ------------- | ------------- | ------------- |
| <img width="823" height="788" alt="image" src="https://github.com/user-attachments/assets/1d26537f-74b5-4744-a5f8-835a4828a355" /> | <img width="823" height="788" alt="image2" src="https://github.com/user-attachments/assets/0acafb8e-f47d-4a32-9b97-59d42caf59e9" /> | <img width="823" height="788" alt="image3" src="https://github.com/user-attachments/assets/a24f69e4-c3bd-4753-b1d8-9a149b787030" /> |
## New Gizmos
The `FireflyGimos` plugin will now also show gizmos for lights, and you can manually insert the `FireflyGizmoStyle` resource to alter the gizmo colors.
## Soft Shadows Changes
Soft shadows went through a soft-rework in which I fixed many visual artifacts and glitches that they were causing before.
The "softness" field on the config component has been replaced with a simple bool that toggles soft shadows on and off. The actual "softness"
of shadows is now purely based on the radius of the light's core.
## Point Light Changes
The main difference is that I've introduced the notion of "light core", which is an innermost area of the light that is usually lit up more than the rest of the light.
A core has 3 adjustable values: a radius, a boost value indicating how much higher its intensity will be than the normal intensity of the light, and a falloff.
```Rs
pub struct LightCore {
pub radius: f32,
pub boost: f32,
pub falloff: Falloff,
}
```
As mentioned above, the soft shadows are now based on the size of the core.
| LightCore { radius: 30.0, boost: 15.0} | LightCore { radius: 30.0, boost: 1.0} | LightCore { radius: 5.0, boost: 10.0 } | LightCore { radius: 100.0, boost: 50.0 } |
| ------------- | ------------- | ------------- | ------------- |
| <img width="1415" height="1009" alt="image" src="https://github.com/user-attachments/assets/bf96092a-1749-44f1-b83f-21acd6e9b7d7" /> | <img width="1415" height="1009" alt="image" src="https://github.com/user-attachments/assets/6c9136e4-c749-4a7e-b0d7-cbb9103fee76" /> | <img width="1415" height="1009" alt="image" src="https://github.com/user-attachments/assets/7d6af06f-e62b-4601-b81f-f3d8f8865a27" /> | <img width="1415" height="1009" alt="image" src="https://github.com/user-attachments/assets/3866e085-c164-464c-8477-09d952910083" /> |
Additionally, `range` has now been renamed to `radius`, and the angle `f32` has been removed in favor of a `LightAngle` struct which allows setting an inner and outer angle which are smoothly transitioned between (see the new [flashlight example](https://github.com/PVDoriginal/firefly/blob/main/examples/flashlight.rs) for a showcase on this).
```Rs
pub struct LightAngle {
pub inner: f32,
pub outer: f32,
}
```
Finally, the old `falloff_intensity` has been moved into the `Falloff` enum, and a new variant has been added for no falloff. Falloff calculations have also been slightly adjusted.
```Rs
pub enum Falloff {
InverseSquare { intensity: f32 },
Linear { intensity: f32 },
None,
}
```
| InverseSquare { 0.0 } | InverseSquare { 2.0 } | InverseSquare { -1.0 } | None |
| ------------- | ------------- | ------------- | ------------- |
| <img width="853" height="736" alt="image" src="https://github.com/user-attachments/assets/53b4c2ca-ba41-4db1-869e-14b2bfce1db4" /> | <img width="853" height="736" alt="image" src="https://github.com/user-attachments/assets/d4331be4-8dc5-49d0-be18-172b4099ba82" /> | <img width="853" height="736" alt="image" src="https://github.com/user-attachments/assets/6dbb087e-14cf-4dcc-8474-e95ae48e5c94" /> | <img width="853" height="736" alt="image" src="https://github.com/user-attachments/assets/200e77ea-99cf-41ee-a485-34fc48270977" /> |
(Note that all the same falloff options are also available when configuring the core)
## Normal Maps Changes
`NormalMode::TopDown` has been split into `NormalMode::TopDownZ` and `NormalMode::TopDownY`.
Previously, the "backwards / forwards" direction of the normal map was based purely on the z of the entities, however, this didn't work for games that use tighter-packed z coordinates
for their sprite sorting (e.g. if they also have sorting layers). In that case, they can set the normal mode to `TopDownY` which will base the coordinats on the y's of the entities instead.
Also, a new method has been added on the `NormalMap` struct to allow constructing it straight from an image handle (useful for when you're doing manual loading and tracking of loaded assets).
However, users should be careful to load this image with no gamma compression.
Valid use cases include:
Instant automatic loading:
```Rs
commands.spawn((
Sprite::from_image(asset_server.load("some_sprite.png")),
NormalMap::from_file("some_sprite_normal.png"),
));
```
Loading the image manually and storing the handle for later:
```Rs
let image: Handle<Image> = asset_server.load_with_settings("some_sprite_normal.png", |x: &mut ImageLoaderSettings| x.is_srgb = false);
commands.spawn((
Sprite::from_image(asset_server.load("some_sprite.png")),
NormalMap::from_image(image),
));
```
Loading th image automatically through the struct and storing the handle for later:
```Rs
let image = NormalMap::from_file("some_sprite_normal.png").handle();
commands.spawn((
Sprite::from_image(asset_server.load("some_sprite.png")),
NormalMap::from_image(image),
));
```
## New Examples
Added a new 'noise' example which shows how to grab the lightmap in a custom render pass and modify it by multiplying a noise over it.
<img width="830" height="573" alt="image" src="https://github.com/user-attachments/assets/348a4a9b-0611-4dc3-bc72-16525811bb78" />
Added a new 'blending' example showing the blending of two lights.
<img width="1089" height="715" alt="image" src="https://github.com/user-attachments/assets/ee80bf2f-081e-43a1-ac2b-fbc1c09a1cf3" />
Added a new 'flashlight' example showcasing rotating occluders and custom LightAngle values.
<img width="980" height="593" alt="image" src="https://github.com/user-attachments/assets/4aea182a-b771-4af9-b880-b3b0b30ceaf8" />
Also, a new spline-based shape was added to the [shapes example](https://github.com/PVDoriginal/firefly/blob/main/examples/shapes.rs), courtesy of [neomewo](https://github.com/neomewo).
<img width="328" height="397" alt="image" src="https://github.com/user-attachments/assets/fe980aaf-9959-4959-92ff-1e37843c63e3" />
## Serde
I've added a new `serde` feature flag which derives `Deserialize` and `Serialize` on important structs, such as `PointLight2d` and `Occluder2d`.
## Bugfixes
- Fixed a bug where despawned occluders would sometimes still block light.
- Fixed a bug that prevented Firefly from running on web.
- Fixed a bug that caused occluders to not be updated properly when parented to another entity.
- Replaced some unwraps() which could potentially cause a panic if something else in the app went wrong.