mirror of
https://github.com/bevyengine/bevy
synced 2025-01-07 18:58:58 +00:00
cdc605cc48
Fixes #13118 If you use `Sprite` or `Mesh2d` and create `Camera` with * hdr=false * any tonemapper You would get ``` wgpu error: Validation Error Caused by: In Device::create_render_pipeline note: label = `sprite_pipeline` Error matching ShaderStages(FRAGMENT) shader requirements against the pipeline Shader global ResourceBinding { group: 0, binding: 19 } is not available in the pipeline layout Binding is missing from the pipeline layout ``` Because of missing tonemapping LUT bindings ## Solution Add missing bindings for tonemapping LUT's to `SpritePipeline` & `Mesh2dPipeline` ## Testing I checked that * `tonemapping` * `color_grading` * `sprite_animations` * `2d_shapes` * `meshlet` * `deferred_rendering` examples are still working 2d cases I checked with this code: ``` use bevy::{ color::palettes::css::PURPLE, core_pipeline::tonemapping::Tonemapping, prelude::*, sprite::MaterialMesh2dBundle, }; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, toggle_tonemapping_method) .run(); } fn setup( mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<ColorMaterial>>, asset_server: Res<AssetServer>, ) { commands.spawn(Camera2dBundle { camera: Camera { hdr: false, ..default() }, tonemapping: Tonemapping::BlenderFilmic, ..default() }); commands.spawn(MaterialMesh2dBundle { mesh: meshes.add(Rectangle::default()).into(), transform: Transform::default().with_scale(Vec3::splat(128.)), material: materials.add(Color::from(PURPLE)), ..default() }); commands.spawn(SpriteBundle { texture: asset_server.load("asd.png"), ..default() }); } fn toggle_tonemapping_method( keys: Res<ButtonInput<KeyCode>>, mut tonemapping: Query<&mut Tonemapping>, ) { let mut method = tonemapping.single_mut(); if keys.just_pressed(KeyCode::Digit1) { *method = Tonemapping::None; } else if keys.just_pressed(KeyCode::Digit2) { *method = Tonemapping::Reinhard; } else if keys.just_pressed(KeyCode::Digit3) { *method = Tonemapping::ReinhardLuminance; } else if keys.just_pressed(KeyCode::Digit4) { *method = Tonemapping::AcesFitted; } else if keys.just_pressed(KeyCode::Digit5) { *method = Tonemapping::AgX; } else if keys.just_pressed(KeyCode::Digit6) { *method = Tonemapping::SomewhatBoringDisplayTransform; } else if keys.just_pressed(KeyCode::Digit7) { *method = Tonemapping::TonyMcMapface; } else if keys.just_pressed(KeyCode::Digit8) { *method = Tonemapping::BlenderFilmic; } } ``` --- ## Changelog Fix the bug which led to the crash when user uses any tonemapper without hdr for rendering sprites and 2d meshes.
95 lines
2.9 KiB
WebGPU Shading Language
95 lines
2.9 KiB
WebGPU Shading Language
#define_import_path bevy_render::maths
|
|
|
|
const PI: f32 = 3.141592653589793; // π
|
|
const PI_2: f32 = 6.283185307179586; // 2π
|
|
const HALF_PI: f32 = 1.57079632679; // π/2
|
|
const FRAC_PI_3: f32 = 1.0471975512; // π/3
|
|
const E: f32 = 2.718281828459045; // exp(1)
|
|
|
|
fn affine2_to_square(affine: mat3x2<f32>) -> mat3x3<f32> {
|
|
return mat3x3<f32>(
|
|
vec3<f32>(affine[0].xy, 0.0),
|
|
vec3<f32>(affine[1].xy, 0.0),
|
|
vec3<f32>(affine[2].xy, 1.0),
|
|
);
|
|
}
|
|
|
|
fn affine3_to_square(affine: mat3x4<f32>) -> mat4x4<f32> {
|
|
return transpose(mat4x4<f32>(
|
|
affine[0],
|
|
affine[1],
|
|
affine[2],
|
|
vec4<f32>(0.0, 0.0, 0.0, 1.0),
|
|
));
|
|
}
|
|
|
|
fn mat2x4_f32_to_mat3x3_unpack(
|
|
a: mat2x4<f32>,
|
|
b: f32,
|
|
) -> mat3x3<f32> {
|
|
return mat3x3<f32>(
|
|
a[0].xyz,
|
|
vec3<f32>(a[0].w, a[1].xy),
|
|
vec3<f32>(a[1].zw, b),
|
|
);
|
|
}
|
|
|
|
// Extracts the square portion of an affine matrix: i.e. discards the
|
|
// translation.
|
|
fn affine3_to_mat3x3(affine: mat4x3<f32>) -> mat3x3<f32> {
|
|
return mat3x3<f32>(affine[0].xyz, affine[1].xyz, affine[2].xyz);
|
|
}
|
|
|
|
// Returns the inverse of a 3x3 matrix.
|
|
fn inverse_mat3x3(matrix: mat3x3<f32>) -> mat3x3<f32> {
|
|
let tmp0 = cross(matrix[1], matrix[2]);
|
|
let tmp1 = cross(matrix[2], matrix[0]);
|
|
let tmp2 = cross(matrix[0], matrix[1]);
|
|
let inv_det = 1.0 / dot(matrix[2], tmp2);
|
|
return transpose(mat3x3<f32>(tmp0 * inv_det, tmp1 * inv_det, tmp2 * inv_det));
|
|
}
|
|
|
|
// Returns the inverse of an affine matrix.
|
|
//
|
|
// https://en.wikipedia.org/wiki/Affine_transformation#Groups
|
|
fn inverse_affine3(affine: mat4x3<f32>) -> mat4x3<f32> {
|
|
let matrix3 = affine3_to_mat3x3(affine);
|
|
let inv_matrix3 = inverse_mat3x3(matrix3);
|
|
return mat4x3<f32>(inv_matrix3[0], inv_matrix3[1], inv_matrix3[2], -(inv_matrix3 * affine[3]));
|
|
}
|
|
|
|
// Extracts the upper 3x3 portion of a 4x4 matrix.
|
|
fn mat4x4_to_mat3x3(m: mat4x4<f32>) -> mat3x3<f32> {
|
|
return mat3x3<f32>(m[0].xyz, m[1].xyz, m[2].xyz);
|
|
}
|
|
|
|
// Creates an orthonormal basis given a Z vector and an up vector (which becomes
|
|
// Y after orthonormalization).
|
|
//
|
|
// The results are equivalent to the Gram-Schmidt process [1].
|
|
//
|
|
// [1]: https://math.stackexchange.com/a/1849294
|
|
fn orthonormalize(z_unnormalized: vec3<f32>, up: vec3<f32>) -> mat3x3<f32> {
|
|
let z_basis = normalize(z_unnormalized);
|
|
let x_basis = normalize(cross(z_basis, up));
|
|
let y_basis = cross(z_basis, x_basis);
|
|
return mat3x3(x_basis, y_basis, z_basis);
|
|
}
|
|
|
|
// Returns true if any part of a sphere is on the positive side of a plane.
|
|
//
|
|
// `sphere_center.w` should be 1.0.
|
|
//
|
|
// This is used for frustum culling.
|
|
fn sphere_intersects_plane_half_space(
|
|
plane: vec4<f32>,
|
|
sphere_center: vec4<f32>,
|
|
sphere_radius: f32
|
|
) -> bool {
|
|
return dot(plane, sphere_center) + sphere_radius > 0.0;
|
|
}
|
|
|
|
// pow() but safe for NaNs/negatives
|
|
fn powsafe(color: vec3<f32>, power: f32) -> vec3<f32> {
|
|
return pow(abs(color), vec3(power)) * sign(color);
|
|
}
|