bevy/assets/shaders/array_texture.wgsl
JMS55 4bf20e7d27
Swap material and mesh bind groups (#10485)
# Objective
- Materials should be a more frequent rebind then meshes (due to being
able to use a single vertex buffer, such as in #10164) and therefore
should be in a higher bind group.

---

## Changelog
- For 2d and 3d mesh/material setups (but not UI materials, or other
rendering setups such as gizmos, sprites, or text), mesh data is now in
bind group 1, and material data is now in bind group 2, which is swapped
from how they were before.

## Migration Guide
- Custom 2d and 3d mesh/material shaders should now use bind group 2
`@group(2) @binding(x)` for their bound resources, instead of bind group
1.
- Many internal pieces of rendering code have changed so that mesh data
is now in bind group 1, and material data is now in bind group 2.
Semi-custom rendering setups (that don't use the Material or Material2d
APIs) should adapt to these changes.
2023-11-28 22:26:22 +00:00

56 lines
1.7 KiB
WebGPU Shading Language

#import bevy_pbr::{
forward_io::VertexOutput,
mesh_view_bindings::view,
pbr_types::{STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT, PbrInput, pbr_input_new},
pbr_functions as fns,
}
#import bevy_core_pipeline::tonemapping::tone_mapping
@group(2) @binding(0) var my_array_texture: texture_2d_array<f32>;
@group(2) @binding(1) var my_array_texture_sampler: sampler;
@fragment
fn fragment(
@builtin(front_facing) is_front: bool,
mesh: VertexOutput,
) -> @location(0) vec4<f32> {
let layer = i32(mesh.world_position.x) & 0x3;
// Prepare a 'processed' StandardMaterial by sampling all textures to resolve
// the material members
var pbr_input: PbrInput = pbr_input_new();
pbr_input.material.base_color = textureSample(my_array_texture, my_array_texture_sampler, mesh.uv, layer);
#ifdef VERTEX_COLORS
pbr_input.material.base_color = pbr_input.material.base_color * mesh.color;
#endif
let double_sided = (pbr_input.material.flags & STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u;
pbr_input.frag_coord = mesh.position;
pbr_input.world_position = mesh.world_position;
pbr_input.world_normal = fns::prepare_world_normal(
mesh.world_normal,
double_sided,
is_front,
);
pbr_input.is_orthographic = view.projection[3].w == 1.0;
pbr_input.N = fns::apply_normal_mapping(
pbr_input.material.flags,
mesh.world_normal,
double_sided,
is_front,
#ifdef VERTEX_TANGENTS
#ifdef STANDARDMATERIAL_NORMAL_MAP
mesh.world_tangent,
#endif
#endif
mesh.uv,
view.mip_bias,
);
pbr_input.V = fns::calculate_view(mesh.world_position, pbr_input.is_orthographic);
return tone_mapping(fns::apply_pbr_lighting(pbr_input), view.color_grading);
}