Skip to content

Minimum Viable Monochromatic Lights#24428

Open
coreh wants to merge 5 commits into
bevyengine:mainfrom
coreh:minimum-viable-monochromatic-lights
Open

Minimum Viable Monochromatic Lights#24428
coreh wants to merge 5 commits into
bevyengine:mainfrom
coreh:minimum-viable-monochromatic-lights

Conversation

@coreh
Copy link
Copy Markdown
Contributor

@coreh coreh commented May 25, 2026

Note: This PR has been extracted from #14822, with the goal of making it easier to review and hopefully merge by splitting off some potentially contentious parts (e.g. SpectralColor) and also since some areas will require more work (e.g. ambient light support: we'll need to add ambient light bitflags and to figure out how to properly interact with with irradiance volumes, etc.)

Related PRs: #24447


Objective

  • Add support for rendering monochromatic lights (e.g. Sodium Vapor and Violet lights).
  • Pave the way for adding more complete spectral rendering support later (e.g. the approach described by Otsu et al. 2018, or perhaps even full or approximate Donaldson Matrix models for fluorescence etc) via a camera enum for choosing between spectral models

Solution

  • Added a new SpectralModel enum to bevy_camera, to allow selecting between the “traditional” Tristimulus rendering or Tristimulus + Monochromatic Lights
  • Added a new monochromatic flagto SpotLight, PointLight and DirectionalLight components
  • Added plumbing to properly extract this info from the camera and lights
  • Added a new MeshPipelineKey::MONOCHROMATIC_LIGHTS flag and MONOCHROMATIC_LIGHTS shader def
  • Added a new POINT_LIGHT_FLAGS_MONOCHROMATIC_BIT and DIRECTIONAL_LIGHT_FLAGS_MONOCHROMATIC_BIT WGSL constants
  • Added a new monochromatic_response() WGSL function, that approximates response of the base color to monochromatic light via a simple HSV + triangle function gaussian approximation
  • Hooked up PBR code to use this new approach instead of simple component-wise tristimulus multiplication for monochrome lights

Notes

  • This implementation is meant to go hand in hand with the SpectralColor type from Spectral Color Lighting #14822, which I will also extract in a separate PR and link from here
  • The current monochromatic light approximation will happily accept RGB values only possible via non-spectral, polychromatic, colors (e.g. white, magenta) producing non-physical results. These look weird but can be used for artistic effect (e.g. a light that turns things grayscale, could be cool for a “noir” type of game)
  • For pure red, green, blue monochromatic lights, or grayscale base colors, the end result is identical to regular tristimulus rendering (as expected)
  • The implementation on Spectral Color Lighting #14822 gated this behind a feature flag, this has been removed as part of the extraction of this PR, by moving to a mesh pipeline key.
  • Only point, spot and directional lights are supported for now
  • The example has been somewhat simplified from its original form, to have a few light presets
  • Tried my best to keep usage of somewhat-related-but-not-exactly-the-same terms like "monochromatic light", "spectral light", "spectral color", "spectral rendering" correct and consistent

Testing

  • Did you test these changes? If so, how? Yes, via example code/manual testing
  • Are there any parts that need more testing? I don't think so, but possibly to check fidelity/display issues?
  • How can other people (reviewers) test your changes? Is there anything specific they need to know? Via the examples
  • If relevant, what platforms did you test these changes on, and are there any important ones you can't test? macOS

Showcase

image image

@coreh coreh added the A-Rendering Drawing game state to the screen label May 25, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Rendering May 25, 2026
@coreh coreh added C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 25, 2026
MyCodingSpace5 pushed a commit to MyCodingSpace5/bevy that referenced this pull request Jun 2, 2026
# Objective

While testing bevyengine#24428, I realized the `rgb_to_hsv` function can return
negative hues, eg `rgb_to_hsv(vec3(1.0, 0.0, 1.0))` returns `(-1.0472,
1.0, 1.0)`.

## Solution

For colors where `(swizzle.x - swizzle.y) / c + swizzle.z` is negative,
`negative % 6.0` stays negative.
I replaced `x % 6.0` with `fract(x / 6.0) * 6.0`, which is always
positive.

## Testing
- Ran the shader from a test script for a couple colors. 

The function is pretty much unused, it currently only gets called when
`ColorGradingGlobal.hue` is set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

1 participant