Skip to content

Commit

Permalink
Consistently use sRGBA CPU side and linear sRGBA (or HDR) GPU side (Fix
Browse files Browse the repository at this point in the history
#380) (#386)

* Update to color changes in three-d-asset

* Color -> Srgba

* Convert all Srgba colors to linear before sending them to shader

* Do not implement data types for Color

* Rename

* Color fixes

* Docs and minor clean-up
  • Loading branch information
asny committed Aug 1, 2023
1 parent fc9341c commit b3aa240
Show file tree
Hide file tree
Showing 48 changed files with 296 additions and 282 deletions.
4 changes: 2 additions & 2 deletions examples/animation/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ pub async fn run() {
.for_each(|part| part.compute_normals());
let mut model = Model::<PhysicalMaterial>::new(&context, &cpu_model).unwrap();

let light0 = DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, -0.5, -0.5));
let light1 = DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, 0.5, 0.5));
let light0 = DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, -0.5, -0.5));
let light1 = DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, 0.5, 0.5));

// main loop
window.render_loop(move |mut frame_input| {
Expand Down
4 changes: 2 additions & 2 deletions examples/environment/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub async fn run() {
&context,
&loaded.deserialize("chinese_garden_4k").unwrap(),
);
let light = AmbientLight::new_with_environment(&context, 1.0, Color::WHITE, skybox.texture());
let light = AmbientLight::new_with_environment(&context, 1.0, Srgba::WHITE, skybox.texture());

let mut model = Gm::new(
Mesh::new(&context, &CpuMesh::sphere(32)),
Expand Down Expand Up @@ -79,7 +79,7 @@ pub async fn run() {
panel_width = gui_context.used_rect().width();
},
);
model.material.albedo = Color::from_rgba_slice(&color);
model.material.albedo = Srgba::from(color);

let viewport = Viewport {
x: (panel_width * frame_input.device_pixel_ratio) as i32,
Expand Down
22 changes: 11 additions & 11 deletions examples/fireworks/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use three_d::*;

#[derive(Clone)]
struct FireworksMaterial {
pub color: Color,
pub color: Srgba,
pub fade: f32,
}

Expand All @@ -21,7 +21,7 @@ impl Material for FireworksMaterial {
}
}
fn use_uniforms(&self, program: &Program, _camera: &Camera, _lights: &[&dyn Light]) {
program.use_uniform("color", self.color);
program.use_uniform("color", self.color.to_linear_srgb());
program.use_uniform("fade", self.fade);
}
fn render_states(&self) -> RenderStates {
Expand Down Expand Up @@ -78,14 +78,14 @@ pub fn run() {
let explosion_speed = 15.0;
let explosion_time = 3.0;
let colors = [
Color::new_opaque(255, 255, 178),
Color::new_opaque(255, 51, 25),
Color::new_opaque(51, 102, 51),
Color::new_opaque(127, 127, 204),
Color::new_opaque(217, 23, 51),
Color::new_opaque(250, 237, 38),
Color::new_opaque(76, 237, 38),
Color::new_opaque(40, 178, 222),
Srgba::new_opaque(255, 255, 178),
Srgba::new_opaque(255, 51, 25),
Srgba::new_opaque(51, 102, 51),
Srgba::new_opaque(127, 127, 204),
Srgba::new_opaque(217, 23, 51),
Srgba::new_opaque(250, 237, 38),
Srgba::new_opaque(76, 237, 38),
Srgba::new_opaque(40, 178, 222),
];
let mut square = CpuMesh::square();
square.transform(&Mat4::from_scale(0.6)).unwrap();
Expand Down Expand Up @@ -130,7 +130,7 @@ pub fn run() {
let colors = Some(
(0..300)
.map(|_| {
Color::new_opaque(
Srgba::new_opaque(
(rng.gen::<f32>() * 100.0 - 50.0) as u8,
(rng.gen::<f32>() * 100.0 - 50.0) as u8,
(rng.gen::<f32>() * 100.0 - 50.0) as u8,
Expand Down
13 changes: 13 additions & 0 deletions examples/fireworks/src/particles.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ in vec4 col;

layout (location = 0) out vec4 outColor;

vec3 srgb_from_linear_srgb(vec3 rgb) {
vec3 a = vec3(0.055, 0.055, 0.055);
vec3 ap1 = vec3(1.0, 1.0, 1.0) + a;
vec3 g = vec3(2.4, 2.4, 2.4);
vec3 ginv = 1.0 / g;
vec3 select = step(vec3(0.0031308, 0.0031308, 0.0031308), rgb);
vec3 lo = rgb * 12.92;
vec3 hi = ap1 * pow(rgb, ginv) - a;
return mix(lo, hi, select);
}

void main()
{
float sqrDist = 2.0 * length(uvs - vec2(0.5, 0.5));
Expand All @@ -18,4 +29,6 @@ void main()
float f = 1.0 - sqrDist*sqrDist;
outColor = vec4(col.rgb + color.rgb, fade * color.a * f);
}

outColor.rgb = srgb_from_linear_srgb(outColor.rgb);
}
6 changes: 3 additions & 3 deletions examples/fog/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ pub async fn run() {
.iter_mut()
.for_each(|m| m.material.render_states.cull = Cull::Back);

let ambient = AmbientLight::new(&context, 0.4, Color::WHITE);
let directional = DirectionalLight::new(&context, 2.0, Color::WHITE, &vec3(-1.0, -1.0, -1.0));
let ambient = AmbientLight::new(&context, 0.4, Srgba::WHITE);
let directional = DirectionalLight::new(&context, 2.0, Srgba::WHITE, &vec3(-1.0, -1.0, -1.0));

// Fog
let mut fog_effect = FogEffect {
color: Color::new_opaque(200, 200, 200),
color: Srgba::new_opaque(200, 200, 200),
density: 0.2,
animation: 0.1,
..Default::default()
Expand Down
6 changes: 3 additions & 3 deletions examples/forest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ pub async fn run() {
.for_each(|m| m.material.render_states.cull = Cull::Back);

// Lights
let ambient = AmbientLight::new(&context, 0.3, Color::WHITE);
let directional = DirectionalLight::new(&context, 4.0, Color::WHITE, &vec3(-1.0, -1.0, -1.0));
let ambient = AmbientLight::new(&context, 0.3, Srgba::WHITE);
let directional = DirectionalLight::new(&context, 4.0, Srgba::WHITE, &vec3(-1.0, -1.0, -1.0));

// Imposters
let mut aabb = AxisAlignedBoundingBox::EMPTY;
Expand Down Expand Up @@ -92,7 +92,7 @@ pub async fn run() {
PhysicalMaterial::new_opaque(
&context,
&CpuMaterial {
albedo: Color::new_opaque(128, 200, 70),
albedo: Srgba::new_opaque(128, 200, 70),
metallic: 0.0,
roughness: 1.0,
..Default::default()
Expand Down
6 changes: 3 additions & 3 deletions examples/headless/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ fn main() {
vec3(0.0, 0.5, 0.0), // top
]),
colors: Some(vec![
Color::new(255, 0, 0, 255), // bottom right
Color::new(0, 255, 0, 255), // bottom left
Color::new(0, 0, 255, 255), // top
Srgba::new(255, 0, 0, 255), // bottom right
Srgba::new(0, 255, 0, 255), // bottom left
Srgba::new(0, 0, 255, 255), // top
]),
..Default::default()
},
Expand Down
32 changes: 11 additions & 21 deletions examples/instanced_draw_order/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ pub fn main() {
Mat4::from_translation(vec3(3.0, 0.0, 0.5)) * rot_z90 * Mat4::from_angle_x(Deg(-45.0)),
],
colors: Some(vec![
Color::new(0, 255, 0, 255), // green, closest, should obscure everything.
Color::new(255, 0, 255, 255), // purple, behind green, second opaque plane.
Color::new(255, 0, 0, 128), // Red, third plane, should be behind two opaques, blend in front of blue.
Color::new(0, 0, 255, 128), // Furthest, blue layer.
Srgba::new(0, 255, 0, 255), // green, closest, should obscure everything.
Srgba::new(255, 0, 255, 255), // purple, behind green, second opaque plane.
Srgba::new(255, 0, 0, 128), // Red, third plane, should be behind two opaques, blend in front of blue.
Srgba::new(0, 0, 255, 128), // Furthest, blue layer.
// Next two always intersect.
Color::new(0, 128, 128, 128), // Limitation of ordering, cyan
Color::new(128, 128, 0, 128), // Limitation of ordering, yellow
Srgba::new(0, 128, 128, 128), // Limitation of ordering, cyan
Srgba::new(128, 128, 0, 128), // Limitation of ordering, yellow
]),
..Default::default()
};
Expand All @@ -66,12 +66,7 @@ pub fn main() {
PhysicalMaterial::new_transparent(
&context,
&CpuMaterial {
albedo: Color {
r: 255,
g: 255,
b: 255,
a: 255,
},
albedo: Srgba::WHITE,
..Default::default()
},
),
Expand All @@ -86,7 +81,7 @@ pub fn main() {
.as_ref()
.unwrap()
.iter()
.map(|c| Color {
.map(|c| Srgba {
r: c.r,
g: c.g,
b: c.b,
Expand All @@ -109,19 +104,14 @@ pub fn main() {
PhysicalMaterial::new_opaque(
&context,
&CpuMaterial {
albedo: Color {
r: 255,
g: 255,
b: 255,
a: 255,
},
albedo: Srgba::WHITE,
..Default::default()
},
),
);

let light0 = DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, -0.5, -0.5));
let ambient_light = three_d::renderer::light::AmbientLight::new(&context, 0.1, Color::WHITE);
let light0 = DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, -0.5, -0.5));
let ambient_light = three_d::renderer::light::AmbientLight::new(&context, 0.1, Srgba::WHITE);

window.render_loop(move |mut frame_input| {
camera.set_viewport(frame_input.viewport);
Expand Down
8 changes: 4 additions & 4 deletions examples/instanced_shapes/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub fn main() {
);
let mut control = OrbitControl::new(vec3(0.0, 0.0, 0.0), 1.0, 1000.0);

let light0 = DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, -0.5, -0.5));
let light1 = DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, 0.5, 0.5));
let light0 = DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, -0.5, -0.5));
let light1 = DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, 0.5, 0.5));

// Container for non instanced meshes.
let mut non_instanced_meshes = Vec::new();
Expand All @@ -32,7 +32,7 @@ pub fn main() {
PhysicalMaterial::new(
&context,
&CpuMaterial {
albedo: Color {
albedo: Srgba {
r: 128,
g: 128,
b: 128,
Expand Down Expand Up @@ -97,7 +97,7 @@ pub fn main() {
PhysicalMaterial::new(
&context,
&CpuMaterial {
albedo: Color {
albedo: Srgba {
r: 128,
g: 128,
b: 128,
Expand Down
14 changes: 7 additions & 7 deletions examples/lighting/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub async fn run() {
PhysicalMaterial::new_opaque(
&context,
&CpuMaterial {
albedo: Color::new_opaque(128, 200, 70),
albedo: Srgba::new_opaque(128, 200, 70),
..Default::default()
},
),
Expand All @@ -80,14 +80,14 @@ pub async fn run() {
DeferredPhysicalMaterial::from_physical_material(&plane.material),
);

let mut ambient = AmbientLight::new(&context, 0.2, Color::WHITE);
let mut directional0 = DirectionalLight::new(&context, 1.0, Color::RED, &vec3(0.0, -1.0, 0.0));
let mut ambient = AmbientLight::new(&context, 0.2, Srgba::WHITE);
let mut directional0 = DirectionalLight::new(&context, 1.0, Srgba::RED, &vec3(0.0, -1.0, 0.0));
let mut directional1 =
DirectionalLight::new(&context, 1.0, Color::GREEN, &vec3(0.0, -1.0, 0.0));
DirectionalLight::new(&context, 1.0, Srgba::GREEN, &vec3(0.0, -1.0, 0.0));
let mut spot0 = SpotLight::new(
&context,
2.0,
Color::BLUE,
Srgba::BLUE,
&vec3(0.0, 0.0, 0.0),
&vec3(0.0, -1.0, 0.0),
degrees(25.0),
Expand All @@ -100,7 +100,7 @@ pub async fn run() {
let mut point0 = PointLight::new(
&context,
1.0,
Color::GREEN,
Srgba::GREEN,
&vec3(0.0, 0.0, 0.0),
Attenuation {
constant: 0.5,
Expand All @@ -111,7 +111,7 @@ pub async fn run() {
let mut point1 = PointLight::new(
&context,
1.0,
Color::RED,
Srgba::RED,
&vec3(0.0, 0.0, 0.0),
Attenuation {
constant: 0.5,
Expand Down
9 changes: 4 additions & 5 deletions examples/lights/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub async fn run() {
for light in lights.iter_mut() {
light.set_light(
intensity,
Color::from_rgba_slice(&color),
Srgba::from(color),
Attenuation {
constant,
linear,
Expand Down Expand Up @@ -155,7 +155,7 @@ impl Glow {
);
Self {
aabb,
light: PointLight::new(&context, 1.0, Color::WHITE, &pos, Attenuation::default()),
light: PointLight::new(&context, 1.0, Srgba::WHITE, &pos, Attenuation::default()),
velocity: vec3(
rng.gen::<f32>() * 2.0 - 1.0,
rng.gen::<f32>() * 2.0 - 1.0,
Expand All @@ -169,12 +169,11 @@ impl Glow {
}
}

pub fn set_light(&mut self, intensity: f32, color: Color, attenuation: Attenuation) {
pub fn set_light(&mut self, intensity: f32, color: Srgba, attenuation: Attenuation) {
self.light.color = color;
self.light.intensity = intensity;
self.light.attenuation = attenuation;
let c = color.to_vec4() * intensity;
self.sphere.material.emissive = Color::from_rgba_slice(&[c.x, c.y, c.z, c.w]);
self.sphere.material.emissive = color;
}

pub fn update(&mut self, delta: f32) {
Expand Down
6 changes: 3 additions & 3 deletions examples/logo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ pub async fn run() {
vec3(0.0, 0.6, 0.0), // top
];
let colors = vec![
Color::new(255, 0, 0, 255), // bottom right
Color::new(0, 255, 0, 255), // bottom left
Color::new(0, 0, 255, 255), // top
Srgba::new(255, 0, 0, 255), // bottom right
Srgba::new(0, 255, 0, 255), // bottom left
Srgba::new(0, 0, 255, 255), // top
];
let cpu_mesh = CpuMesh {
positions: Positions::F32(positions),
Expand Down
14 changes: 2 additions & 12 deletions examples/multisample/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,7 @@ pub fn main() {
ColorMaterial::new_opaque(
&context,
&CpuMaterial {
albedo: Color {
r: 255,
g: 255,
b: 255,
a: 255,
},
albedo: Srgba::WHITE,
..Default::default()
},
),
Expand All @@ -55,12 +50,7 @@ pub fn main() {
ColorMaterial::new_opaque(
&context,
&CpuMaterial {
albedo: Color {
r: 255,
g: 255,
b: 255,
a: 255,
},
albedo: Srgba::WHITE,
..Default::default()
},
),
Expand Down
6 changes: 3 additions & 3 deletions examples/multiwindow/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ pub fn main() {
vec3(0.0, 0.5, 0.0), // top
];
let colors = vec![
Color::new(255, 0, 0, 255), // bottom right
Color::new(0, 255, 0, 255), // bottom left
Color::new(0, 0, 255, 255), // top
Srgba::new(255, 0, 0, 255), // bottom right
Srgba::new(0, 255, 0, 255), // bottom left
Srgba::new(0, 0, 255, 255), // top
];
let cpu_mesh = CpuMesh {
positions: Positions::F32(positions),
Expand Down
4 changes: 2 additions & 2 deletions examples/normals/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ pub async fn run() {
);
let mut control = OrbitControl::new(*camera.target(), 1.0, 100.0);

let ambient = AmbientLight::new(&context, 0.4, Color::WHITE);
let directional = DirectionalLight::new(&context, 2.0, Color::WHITE, &vec3(0.0, -1.0, 0.0));
let ambient = AmbientLight::new(&context, 0.4, Srgba::WHITE);
let directional = DirectionalLight::new(&context, 2.0, Srgba::WHITE, &vec3(0.0, -1.0, 0.0));

// main loop
window.render_loop(move |mut frame_input| {
Expand Down
Loading

0 comments on commit b3aa240

Please sign in to comment.