Skip to content

Commit eed3444

Browse files
committed
Add support for flat shading using indices
Will apply the flat interpolation qualifier for vertex_normal, this uses the provoking vertex for the whole primitive in the fragment shader, so mostly useful for custom meshes. I made this as an alternative for bevyengine#1808 when for example making procedually generated terrain.
1 parent 6a8a8c9 commit eed3444

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

crates/bevy_pbr/src/material.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ pub struct StandardMaterial {
4242
#[render_resources(ignore)]
4343
#[shader_def]
4444
pub unlit: bool,
45+
/// Use the 'flat' Type Qualifier for the normal vectors.
46+
/// This allows for flat shading even with indiced meshes.
47+
/// The normal that is used for the whole primitive in the fragment
48+
/// shader will be the [Provoking Vertex](https://www.khronos.org/opengl/wiki/Primitive#Provoking_vertex)
49+
#[render_resources(ignore)]
50+
#[shader_def]
51+
pub flat_shading: bool,
4552
}
4653

4754
impl Default for StandardMaterial {
@@ -69,6 +76,7 @@ impl Default for StandardMaterial {
6976
emissive: Color::BLACK,
7077
emissive_texture: None,
7178
unlit: false,
79+
flat_shading: false,
7280
}
7381
}
7482
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ struct DirectionalLight {
5050
};
5151

5252
layout(location = 0) in vec3 v_WorldPosition;
53+
54+
#ifdef STANDARDMATERIAL_FLAT_SHADING
55+
layout(location = 1) flat in vec3 v_WorldNormal;
56+
#endif
57+
#ifndef STANDARDMATERIAL_FLAT_SHADING
5358
layout(location = 1) in vec3 v_WorldNormal;
59+
#endif
5460
layout(location = 2) in vec2 v_Uv;
5561

5662
#ifdef STANDARDMATERIAL_NORMAL_MAP

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ layout(location = 3) in vec4 Vertex_Tangent;
99
#endif
1010

1111
layout(location = 0) out vec3 v_WorldPosition;
12+
#ifdef STANDARDMATERIAL_FLAT_SHADING
13+
layout(location = 1) flat out vec3 v_WorldNormal;
14+
#endif
15+
#ifndef STANDARDMATERIAL_FLAT_SHADING
1216
layout(location = 1) out vec3 v_WorldNormal;
17+
#endif
1318
layout(location = 2) out vec2 v_Uv;
1419

1520
layout(set = 0, binding = 0) uniform CameraViewProj {

examples/3d/3d_scene.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,26 @@ fn setup(
2020
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
2121
..Default::default()
2222
});
23+
// flat shaded Icosphere
24+
commands.spawn_bundle(PbrBundle {
25+
mesh: meshes.add(Mesh::from(shape::Icosphere {
26+
radius: 0.45,
27+
subdivisions: 2,
28+
})),
29+
material: materials.add(StandardMaterial {
30+
base_color: Color::hex("ffd891").unwrap(),
31+
// vary key PBR parameters on a grid of spheres to show the effect
32+
flat_shading: true,
33+
..Default::default()
34+
}),
35+
transform: Transform::from_xyz(-0.5, 0.5, 0.0),
36+
..Default::default()
37+
});
2338
// cube
2439
commands.spawn_bundle(PbrBundle {
2540
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
2641
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
27-
transform: Transform::from_xyz(0.0, 0.5, 0.0),
42+
transform: Transform::from_xyz(0.6, 0.5, 0.0),
2843
..Default::default()
2944
});
3045
// light

0 commit comments

Comments
 (0)