mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 05:33:04 +00:00
move wgsl color operations from bevy_pbr to bevy_render (#13209)
# 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`.
This commit is contained in:
parent
40837501b4
commit
6027890a11
14 changed files with 92 additions and 64 deletions
|
@ -1,9 +1,10 @@
|
|||
#import bevy_pbr::{
|
||||
mesh_view_bindings,
|
||||
forward_io::VertexOutput,
|
||||
utils::PI,
|
||||
}
|
||||
|
||||
#import bevy_render::maths::PI
|
||||
|
||||
#ifdef TONEMAP_IN_SHADER
|
||||
#import bevy_core_pipeline::tonemapping::tone_mapping
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#define_import_path bevy_core_pipeline::tonemapping
|
||||
|
||||
#import bevy_render::view::ColorGrading
|
||||
#import bevy_pbr::utils::{PI_2, hsv_to_rgb, rgb_to_hsv};
|
||||
#import bevy_render::{
|
||||
view::ColorGrading,
|
||||
color_operations::{hsv_to_rgb, rgb_to_hsv},
|
||||
maths::PI_2
|
||||
}
|
||||
|
||||
// hack !! not sure what to do with this
|
||||
#ifdef TONEMAPPING_PASS
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
#import bevy_pbr::{
|
||||
mesh_view_bindings as bindings,
|
||||
utils::{PI_2, hsv_to_rgb, rand_f},
|
||||
utils::rand_f,
|
||||
}
|
||||
|
||||
#import bevy_render::{
|
||||
color_operations::hsv_to_rgb,
|
||||
maths::PI_2,
|
||||
}
|
||||
|
||||
// NOTE: Keep in sync with bevy_pbr/src/light.rs
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
ambient,
|
||||
irradiance_volume,
|
||||
mesh_types::{MESH_FLAGS_SHADOW_RECEIVER_BIT, MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT},
|
||||
utils::E,
|
||||
}
|
||||
|
||||
#import bevy_render::maths::E
|
||||
|
||||
#ifdef ENVIRONMENT_MAP
|
||||
#import bevy_pbr::environment_map
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#define_import_path bevy_pbr::lighting
|
||||
|
||||
#import bevy_pbr::{
|
||||
utils::PI,
|
||||
mesh_view_types::POINT_LIGHT_FLAGS_SPOT_LIGHT_Y_NEGATIVE,
|
||||
mesh_view_bindings as view_bindings,
|
||||
}
|
||||
|
||||
#import bevy_render::maths::PI
|
||||
|
||||
// From the Filament design doc
|
||||
// https://google.github.io/filament/Filament.html#table_symbols
|
||||
// Symbol Definition
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
#import bevy_pbr::{
|
||||
lighting,
|
||||
prepass_utils,
|
||||
utils::{PI, interleaved_gradient_noise},
|
||||
utils::interleaved_gradient_noise,
|
||||
utils,
|
||||
mesh_view_bindings as view_bindings,
|
||||
};
|
||||
|
||||
#import bevy_render::maths::PI
|
||||
|
||||
#import bevy_core_pipeline::tonemapping::{
|
||||
approximate_inverse_tone_mapping
|
||||
};
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
#import bevy_pbr::{
|
||||
mesh_view_bindings as view_bindings,
|
||||
utils::{PI, interleaved_gradient_noise},
|
||||
utils::interleaved_gradient_noise,
|
||||
utils,
|
||||
}
|
||||
#import bevy_render::maths::orthonormalize
|
||||
#import bevy_render::maths::{orthonormalize, PI}
|
||||
|
||||
// Do the lookup, using HW 2x2 PCF and comparison
|
||||
fn sample_shadow_map_hardware(light_local: vec2<f32>, depth: f32, array_index: i32) -> f32 {
|
||||
|
|
|
@ -3,10 +3,14 @@
|
|||
#import bevy_pbr::{
|
||||
mesh_view_types::POINT_LIGHT_FLAGS_SPOT_LIGHT_Y_NEGATIVE,
|
||||
mesh_view_bindings as view_bindings,
|
||||
utils::{hsv_to_rgb, PI_2},
|
||||
shadow_sampling::{SPOT_SHADOW_TEXEL_SIZE, sample_shadow_cubemap, sample_shadow_map}
|
||||
}
|
||||
|
||||
#import bevy_render::{
|
||||
color_operations::hsv_to_rgb,
|
||||
maths::PI_2
|
||||
}
|
||||
|
||||
const flip_z: vec3<f32> = vec3<f32>(1.0, 1.0, -1.0);
|
||||
|
||||
fn fetch_point_shadow(light_id: u32, frag_position: vec4<f32>, surface_normal: vec3<f32>) -> f32 {
|
||||
|
|
|
@ -2,55 +2,6 @@
|
|||
|
||||
#import bevy_pbr::rgb9e5
|
||||
|
||||
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)
|
||||
|
||||
// Converts HSV to RGB.
|
||||
//
|
||||
// Input: H ∈ [0, 2π), S ∈ [0, 1], V ∈ [0, 1].
|
||||
// Output: R ∈ [0, 1], G ∈ [0, 1], B ∈ [0, 1].
|
||||
//
|
||||
// <https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative>
|
||||
fn hsv_to_rgb(hsv: vec3<f32>) -> vec3<f32> {
|
||||
let n = vec3(5.0, 3.0, 1.0);
|
||||
let k = (n + hsv.x / FRAC_PI_3) % 6.0;
|
||||
return hsv.z - hsv.z * hsv.y * max(vec3(0.0), min(k, min(4.0 - k, vec3(1.0))));
|
||||
}
|
||||
|
||||
// Converts RGB to HSV.
|
||||
//
|
||||
// Input: R ∈ [0, 1], G ∈ [0, 1], B ∈ [0, 1].
|
||||
// Output: H ∈ [0, 2π), S ∈ [0, 1], V ∈ [0, 1].
|
||||
//
|
||||
// <https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB>
|
||||
fn rgb_to_hsv(rgb: vec3<f32>) -> vec3<f32> {
|
||||
let x_max = max(rgb.r, max(rgb.g, rgb.b)); // i.e. V
|
||||
let x_min = min(rgb.r, min(rgb.g, rgb.b));
|
||||
let c = x_max - x_min; // chroma
|
||||
|
||||
var swizzle = vec3<f32>(0.0);
|
||||
if (x_max == rgb.r) {
|
||||
swizzle = vec3(rgb.gb, 0.0);
|
||||
} else if (x_max == rgb.g) {
|
||||
swizzle = vec3(rgb.br, 2.0);
|
||||
} else {
|
||||
swizzle = vec3(rgb.rg, 4.0);
|
||||
}
|
||||
|
||||
let h = FRAC_PI_3 * (((swizzle.x - swizzle.y) / c + swizzle.z) % 6.0);
|
||||
|
||||
// Avoid division by zero.
|
||||
var s = 0.0;
|
||||
if (x_max > 0.0) {
|
||||
s = c / x_max;
|
||||
}
|
||||
|
||||
return vec3(h, s, x_max);
|
||||
}
|
||||
|
||||
// Generates a random u32 in range [0, u32::MAX].
|
||||
//
|
||||
// `state` is a mutable reference to a u32 used as the seed.
|
||||
|
|
|
@ -5,13 +5,12 @@
|
|||
// Source code heavily based on XeGTAO v1.30 from Intel
|
||||
// https://github.com/GameTechDev/XeGTAO/blob/0d177ce06bfa642f64d8af4de1197ad1bcb862d4/Source/Rendering/Shaders/XeGTAO.hlsli
|
||||
|
||||
#import bevy_pbr::{
|
||||
gtao_utils::fast_acos,
|
||||
utils::{PI, HALF_PI},
|
||||
}
|
||||
#import bevy_pbr::gtao_utils::fast_acos
|
||||
|
||||
#import bevy_render::{
|
||||
view::View,
|
||||
globals::Globals,
|
||||
maths::{PI, HALF_PI},
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var preprocessed_depth: texture_2d<f32>;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define_import_path bevy_pbr::gtao_utils
|
||||
|
||||
#import bevy_pbr::utils::{PI, HALF_PI}
|
||||
#import bevy_render::maths::{PI, HALF_PI}
|
||||
|
||||
// Approximates single-bounce ambient occlusion to multi-bounce ambient occlusion
|
||||
// https://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf#page=78
|
||||
|
|
47
crates/bevy_render/src/color_operations.wgsl
Normal file
47
crates/bevy_render/src/color_operations.wgsl
Normal file
|
@ -0,0 +1,47 @@
|
|||
#define_import_path bevy_render::color_operations
|
||||
|
||||
#import bevy_render::maths::FRAC_PI_3
|
||||
|
||||
// Converts HSV to RGB.
|
||||
//
|
||||
// Input: H ∈ [0, 2π), S ∈ [0, 1], V ∈ [0, 1].
|
||||
// Output: R ∈ [0, 1], G ∈ [0, 1], B ∈ [0, 1].
|
||||
//
|
||||
// <https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative>
|
||||
fn hsv_to_rgb(hsv: vec3<f32>) -> vec3<f32> {
|
||||
let n = vec3(5.0, 3.0, 1.0);
|
||||
let k = (n + hsv.x / FRAC_PI_3) % 6.0;
|
||||
return hsv.z - hsv.z * hsv.y * max(vec3(0.0), min(k, min(4.0 - k, vec3(1.0))));
|
||||
}
|
||||
|
||||
// Converts RGB to HSV.
|
||||
//
|
||||
// Input: R ∈ [0, 1], G ∈ [0, 1], B ∈ [0, 1].
|
||||
// Output: H ∈ [0, 2π), S ∈ [0, 1], V ∈ [0, 1].
|
||||
//
|
||||
// <https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB>
|
||||
fn rgb_to_hsv(rgb: vec3<f32>) -> vec3<f32> {
|
||||
let x_max = max(rgb.r, max(rgb.g, rgb.b)); // i.e. V
|
||||
let x_min = min(rgb.r, min(rgb.g, rgb.b));
|
||||
let c = x_max - x_min; // chroma
|
||||
|
||||
var swizzle = vec3<f32>(0.0);
|
||||
if (x_max == rgb.r) {
|
||||
swizzle = vec3(rgb.gb, 0.0);
|
||||
} else if (x_max == rgb.g) {
|
||||
swizzle = vec3(rgb.br, 2.0);
|
||||
} else {
|
||||
swizzle = vec3(rgb.rg, 4.0);
|
||||
}
|
||||
|
||||
let h = FRAC_PI_3 * (((swizzle.x - swizzle.y) / c + swizzle.z) % 6.0);
|
||||
|
||||
// Avoid division by zero.
|
||||
var s = 0.0;
|
||||
if (x_max > 0.0) {
|
||||
s = c / x_max;
|
||||
}
|
||||
|
||||
return vec3(h, s, x_max);
|
||||
}
|
||||
|
|
@ -236,6 +236,8 @@ pub struct RenderApp;
|
|||
pub const INSTANCE_INDEX_SHADER_HANDLE: Handle<Shader> =
|
||||
Handle::weak_from_u128(10313207077636615845);
|
||||
pub const MATHS_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(10665356303104593376);
|
||||
pub const COLOR_OPERATIONS_SHADER_HANDLE: Handle<Shader> =
|
||||
Handle::weak_from_u128(1844674407370955161);
|
||||
|
||||
impl Plugin for RenderPlugin {
|
||||
/// Initializes the renderer, sets up the [`RenderSet`] and creates the rendering sub-app.
|
||||
|
@ -359,6 +361,12 @@ impl Plugin for RenderPlugin {
|
|||
|
||||
fn finish(&self, app: &mut App) {
|
||||
load_internal_asset!(app, MATHS_SHADER_HANDLE, "maths.wgsl", Shader::from_wgsl);
|
||||
load_internal_asset!(
|
||||
app,
|
||||
COLOR_OPERATIONS_SHADER_HANDLE,
|
||||
"color_operations.wgsl",
|
||||
Shader::from_wgsl
|
||||
);
|
||||
if let Some(future_renderer_resources) =
|
||||
app.world_mut().remove_resource::<FutureRendererResources>()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#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),
|
||||
|
|
Loading…
Reference in a new issue