pub mod energy;
pub mod gpu;
pub mod surface;
pub mod types;
pub use energy::EnergyTables;
pub use gpu::{Material, material_of, material_of_scaled};
pub use surface::{INPUTS, OpenPbrSurface};
pub use types::{Color3, InputError, InputSpec, Value, ValueType, Vector3};
use bevy_color::LinearRgba;
use glam::Vec3;
impl From<Color3> for LinearRgba {
fn from(c: Color3) -> Self {
LinearRgba::rgb(c.r, c.g, c.b)
}
}
impl From<LinearRgba> for Color3 {
fn from(c: LinearRgba) -> Self {
Color3::new(c.red, c.green, c.blue)
}
}
impl From<Color3> for Vec3 {
fn from(c: Color3) -> Self {
Vec3::new(c.r, c.g, c.b)
}
}
impl From<Vector3> for Vec3 {
fn from(v: Vector3) -> Self {
Vec3::new(v.x, v.y, v.z)
}
}
impl From<Vec3> for Vector3 {
fn from(v: Vec3) -> Self {
Vector3::new(v.x, v.y, v.z)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_new_surface_is_the_spec_default_not_zeroes() {
let surface = OpenPbrSurface::default();
assert_eq!(surface.base_weight, 1.0);
assert_eq!(surface.base_color, Color3::new(0.8, 0.8, 0.8));
assert_eq!(surface.specular_roughness, 0.3);
assert_eq!(surface.specular_ior, 1.5);
assert_eq!(surface.transmission_weight, 0.0);
assert_eq!(surface.subsurface_weight, 0.0);
assert_eq!(surface.fuzz_weight, 0.0);
assert_eq!(surface.coat_weight, 0.0);
assert_eq!(surface.thin_film_weight, 0.0);
assert_eq!(surface.emission_luminance, 0.0);
}
#[test]
fn every_input_is_reachable_by_name() {
let surface = OpenPbrSurface::default();
assert_eq!(INPUTS.len(), 41);
for name in OpenPbrSurface::INPUT_NAMES {
assert!(
OpenPbrSurface::input_spec(name).is_some(),
"{name} has no spec",
);
assert!(surface.get(name).is_ok(), "{name} cannot be read");
}
}
#[test]
fn a_colour_crosses_into_the_renderer_unchanged() {
let linear: LinearRgba = Color3::new(0.25, 0.5, 0.75).into();
assert_eq!(linear, LinearRgba::rgb(0.25, 0.5, 0.75));
assert_eq!(Color3::from(linear), Color3::new(0.25, 0.5, 0.75));
}
#[test]
fn setting_an_input_by_name_reaches_the_field() {
let mut surface = OpenPbrSurface::default();
surface.set_from_str("base_metalness", "1.0").unwrap();
assert_eq!(surface.base_metalness, 1.0);
assert!(!surface.is_default("base_metalness").unwrap());
surface.reset("base_metalness").unwrap();
assert_eq!(surface.base_metalness, 0.0);
assert!(surface.changed_inputs().is_empty());
}
}
pub const SHADER: &str = concat!(
include_str!("wgsl/material.wgsl"),
"\n",
include_str!("wgsl/common.wgsl"),
"\n",
include_str!("wgsl/fuzz_brdf.wgsl"),
"\n",
include_str!("wgsl/coat_brdf.wgsl"),
"\n",
include_str!("wgsl/thin_film.wgsl"),
"\n",
include_str!("wgsl/specular_brdf.wgsl"),
"\n",
include_str!("wgsl/specular_btdf.wgsl"),
"\n",
include_str!("wgsl/metal_brdf.wgsl"),
"\n",
include_str!("wgsl/diffuse.wgsl"),
"\n",
include_str!("wgsl/openpbr_surface.wgsl"),
);