Path: blob/main/assets/shaders/custom_clustered_decal.wgsl
9441 views
// This shader, a part of the `clustered_decals` example, shows how to use the
// decal `tag` field to apply arbitrary decal effects.
#import bevy_pbr::{
clustered_forward,
decal::clustered,
forward_io::{VertexOutput, FragmentOutput},
mesh_view_bindings,
pbr_fragment::pbr_input_from_standard_material,
pbr_functions::{alpha_discard, apply_pbr_lighting, main_pass_post_lighting_processing},
}
@fragment
fn fragment(
in: VertexOutput,
@builtin(front_facing) is_front: bool,
) -> FragmentOutput {
// Generate a `PbrInput` struct from the `StandardMaterial` bindings.
var pbr_input = pbr_input_from_standard_material(in, is_front);
// Alpha discard.
pbr_input.material.base_color = alpha_discard(pbr_input.material, pbr_input.material.base_color);
// Apply the normal decals.
clustered::apply_decals(&pbr_input);
// Here we tint the color based on the tag of the decal.
// We could optionally do other things, such as adjust the normal based on a normal map.
let view_z = clustered::get_view_z(in.world_position.xyz);
let is_orthographic = clustered::view_is_orthographic();
let cluster_index =
clustered_forward::fragment_cluster_index(in.position.xy, view_z, is_orthographic);
var clusterable_object_index_ranges =
clustered_forward::unpack_clusterable_object_index_ranges(cluster_index);
var decal_iterator = clustered::clustered_decal_iterator_new(
in.world_position.xyz,
&clusterable_object_index_ranges
);
while (clustered::clustered_decal_iterator_next(&decal_iterator)) {
var decal_base_color = textureSampleLevel(
mesh_view_bindings::clustered_decal_textures[decal_iterator.base_color_texture_index],
mesh_view_bindings::clustered_decal_sampler,
decal_iterator.uv,
0.0
);
switch (decal_iterator.tag) {
case 1u: {
// Tint with red.
decal_base_color = vec4(
mix(pbr_input.material.base_color.rgb, vec3(1.0, 0.0, 0.0), 0.5),
decal_base_color.a,
);
}
case 2u: {
// Tint with blue.
decal_base_color = vec4(
mix(pbr_input.material.base_color.rgb, vec3(0.0, 0.0, 1.0), 0.5),
decal_base_color.a,
);
}
default: {}
}
pbr_input.material.base_color = vec4(
mix(pbr_input.material.base_color.rgb, decal_base_color.rgb, decal_base_color.a),
pbr_input.material.base_color.a + decal_base_color.a
);
}
// Apply lighting.
var out: FragmentOutput;
out.color = apply_pbr_lighting(pbr_input);
// Apply in-shader post processing (fog, alpha-premultiply, and also
// tonemapping, debanding if the camera is non-HDR). Note this does not
// include fullscreen postprocessing effects like bloom.
out.color = main_pass_post_lighting_processing(pbr_input, out.color);
return out;
}