Struct SphericalHarmonics

Source
#[repr(C)]
pub struct SphericalHarmonics { pub coefficients: [Vec3; 9], }
Expand description

Spherical Harmonics are kinda like Fourier, but on a sphere. That doesn’t mean terribly much to me, and could be wrong, but check out here for more details about how Spherical Harmonics work in this context!

However, the more prctical thing is, SH can be a function that describes a value over the surface of a sphere! This is particularly useful for lighting, since you can basically store the lighting information for a space in this value! This is often used for lightmap data, or a light probe grid, but StereoKit just uses a single SH for the entire scene. It’s a gross oversimplification, but looks quite good, and is really fast! That’s extremely great when you’re trying to hit 60fps, or even 144fps. https://stereokit.net/Pages/StereoKit/SphericalHarmonics.html

see also: crate::tex::SHCubemap

§Examples

use stereokit_rust::{maths::Vec3,
                     util::{SHLight, named_colors, Color128, SphericalHarmonics}};

let light0 = SHLight::new([1.0, 0.0, 0.0], named_colors::RED);
let light1 = SHLight::new([0.0, 1.0, 0.0], named_colors::GREEN);
let light2 = SHLight::new([0.0, 0.0, 1.0], named_colors::BLUE);

let mut sh = SphericalHarmonics::from_lights(&[light0, light1, light2]);
sh.brightness(1.0)
  .add(Vec3::NEG_Y, named_colors::GREEN)
  .add(Vec3::NEG_Z, named_colors::BLUE)
  .add(Vec3::NEG_X, named_colors::RED);

assert_eq!(sh.get_sample(Vec3::UP), Color128 { r: 0.5813507, g: 0.8046322, b: 0.5813487, a: 1.0 });
assert_eq!(sh.get_dominent_light_direction(), Vec3 { x: 0.27644092, y: 0.2728996, z: 0.9214696 });

Fields§

§coefficients: [Vec3; 9]

Implementations§

Source§

impl SphericalHarmonics

Source

pub fn from_lights(lights: &[SHLight]) -> Self

Creates a SphericalHarmonics approximation of the irradiance given from a set of directional lights! https://stereokit.net/Pages/StereoKit/SphericalHarmonics/FromLights.html

  • lights - A list of directional lights!

Returns a SphericalHarmonics approximation of the irradiance given from a set of directional lights! see also SHLight

§Examples
use stereokit_rust::{maths::Vec3,
                     util::{SHLight, named_colors, Color128, SphericalHarmonics}};

let light0 = SHLight::new([1.0, 1.0, 1.0], named_colors::RED);
let light1 = SHLight::new([0.5, 0.5, 0.5], named_colors::RED);
let light2 = SHLight::new([0.25, 0.25, 0.25], named_colors::RED);

let sh = SphericalHarmonics::from_lights(&[light0, light1, light2]);

assert_eq!(sh.get_sample(Vec3::UP), Color128 { r: 2.2098913, g: 0.0, b: 0.0, a: 1.0 });
assert_eq!(sh.get_dominent_light_direction(), -Vec3::ONE.get_normalized());
Source

pub fn new(coefficients: [Vec3; 9]) -> Self

Creates a SphericalHarmonic from an array of coefficients. Useful for loading stored data! https://stereokit.net/Pages/StereoKit/SphericalHarmonics/SphericalHarmonics.html

  • coefficients - Must be an array with a length of 9!

see also sh_create

§Examples
use stereokit_rust::{maths::Vec3,
                     util::{SHLight, named_colors, Color128, SphericalHarmonics}};

let mut sh0 = SphericalHarmonics::default();
sh0.add([1.0, 0.0, 1.0], named_colors::RED);
let coefficient = sh0.coefficients;

let sh = SphericalHarmonics::new(coefficient);

assert_eq!(sh.get_sample([1.0, 0.0, 1.0]), Color128 { r: 11.453729, g: 0.0, b: 0.0, a: 1.0 });
assert_eq!(sh.get_dominent_light_direction(), Vec3::new(-1.0, 0.0, -1.0).get_normalized());
Source

pub fn add( &mut self, light_dir: impl Into<Vec3>, light_color: impl Into<Color128>, ) -> &mut Self

Adds a ‘directional light’ to the lighting approximation. This can be used to bake a multiple light setup, or accumulate light from a field of points. https://stereokit.net/Pages/StereoKit/SphericalHarmonics/Add.html

  • light_dir - The direction of the light source.
  • light_color - Color of the light, in linear color space.

