mirror of
https://github.com/bevyengine/bevy
synced 2025-01-09 19:58:58 +00:00
6027890a11
# Objective `bevy_pbr/utils.wgsl` shader file contains mathematical constants and color conversion functions. Both of those should be accessible without enabling `bevy_pbr` feature. For example, tonemapping can be done in non pbr scenario, and it uses color conversion functions. Fixes #13207 ## Solution * Move mathematical constants (such as PI, E) from `bevy_pbr/src/render/utils.wgsl` into `bevy_render/src/maths.wgsl` * Move color conversion functions from `bevy_pbr/src/render/utils.wgsl` into new file `bevy_render/src/color_operations.wgsl` ## Testing Ran multiple examples, checked they are working: * tonemapping * color_grading * 3d_scene * animated_material * deferred_rendering * 3d_shapes * fog * irradiance_volumes * meshlet * parallax_mapping * pbr * reflection_probes * shadow_biases * 2d_gizmos * light_gizmos --- ## Changelog * Moved mathematical constants (such as PI, E) from `bevy_pbr/src/render/utils.wgsl` into `bevy_render/src/maths.wgsl` * Moved color conversion functions from `bevy_pbr/src/render/utils.wgsl` into new file `bevy_render/src/color_operations.wgsl` ## Migration Guide In user's shader code replace usage of mathematical constants from `bevy_pbr::utils` to the usage of the same constants from `bevy_render::maths`.
90 lines
2.8 KiB
WebGPU Shading Language
90 lines
2.8 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;
|
|
}
|