bevy/assets/shaders/tonemapping_test_patterns.wgsl
Griffin 912fb58869 Initial tonemapping options (#7594)
# Objective

Splits tone mapping from https://github.com/bevyengine/bevy/pull/6677 into a separate PR.
Address https://github.com/bevyengine/bevy/issues/2264.
Adds tone mapping options:
- None: Bypasses tonemapping for instances where users want colors output to match those set.
- Reinhard
- Reinhard Luminance: Bevy's exiting tonemapping
- [ACES](https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl) (Fitted version, based on the same implementation that Godot 4 uses) see https://github.com/bevyengine/bevy/issues/2264
- [AgX](https://github.com/sobotka/AgX)
- SomewhatBoringDisplayTransform
- TonyMcMapface
- Blender Filmic

This PR also adds support for EXR images so they can be used to compare tonemapping options with reference images.

## Migration Guide
- Tonemapping is now an enum with NONE and the various tonemappers.
- The DebandDither is now a separate component.




Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2023-02-19 20:38:13 +00:00

64 lines
1.8 KiB
WebGPU Shading Language

#import bevy_pbr::mesh_view_bindings
#import bevy_pbr::mesh_bindings
#import bevy_pbr::utils
#ifdef TONEMAP_IN_SHADER
#import bevy_core_pipeline::tonemapping
#endif
struct FragmentInput {
@builtin(front_facing) is_front: bool,
@builtin(position) frag_coord: vec4<f32>,
#import bevy_pbr::mesh_vertex_output
};
// Sweep across hues on y axis with value from 0.0 to +15EV across x axis
// quantized into 24 steps for both axis.
fn color_sweep(uv: vec2<f32>) -> vec3<f32> {
var uv = uv;
let steps = 24.0;
uv.y = uv.y * (1.0 + 1.0 / steps);
let ratio = 2.0;
let h = PI * 2.0 * floor(1.0 + steps * uv.y) / steps;
let L = floor(uv.x * steps * ratio) / (steps * ratio) - 0.5;
var color = vec3(0.0);
if uv.y < 1.0 {
color = cos(h + vec3(0.0, 1.0, 2.0) * PI * 2.0 / 3.0);
let maxRGB = max(color.r, max(color.g, color.b));
let minRGB = min(color.r, min(color.g, color.b));
color = exp(15.0 * L) * (color - minRGB) / (maxRGB - minRGB);
} else {
color = vec3(exp(15.0 * L));
}
return color;
}
fn hsv_to_srgb(c: vec3<f32>) -> vec3<f32> {
let K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
let p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, vec3(0.0), vec3(1.0)), c.y);
}
// Generates a continuous sRGB sweep.
fn continuous_hue(uv: vec2<f32>) -> vec3<f32> {
return hsv_to_srgb(vec3(uv.x, 1.0, 1.0)) * max(0.0, exp2(uv.y * 9.0) - 1.0);
}
@fragment
fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
var uv = in.uv;
var out = vec3(0.0);
if uv.y > 0.5 {
uv.y = 1.0 - uv.y;
out = color_sweep(vec2(uv.x, uv.y * 2.0));
} else {
out = continuous_hue(vec2(uv.y * 2.0, uv.x));
}
var color = vec4(out, 1.0);
#ifdef TONEMAP_IN_SHADER
color = tone_mapping(color);
#endif
return color;
}