Skip to content

Commit ea2ecd4

Browse files
robtfmatlv24
andcommitted
add ambient lighting hook (#5428)
# Objective add a hook for ambient occlusion to the pbr shader ## Solution add a hook for ambient occlusion to the pbr shader Co-authored-by: atlas dostal <[email protected]>
1 parent 0cbb9f7 commit ea2ecd4

File tree

4 files changed

+32
-7
lines changed

4 files changed

+32
-7
lines changed

crates/bevy_pbr/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ pub const PBR_PREPASS_SHADER_HANDLE: HandleUntyped =
7575
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 9407115064344201137);
7676
pub const PBR_FUNCTIONS_HANDLE: HandleUntyped =
7777
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 16550102964439850292);
78+
pub const PBR_AMBIENT_HANDLE: HandleUntyped =
79+
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 2441520459096337034);
7880
pub const SHADOW_SHADER_HANDLE: HandleUntyped =
7981
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 1836745567947005696);
8082

@@ -132,6 +134,12 @@ impl Plugin for PbrPlugin {
132134
"render/pbr_functions.wgsl",
133135
Shader::from_wgsl
134136
);
137+
load_internal_asset!(
138+
app,
139+
PBR_AMBIENT_HANDLE,
140+
"render/pbr_ambient.wgsl",
141+
Shader::from_wgsl
142+
);
135143
load_internal_asset!(app, PBR_SHADER_HANDLE, "render/pbr.wgsl", Shader::from_wgsl);
136144
load_internal_asset!(
137145
app,

crates/bevy_pbr/src/render/pbr.wgsl

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#import bevy_pbr::utils
66
#import bevy_pbr::clustered_forward
77
#import bevy_pbr::lighting
8+
#import bevy_pbr::pbr_ambient
89
#import bevy_pbr::shadows
910
#import bevy_pbr::fog
1011
#import bevy_pbr::pbr_functions
@@ -66,8 +67,6 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
6667
occlusion = textureSample(occlusion_texture, occlusion_sampler, in.uv).r;
6768
}
6869
#endif
69-
pbr_input.occlusion = occlusion;
70-
7170
pbr_input.frag_coord = in.frag_coord;
7271
pbr_input.world_position = in.world_position;
7372
pbr_input.world_normal = prepare_world_normal(
@@ -91,6 +90,8 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
9190
#endif
9291
);
9392
pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic);
93+
pbr_input.occlusion = occlusion;
94+
9495
output_color = pbr(pbr_input);
9596
} else {
9697
output_color = alpha_discard(material, output_color);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#define_import_path bevy_pbr::pbr_ambient
2+
3+
// A precomputed `NdotV` is provided because it is computed regardless,
4+
// but `world_normal` and the view vector `V` are provided separately for more advanced uses.
5+
fn ambient_light(
6+
world_position: vec4<f32>,
7+
world_normal: vec3<f32>,
8+
V: vec3<f32>,
9+
NdotV: f32,
10+
diffuse_color: vec3<f32>,
11+
specular_color: vec3<f32>,
12+
perceptual_roughness: f32,
13+
occlusion: f32,
14+
) -> vec3<f32> {
15+
let diffuse_ambient = EnvBRDFApprox(diffuse_color, 1.0, NdotV);
16+
let specular_ambient = EnvBRDFApprox(specular_color, perceptual_roughness, NdotV);
17+
18+
return (diffuse_ambient + specular_ambient) * lights.ambient_color.rgb * occlusion;
19+
}

crates/bevy_pbr/src/render/pbr_functions.wgsl

+2-5
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,10 @@ fn pbr(
233233
light_accum = light_accum + light_contrib * shadow;
234234
}
235235

236-
let diffuse_ambient = EnvBRDFApprox(diffuse_color, 1.0, NdotV);
237-
let specular_ambient = EnvBRDFApprox(F0, perceptual_roughness, NdotV);
236+
let ambient_contrib = ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, occlusion);
238237

239238
output_color = vec4<f32>(
240-
light_accum
241-
+ (diffuse_ambient + specular_ambient) * lights.ambient_color.rgb * occlusion
242-
+ emissive.rgb * output_color.a,
239+
light_accum + ambient_contrib + emissive.rgb * output_color.a,
243240
output_color.a
244241
);
245242

0 commit comments

Comments
 (0)