Skip to content

Commit 45b2db7

Browse files
mtsrStarArawnIngmarBitter
committed
Rebase of existing PBR work (#1554)
This is a rebase of StarArawns PBR work from #261 with IngmarBitters work from #1160 cherry-picked on top. I had to make a few minor changes to make some intermediate commits compile and the end result is not yet 100% what I expected, so there's a bit more work to do. Co-authored-by: John Mitchell <[email protected]> Co-authored-by: Ingmar Bitter <[email protected]>
1 parent b6be8a5 commit 45b2db7

File tree

28 files changed

+520
-131
lines changed

28 files changed

+520
-131
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ path = "examples/3d/orthographic.rs"
135135
name = "parenting"
136136
path = "examples/3d/parenting.rs"
137137

138+
[[example]]
139+
name = "pbr"
140+
path = "examples/3d/pbr.rs"
141+
138142
[[example]]
139143
name = "spawner"
140144
path = "examples/3d/spawner.rs"

crates/bevy_gltf/src/loader.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,12 @@ fn load_material(material: &Material, load_context: &mut LoadContext) -> Handle<
277277
load_context.set_labeled_asset(
278278
&material_label,
279279
LoadedAsset::new(StandardMaterial {
280-
albedo: Color::rgba(color[0], color[1], color[2], color[3]),
281-
albedo_texture: texture_handle,
280+
base_color: Color::rgba(color[0], color[1], color[2], color[3]),
281+
base_color_texture: texture_handle,
282+
roughness: pbr.roughness_factor(),
283+
metallic: pbr.metallic_factor(),
282284
unlit: material.unlit(),
285+
..Default::default()
283286
})
284287
.with_dependencies(dependencies),
285288
)

crates/bevy_internal/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ pub mod gltf {
9696
#[cfg(feature = "bevy_pbr")]
9797
pub mod pbr {
9898
//! Physically based rendering.
99-
//! **Note**: true PBR has not yet been implemented; the name `pbr` is aspirational.
10099
pub use bevy_pbr::*;
101100
}
102101

crates/bevy_pbr/src/entity.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{light::Light, material::StandardMaterial, render_graph::FORWARD_PIPELINE_HANDLE};
1+
use crate::{light::Light, material::StandardMaterial, render_graph::PBR_PIPELINE_HANDLE};
22
use bevy_asset::Handle;
33
use bevy_ecs::bundle::Bundle;
44
use bevy_render::{
@@ -27,7 +27,7 @@ impl Default for PbrBundle {
2727
fn default() -> Self {
2828
Self {
2929
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
30-
FORWARD_PIPELINE_HANDLE.typed(),
30+
PBR_PIPELINE_HANDLE.typed(),
3131
)]),
3232
mesh: Default::default(),
3333
visible: Default::default(),

crates/bevy_pbr/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ impl Plugin for PbrPlugin {
4242
materials.set_untracked(
4343
Handle::<StandardMaterial>::default(),
4444
StandardMaterial {
45-
albedo: Color::PINK,
45+
base_color: Color::PINK,
4646
unlit: true,
47-
albedo_texture: None,
47+
..Default::default()
4848
},
4949
);
5050
}

crates/bevy_pbr/src/light.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ pub struct Light {
1515
pub color: Color,
1616
pub fov: f32,
1717
pub depth: Range<f32>,
18+
pub intensity: f32,
19+
pub range: f32,
1820
}
1921

2022
impl Default for Light {
@@ -23,6 +25,8 @@ impl Default for Light {
2325
color: Color::rgb(1.0, 1.0, 1.0),
2426
depth: 0.1..50.0,
2527
fov: f32::to_radians(60.0),
28+
intensity: 200.0,
29+
range: 20.0,
2630
}
2731
}
2832
}
@@ -48,10 +52,14 @@ impl LightRaw {
4852

4953
let proj = perspective.get_projection_matrix() * global_transform.compute_matrix();
5054
let (x, y, z) = global_transform.translation.into();
55+
56+
// premultiply color by intensity
57+
// we don't use the alpha at all, so no reason to multiply only [0..3]
58+
let color: [f32; 4] = (light.color * light.intensity).into();
5159
LightRaw {
5260
proj: proj.to_cols_array_2d(),
53-
pos: [x, y, z, 1.0],
54-
color: light.color.into(),
61+
pos: [x, y, z, 1.0 / (light.range * light.range)], // pos.w is the attenuation.
62+
color,
5563
}
5664
}
5765
}

crates/bevy_pbr/src/material.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,28 @@ use bevy_reflect::TypeUuid;
33
use bevy_render::{color::Color, renderer::RenderResources, shader::ShaderDefs, texture::Texture};
44

55
/// A material with "standard" properties used in PBR lighting
6+
/// Standard property values with pictures here https://google.github.io/filament/Material%20Properties.pdf
67
#[derive(Debug, RenderResources, ShaderDefs, TypeUuid)]
78
#[uuid = "dace545e-4bc6-4595-a79d-c224fc694975"]
89
pub struct StandardMaterial {
9-
pub albedo: Color,
10+
/// Doubles as diffuse albedo for non-metallic, specular for metallic and a mix for everything in between
11+
/// If used together with a base_color_texture, this is factored into the final base color
12+
/// as `base_color * base_color_texture_value`
13+
pub base_color: Color,
1014
#[shader_def]
11-
pub albedo_texture: Option<Handle<Texture>>,
15+
pub base_color_texture: Option<Handle<Texture>>,
16+
/// Linear perceptual roughness, clamped to [0.089, 1.0] in the shader
17+
/// Defaults to minimum of 0.089
18+
/// If used together with a roughness/metallic texture, this is factored into the final base color
19+
/// as `roughness * roughness_texture_value`
20+
pub roughness: f32,
21+
/// From [0.0, 1.0], dielectric to pure metallic
22+
/// If used together with a roughness/metallic texture, this is factored into the final base color
23+
/// as `metallic * metallic_texture_value`
24+
pub metallic: f32,
25+
/// Specular intensity for non-metals on a linear scale of [0.0, 1.0]
26+
/// defaults to 0.5 which is mapped to 4% reflectance in the shader
27+
pub reflectance: f32,
1228
#[render_resources(ignore)]
1329
#[shader_def]
1430
pub unlit: bool,
@@ -17,8 +33,19 @@ pub struct StandardMaterial {
1733
impl Default for StandardMaterial {
1834
fn default() -> Self {
1935
StandardMaterial {
20-
albedo: Color::rgb(1.0, 1.0, 1.0),
21-
albedo_texture: None,
36+
base_color: Color::rgb(1.0, 1.0, 1.0),
37+
base_color_texture: None,
38+
// This is the minimum the roughness is clamped to in shader code
39+
// See https://google.github.io/filament/Filament.html#materialsystem/parameterization/
40+
// It's the minimum floating point value that won't be rounded down to 0 in the calculations used.
41+
// Although technically for 32-bit floats, 0.045 could be used.
42+
roughness: 0.089,
43+
// Few materials are purely dielectric or metallic
44+
// This is just a default for mostly-dielectric
45+
metallic: 0.01,
46+
// Minimum real-world reflectance is 2%, most materials between 2-5%
47+
// Expressed in a linear scale and equivalent to 4% reflectance see https://google.github.io/filament/Material%20Properties.pdf
48+
reflectance: 0.5,
2249
unlit: false,
2350
}
2451
}
@@ -27,7 +54,7 @@ impl Default for StandardMaterial {
2754
impl From<Color> for StandardMaterial {
2855
fn from(color: Color) -> Self {
2956
StandardMaterial {
30-
albedo: color,
57+
base_color: color,
3158
..Default::default()
3259
}
3360
}
@@ -36,7 +63,7 @@ impl From<Color> for StandardMaterial {
3663
impl From<Handle<Texture>> for StandardMaterial {
3764
fn from(texture: Handle<Texture>) -> Self {
3865
StandardMaterial {
39-
albedo_texture: Some(texture),
66+
base_color_texture: Some(texture),
4067
..Default::default()
4168
}
4269
}

crates/bevy_pbr/src/render_graph/forward_pipeline/forward.frag

Lines changed: 0 additions & 65 deletions
This file was deleted.

crates/bevy_pbr/src/render_graph/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
mod forward_pipeline;
21
mod lights_node;
2+
mod pbr_pipeline;
33

44
use bevy_ecs::world::World;
5-
pub use forward_pipeline::*;
65
pub use lights_node::*;
6+
pub use pbr_pipeline::*;
77

88
/// the names of pbr graph nodes
99
pub mod node {
@@ -50,10 +50,9 @@ pub(crate) fn add_pbr_graph(world: &mut World) {
5050
.add_node_edge(node::LIGHTS, base::node::MAIN_PASS)
5151
.unwrap();
5252
}
53-
let forward_pipeline =
54-
build_forward_pipeline(&mut world.get_resource_mut::<Assets<Shader>>().unwrap());
53+
let pipeline = build_pbr_pipeline(&mut world.get_resource_mut::<Assets<Shader>>().unwrap());
5554
let mut pipelines = world
5655
.get_resource_mut::<Assets<PipelineDescriptor>>()
5756
.unwrap();
58-
pipelines.set_untracked(FORWARD_PIPELINE_HANDLE, forward_pipeline);
57+
pipelines.set_untracked(PBR_PIPELINE_HANDLE, pipeline);
5958
}

crates/bevy_pbr/src/render_graph/forward_pipeline/mod.rs renamed to crates/bevy_pbr/src/render_graph/pbr_pipeline/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ use bevy_render::{
99
texture::TextureFormat,
1010
};
1111

12-
pub const FORWARD_PIPELINE_HANDLE: HandleUntyped =
12+
pub const PBR_PIPELINE_HANDLE: HandleUntyped =
1313
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 13148362314012771389);
1414

15-
pub(crate) fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
15+
pub(crate) fn build_pbr_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
1616
PipelineDescriptor {
1717
depth_stencil: Some(DepthStencilState {
1818
format: TextureFormat::Depth32Float,
@@ -48,11 +48,11 @@ pub(crate) fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDe
4848
..PipelineDescriptor::new(ShaderStages {
4949
vertex: shaders.add(Shader::from_glsl(
5050
ShaderStage::Vertex,
51-
include_str!("forward.vert"),
51+
include_str!("pbr.vert"),
5252
)),
5353
fragment: Some(shaders.add(Shader::from_glsl(
5454
ShaderStage::Fragment,
55-
include_str!("forward.frag"),
55+
include_str!("pbr.frag"),
5656
))),
5757
})
5858
}

0 commit comments

Comments
 (0)