pub enum PhaseFunction {
Isotropic,
Rayleigh,
Mie {
asymmetry: f32,
},
Curve(Arc<dyn Curve<f32> + Sync + Send>),
ChromaticCurve(Arc<dyn Curve<LinearRgba> + Sync + Send>),
ChromaticTexture(Handle<Image>),
}Expand description
Describes how a ScatteringTerm scatters light in different directions.
A phase function is a function f: [-1, 1] -> [0, ∞), symmetric about x=0
whose input is the cosine of the angle between an incoming light direction and
and outgoing light direction, and whose output is the proportion of the incoming
light that is actually scattered in that direction.
The phase function has an important effect on the “look” of a medium in a scene.
Media consisting of particles of a different size or shape scatter light differently,
and our brains are very good at telling the difference. A dust cloud, which might
correspond roughly to PhaseFunction::Mie { asymmetry: 0.8 }, looks quite different
from the rest of the sky (atmospheric gases), which correspond to PhaseFunction::Rayleigh
Variants§
Isotropic
A phase function that scatters light evenly in all directions.
Rayleigh
A phase function representing Rayleigh scattering.
Rayleigh scattering occurs naturally for particles much smaller than the wavelengths of visible light, such as gas molecules in the atmosphere. It’s generally wavelength-dependent, where shorter wavelengths are scattered more strongly, so scattering should have higher values for blue than green and green than red. Particles that participate in Rayleigh scattering don’t absorb any light, either.
Mie
The Henyey-Greenstein phase function, which approximates Mie scattering.
Mie scattering occurs naturally for spherical particles of dust and aerosols roughly the same size as the wavelengths of visible light, so it’s useful for representing dust or sea spray. It’s generally wavelength-independent, so absorption and scattering should be set to a greyscale value.
Fields
Curve(Arc<dyn Curve<f32> + Sync + Send>)
A phase function defined by a custom curve, where the input is the cosine of the angle between the incoming light ray and the scattered light ray, and the output is the fraction of the incoming light scattered in that direction.
Note: it’s important for photorealism that the phase function be energy conserving, meaning that in total no more light can be scattered than actually entered the medium. For this to be the case, the integral of the phase function over its domain must be equal to 1/2π.
1 ∫ p(x) dx = 1/2π -1
domain: [-1, 1] range: [0, 1]
ChromaticCurve(Arc<dyn Curve<LinearRgba> + Sync + Send>)
A wavelength-dependent (chromatic) phase function returning linear RGB phase values per channel. Used when the phase varies with wavelength, for instance Mie scattering on Martian dust.
Energy conservation applies per channel. Each of the channels must independently satisfy the equation above.
domain: [-1, 1] range: [0, 1] per channel (R, G, B)
ChromaticTexture(Handle<Image>)
A chromatic phase function sampled from an N×1 texture (R,G,B per column).
Use Rgba32Float format. Columns map linearly to cos θ. The LUT spans the
scattering hemisphere: first column is back-scattering (θ = π), last is
forward-scattering (θ = 0).
Resolved to PhaseFunction::ChromaticCurve when the image loads.
To generate your own, compute the phase function using Mie theory (for example,
using the miepython package) and write it as a 32-bit float texture (OpenEXR or KTX2).
Implementations§
Source§impl PhaseFunction
impl PhaseFunction
Sourcepub fn from_curve(
curve: impl Curve<f32> + Send + Sync + 'static,
) -> PhaseFunction
pub fn from_curve( curve: impl Curve<f32> + Send + Sync + 'static, ) -> PhaseFunction
A phase function defined by a custom curve.
Sourcepub fn from_chromatic_curve(
curve: impl Curve<LinearRgba> + Send + Sync + 'static,
) -> PhaseFunction
pub fn from_chromatic_curve( curve: impl Curve<LinearRgba> + Send + Sync + 'static, ) -> PhaseFunction
A wavelength-dependent phase function from a curve that returns linear RGBA.
Sourcepub fn from_chromatic_texture(image: Handle<Image>) -> PhaseFunction
pub fn from_chromatic_texture(image: Handle<Image>) -> PhaseFunction
A chromatic phase function from an N×1 texture. Resolved to a curve when loaded.
Sourcepub fn sample(&self, neg_l_dot_v: f32) -> Option<LinearRgba>
pub fn sample(&self, neg_l_dot_v: f32) -> Option<LinearRgba>
Samples the phase function at the given value in [-1, 1].
Returns Some(LinearRgba) with per-channel phase values (scalar phases use R=G=B).
Returns None when the phase is not yet available (e.g. PhaseFunction::ChromaticTexture before load).
Trait Implementations§
Source§impl Clone for PhaseFunction
impl Clone for PhaseFunction
Source§fn clone(&self) -> PhaseFunction
fn clone(&self) -> PhaseFunction
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Default for PhaseFunction
impl Default for PhaseFunction
Source§fn default() -> PhaseFunction
fn default() -> PhaseFunction
Auto Trait Implementations§
impl !RefUnwindSafe for PhaseFunction
impl !Unpin for PhaseFunction
impl !UnwindSafe for PhaseFunction
impl Freeze for PhaseFunction
impl Send for PhaseFunction
impl Sync for PhaseFunction
impl UnsafeUnpin for PhaseFunction
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T ShaderType for self. When used in AsBindGroup
derives, it is safe to assume that all images in self exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ConditionalSend for Twhere
T: Send,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
Source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Creates Self using default().
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more