see also sh_add

§Examples
use stereokit_rust::{maths::Vec3,
                     util::{SHLight, named_colors, Color128, SphericalHarmonics}};

let mut sh = SphericalHarmonics::default();
sh.add([1.0, 0.0, 1.0], named_colors::RED)
  .add([0.0, 1.0, 0.0], named_colors::GREEN)
  .add([0.0, 0.0, 1.0], named_colors::BLUE);

assert_eq!(sh.get_sample([1.0, 0.0, 1.0]), Color128 { r: 11.453729, g: -0.2956792, b: 4.4505944, a: 1.0 });
assert_eq!(sh.get_dominent_light_direction(), Vec3 { x: -0.21951628, y: -0.21670417, z: -0.95123714 });
Source

pub fn brightness(&mut self, scale: f32) -> &mut Self

Scales all the SphericalHarmonic’s coefficients! This behaves as if you’re modifying the brightness of the lighting this object represents. https://stereokit.net/Pages/StereoKit/SphericalHarmonics/Brightness.html

  • scale - A multiplier for the coefficients! A value of 1 will leave everything the same, 0.5 will cut the brightness in half, and a 2 will double the brightness.

see also sh_brightness

§Examples
use stereokit_rust::{maths::Vec3,
                     util::{SHLight, named_colors, Color128, SphericalHarmonics}};

let mut sh = SphericalHarmonics::default();
sh.add([1.0, 0.0, 1.0], named_colors::RED)
  .brightness(0.5);

assert_eq!(sh.get_sample([1.0, 0.0, 1.0]), Color128 { r: 5.726864, g: 0.0, b: 0.0, a: 1.0 });
assert_eq!(sh.get_dominent_light_direction(), Vec3::new(-1.0, 0.0, -1.0).get_normalized());

sh.brightness(2.0);
assert_eq!(sh.get_sample([1.0, 0.0, 1.0]), Color128 { r: 11.453729, g: 0.0, b: 0.0, a: 1.0 });
assert_eq!(sh.get_dominent_light_direction(), Vec3::new(-1.0, 0.0, -1.0).get_normalized());


sh.brightness(0.0);
assert_eq!(sh.get_sample([1.0, 0.0, 1.0]), Color128::BLACK);
assert_eq!(sh.get_dominent_light_direction().x.is_nan(), true);
Source

pub fn get_sample(&self, normal: impl Into<Vec3>) -> Color128

Look up the color information in a particular direction! https://stereokit.net/Pages/StereoKit/SphericalHarmonics/Sample.html

  • normal - The direction to look in. Should be normalized.

Returns the color represented by the SH in the given direction. see also sh_brightness

Source

pub fn get_dominent_light_direction(&self) -> Vec3

Returns the dominant direction of the light represented by this spherical harmonics data. The direction value is normalized. You can get the color of the light in this direction by using the struct’s Sample method: light.get_sample(-light.get_dominent_light_direction()). https://stereokit.net/Pages/StereoKit/SphericalHarmonics/DominantLightDirection.html

see also sh_brightness

§Examples
use stereokit_rust::{maths::Vec3,
                     util::{SHLight, named_colors, Color128, SphericalHarmonics}};

let mut sh = SphericalHarmonics::default();
sh.add([1.0, 0.0, 1.0], named_colors::RED)
  .add([1.0, 1.0, 0.0], named_colors::GREEN)
  .add([0.0, 1.0, 1.0], named_colors::BLUE);

assert_eq!(sh.get_dominent_light_direction(), Vec3 { x: -0.3088678, y: -0.6715365, z: -0.6735276 });
Source

pub fn to_array(&self) -> [Vec3; 9]

Converts the SphericalHarmonic into a vector of coefficients 9 long. Useful for storing calculated data! https://stereokit.net/Pages/StereoKit/SphericalHarmonics/ToArray.html

Returns an array of coefficients 9 long. see also sh_brightness

Trait Implementations§

Source§

impl Clone for SphericalHarmonics

Source§

fn clone(&self) -> SphericalHarmonics

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SphericalHarmonics

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SphericalHarmonics

Source§

fn default() -> SphericalHarmonics

Returns the “default value” for a type. Read more
Source§

impl PartialEq for SphericalHarmonics

Source§

fn eq(&self, other: &SphericalHarmonics) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for SphericalHarmonics

Source§

impl StructuralPartialEq for SphericalHarmonics

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &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> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more