Skip to content

Commit 69af890

Browse files
committed
Add support for flat shading with indiced meshes
Use the partial derivative (dFdx, dFdy) for computing facet normals in the fragment shader. I made this as an alternative for #1808 when for example making procedually generated terrain.
1 parent 6a8a8c9 commit 69af890

File tree

6 files changed

+83
-2
lines changed

6 files changed

+83
-2
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ path = "examples/3d/wireframe.rs"
181181
name = "z_sort_debug"
182182
path = "examples/3d/z_sort_debug.rs"
183183

184+
[[example]]
185+
name = "flat_shading"
186+
path = "examples/3d/flat_shading.rs"
187+
184188
# Application
185189
[[example]]
186190
name = "custom_loop"

crates/bevy_pbr/src/material.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ pub struct StandardMaterial {
4242
#[render_resources(ignore)]
4343
#[shader_def]
4444
pub unlit: bool,
45+
/// This allows for flat shading even with indiced meshes.
46+
#[render_resources(ignore)]
47+
#[shader_def]
48+
pub flat_shading: bool,
4549
}
4650

4751
impl Default for StandardMaterial {
@@ -69,6 +73,7 @@ impl Default for StandardMaterial {
6973
emissive: Color::BLACK,
7074
emissive_texture: None,
7175
unlit: false,
76+
flat_shading: false,
7277
}
7378
}
7479
}

crates/bevy_pbr/src/render_graph/pbr_pipeline/pbr.frag

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,17 @@ struct PointLight {
4343
vec4 color;
4444
vec4 lightParams;
4545
};
46-
46+
4747
struct DirectionalLight {
4848
vec4 direction;
4949
vec4 color;
5050
};
5151

5252
layout(location = 0) in vec3 v_WorldPosition;
53+
54+
#ifndef STANDARDMATERIAL_FLAT_SHADING
5355
layout(location = 1) in vec3 v_WorldNormal;
56+
#endif
5457
layout(location = 2) in vec2 v_Uv;
5558

5659
#ifdef STANDARDMATERIAL_NORMAL_MAP
@@ -368,7 +371,12 @@ void main() {
368371

369372
float roughness = perceptualRoughnessToRoughness(perceptual_roughness);
370373

371-
vec3 N = normalize(v_WorldNormal);
374+
# ifdef STANDARDMATERIAL_FLAT_SHADING
375+
vec3 N = normalize(cross(dFdy(v_WorldPosition), dFdx(v_WorldPosition)));
376+
# endif
377+
# ifndef STANDARDMATERIAL_FLAT_SHADING
378+
vec3 N = v_WorldNormal;
379+
# endif
372380

373381
# ifdef STANDARDMATERIAL_NORMAL_MAP
374382
vec3 T = normalize(v_WorldTangent.xyz);

crates/bevy_pbr/src/render_graph/pbr_pipeline/pbr.vert

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
#version 450
22

33
layout(location = 0) in vec3 Vertex_Position;
4+
#ifndef STANDARDMATERIAL_FLAT_SHADING
45
layout(location = 1) in vec3 Vertex_Normal;
6+
#endif
57
layout(location = 2) in vec2 Vertex_Uv;
68

79
#ifdef STANDARDMATERIAL_NORMAL_MAP
810
layout(location = 3) in vec4 Vertex_Tangent;
911
#endif
1012

1113
layout(location = 0) out vec3 v_WorldPosition;
14+
#ifndef STANDARDMATERIAL_FLAT_SHADING
1215
layout(location = 1) out vec3 v_WorldNormal;
16+
#endif
1317
layout(location = 2) out vec2 v_Uv;
1418

1519
layout(set = 0, binding = 0) uniform CameraViewProj {
@@ -27,7 +31,9 @@ layout(set = 2, binding = 0) uniform Transform {
2731
void main() {
2832
vec4 world_position = Model * vec4(Vertex_Position, 1.0);
2933
v_WorldPosition = world_position.xyz;
34+
#ifndef STANDARDMATERIAL_FLAT_SHADING
3035
v_WorldNormal = mat3(Model) * Vertex_Normal;
36+
#endif
3137
v_Uv = Vertex_Uv;
3238
#ifdef STANDARDMATERIAL_NORMAL_MAP
3339
v_WorldTangent = vec4(mat3(Model) * Vertex_Tangent.xyz, Vertex_Tangent.w);

examples/3d/flat_shading.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use bevy::prelude::*;
2+
3+
fn main() {
4+
App::new()
5+
.insert_resource(Msaa { samples: 4 })
6+
.add_plugins(DefaultPlugins)
7+
.add_startup_system(setup)
8+
.run();
9+
}
10+
11+
/// set up a simple 3D scene
12+
fn setup(
13+
mut commands: Commands,
14+
mut meshes: ResMut<Assets<Mesh>>,
15+
mut materials: ResMut<Assets<StandardMaterial>>,
16+
) {
17+
// flat
18+
commands.spawn_bundle(PbrBundle {
19+
mesh: meshes.add(Mesh::from(shape::Icosphere {
20+
radius: 0.5,
21+
subdivisions: 4,
22+
})),
23+
material: materials.add(StandardMaterial {
24+
base_color: Color::rgb(0.8, 0.7, 0.6),
25+
flat_shading: true,
26+
..Default::default()
27+
}),
28+
transform: Transform::from_xyz(-0.55, 0.5, 0.0),
29+
..Default::default()
30+
});
31+
// smooth
32+
commands.spawn_bundle(PbrBundle {
33+
mesh: meshes.add(Mesh::from(shape::Icosphere {
34+
radius: 0.5,
35+
subdivisions: 4,
36+
})),
37+
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
38+
transform: Transform::from_xyz(0.55, 0.5, 0.0),
39+
..Default::default()
40+
});
41+
// plane
42+
commands.spawn_bundle(PbrBundle {
43+
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
44+
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
45+
..Default::default()
46+
});
47+
// light
48+
commands.spawn_bundle(PointLightBundle {
49+
transform: Transform::from_xyz(5.0, 5.0, 5.0),
50+
..Default::default()
51+
});
52+
// camera
53+
commands.spawn_bundle(PerspectiveCameraBundle {
54+
transform: Transform::from_xyz(1.0, 3.0, 4.0).looking_at(Vec3::ZERO, Vec3::Y),
55+
..Default::default()
56+
});
57+
}

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ Example | File | Description
107107
`update_gltf_scene` | [`3d/update_gltf_scene.rs`](./3d/update_gltf_scene.rs) | Update a scene from a gltf file, either by spawning the scene as a child of another entity, or by accessing the entities of the scene
108108
`wireframe` | [`3d/wireframe.rs`](./3d/wireframe.rs) | Showcases wireframe rendering
109109
`z_sort_debug` | [`3d/z_sort_debug.rs`](./3d/z_sort_debug.rs) | Visualizes camera Z-ordering
110+
`flat_shading` | [`3d/flat_shading.rs`](./3d/flat_shading.rs) | Simple 3D scene showing flat and normal (smooth) shading
110111

111112
## Application
112113

0 commit comments

Comments
 (0)