# Firefly 0.18.2 Release Notes
## Multiple Cameras & Render Layers
Firefly finally supports multiple cameras, each rendering a separate lightmap.
With this comes, also, the ability to put each Light or Occluder on different `RenderLayers`, creating Occluders that only block certain Lights, and Lights that are only rendered to specific cameras.
Here's the new `render_layers` examples:
<img width="1792" height="1018" alt="image" src="https://github.com/user-attachments/assets/3a0f6557-a254-4e43-b029-9bbe44d67f84" />
The left light and occluder are on layer 0, the right ones on layer 1, and there are 3 cameras: one which renders layer 0, one which renders layer 1, and one which renders both.
## Combining Lightmaps
I've added a new `CombineLightmapTo` relationship component which can link any number of cameras to one target camera, combining all their output as specified by the `combination_mode` field on the target's `FireflyConfig`.
This can be used to achieve, for instance, an FOV effect such as the one in the new `fov` example.
<img width="911" height="696" alt="image" src="https://github.com/user-attachments/assets/1d91d869-420c-4612-81a9-27b3c9a2e7ad" />
## Custom Lightmap Sizes
The new `lightmap_size` field on `FireflyConfig` can be used to give each lightmap a custom size. It can be set to the target window's size, it can be scaled based on it, or set to a completely custom size.
This offers great potential for optimizing and offering different quality settings to users, as scaling it down to e.g. `LightmapSize::Scaled(0.5)`(half the normal size) halves the GPU workload while being almost unnoticable in most cases.
There's also a new `lightmap_filtering` field which allows users to disable the filtered sampling on lightmaps, possibly achieving a stylized pixel effect.
| Full size | 75% Size | 50% Size | 25% Size | 25% Size unfiltered |
| ------------- | ------------- | ------------- | ------------- | ------------- |
|<img width="1414" height="996" alt="image" src="https://github.com/user-attachments/assets/2f68754a-fa3e-44ff-bdc8-da04b050ac02" />|<img width="1414" height="996" alt="image" src="https://github.com/user-attachments/assets/18d1951e-f464-47a5-92cb-ac763a38bc8e" />|<img width="1414" height="996" alt="image" src="https://github.com/user-attachments/assets/0404712b-6d07-40e4-a37e-c731c90acf3d" />|<img width="1414" height="996" alt="image" src="https://github.com/user-attachments/assets/51d32ba3-ad64-459b-99d8-e904a96f6e40" />|<img width="1414" height="996" alt="image" src="https://github.com/user-attachments/assets/870beb20-ff52-43ae-b559-06c5c6f2165b" />|
## Polygonal Occluder Ordering
Previously, Firefly would assume the vertices passed to the `Occluder2d::polygon` method were in clockwise order. There was a test done to ensure this, but it didn't function for concave occluders.
Now, the method performs a proper O(N) [shoelace](https://en.wikipedia.org/wiki/Shoelace_formula) test to determine the ordering of the vertices and reverse them if they're not in clockwise order.
Additionally, I have introduced the `polygon_cc` and `polygon_ccw` methods which bypass this test and simply expect the vertices to be in clockwise, respectively counter-clockwise orde.r
## Changes to LightHeight
Previously, `LightHeight` used to assume the light's translation is already off the ground and it translated it downwards by the specified amount. This was pretty confusing, so now the `LightHeight` assumes
the light is already positioned on the ground and doesn't translate it.
For instance, if before you had:
```Rs
(PointLight2d {offset: vec3(0.0, 22.0, 0.0), ..default()}, LightHeight(22.0))
```
```Rs
(PointLight2d::default(), Transform::from_translation(vec3(0.0, 22.0, 0.0)), LightHeight(22.0))
```
```Rs
(PointLight2d {offset: vec3(0.0, 10.0, 0.0), ..default()}, Transform::from_translation(vec3(0.0, 12.0, 0.0)), LightHeight(22.0))
```
You now should have:
```Rs
(PointLight2d::default(), LightHeight(22.0))
```
## Minor Changes
- Each light core's boost now defaults to 0.0.
- Added a `enable_32bit_stencils` to `FireflyConfig`, which prevents losing precision when z-sorting, but prevents the app from running on web.
- Replaced more `unwraps` with early returns.
## Bugfixes
- Fixed the serde feature flag.
- Fixed occluder colors.