-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Spectral Color Lighting #14822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Spectral Color Lighting #14822
Conversation
The generated |
The generated |
You added a new feature but didn't update the readme. Please run |
/// | ||
/// Source: <http://cvrl.ioo.ucl.ac.uk/plotcmfs.php> | ||
#[allow(clippy::excessive_precision)] | ||
const CIE_1931_XYZ_CMF_LOOKUP_TABLE: [[f32; 3]; 97] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be better to use the approximations https://github.com/cadacoon/polylight/blob/main/src/color.rs#L88
there is probably not much of a speed difference on modern CPUs.
otherwise, really cool to see
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That link is not working for me 😕 Maybe it's a private repo, or they removed it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, corrected it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example looks fine. Code mostly looks fine minus my comments. I'm going to assume the math is all correct.
I'm happy to merge this once my nits are addressed, meshlet support is fixed, and we remove the cargo feature.
@@ -316,6 +316,9 @@ pbr_multi_layer_material_textures = [ | |||
# Enable support for anisotropy texture in the `StandardMaterial`, at the risk of blowing past the global, per-shader texture limit on older/lower-end GPUs | |||
pbr_anisotropy_texture = ["bevy_internal/pbr_anisotropy_texture"] | |||
|
|||
# Enable support for spectral colors (monochromatic light) in lights | |||
spectral_lighting = ["bevy_internal/spectral_lighting"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why make this a cargo feature? Imo, the less features we have, the better, and we should only use them for things that can't be changed at runtime.
Can we make this a field on PbrPlugin instead?
use bevy_math::FloatExt; | ||
use std::ops::Mul; | ||
|
||
/// A color produced by monochromatic light (of a single wavelength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// A color produced by monochromatic light (of a single wavelength) | |
/// A color produced by monochromatic light (of a single wavelength). |
Maybe(?). Also in all the fields and other places.
@@ -255,6 +255,9 @@ impl SpecializedRenderPipeline for DeferredLightingLayout { | |||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))] | |||
shader_defs.push("WEBGL2".into()); | |||
|
|||
#[cfg(feature = "spectral_lighting")] | |||
shader_defs.push("SPECTRAL_LIGHTING".into()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shaderdefs need to be copied to the meshlet material pipeline stuff.
(Note to maintainers: This seems like a frequent problem with people forgetting meshlet stuff, idk how to prevent it other than me watching out for it 😓)
@@ -78,6 +78,7 @@ The default feature set enables most of the expected features of a game engine, | |||
|serialize|Enable serialization support through serde| | |||
|shader_format_glsl|Enable support for shaders in GLSL| | |||
|shader_format_spirv|Enable support for shaders in SPIR-V| | |||
|spectral_lighting|Enable support for spectral colors (monochromatic light) in lights| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than monochromatic light, single wavelength light might be a better description? Idk what the usual terminology is.
@coreh are you still interested in working on this? |
Yeah. Sorry I went a bit radio silent on this, was busy with a couple other things. Looks like there's a lot of conflicts, but I have a more up-to-date version (as of the latest bevy release) of this on the |
Objective
Lighting calculations in the PBR shader currently take place independently over R, G and B channels. (As is usual for 3D engines!)
This works well for approximating the common case of polychromatic light sources that cover a broad spectrum (e.g. daylight) but falls short when attempting to render scenes with monochromatic light sources, with spectral colors of a single wavelength (e.g. sodium vapor light).
This PR adds initial support for more accurately rendering of monochromatic light sources, using a new blending implementation based on hue and value. (Instead of the existing multiplicative blending implementation). Since this more complex blending has a cost associated and isn't needed for most applications, this feature is behind a
spectral_lighting
feature flag.Solution
SpectralColor
struct, describing a physically-based spectral color, with a single wavelength (in nanometers) and luminance (in candelas per square meter)SpectralColor
toColor
, using the CIE 1931 XYZ color matching functions; (via a lookup table)spectral_lighting
feature flag, and a matchingSPECTRAL_LIGHTING
shader def;monochromaticity
field toPointLight
,SpotLight
,DirectionalLight
,AmbientLight
, to control how monochromatic a given light source is;monochromaticity_blend()
function, to blend colors in a way that more accurately matches the physical behavior of spectral lights. (Existing polychromatic lights are handled as a special case)monochromaticity_blend()
whenever theSPECTRAL_LIGHTING
shader def is enabled;Some notes about the
monochromaticity_blend()
implementation:Testing
Showcase
With spectral color / monochromatic lighting:
Without spectral color / monochromatic lighting:
spectral.mov
Migration Guide
spectral_lighting
feature flag, theAmbientLight
resource will have one extra property (monochromaticity
). We recommend adding..default()
toAmbientLight
(as is usual for other light types with more properties) to make sure your code compiles with the flag.