fn is_nan(x: f32) -> bool {
return x != x;
}
fn is_inf(x: f32) -> bool {
return abs(x) > 1e20;
}
fn is_nan3(v: vec3<f32>) -> bool {
return is_nan(v.x) || is_nan(v.y) || is_nan(v.z);
}
fn is_inf3(v: vec3<f32>) -> bool {
return abs(v.x) > 1e20 || abs(v.y) > 1e20 || abs(v.z) > 1e20;
}
fn luminance(color: vec3<f32>) -> f32 {
return dot(color, vec3<f32>(0.2126, 0.7152, 0.0722));
}
fn float_to_int(f: f32) -> i32 {
return bitcast<i32>(f);
}
fn int_to_float(i: i32) -> f32 {
return bitcast<f32>(i);
}
fn srgb_to_linear(rgb: vec3<f32>) -> vec3<f32> {
return select(pow((rgb + 0.055) * (1.0 / 1.055), vec3<f32>(2.4)), rgb * (1.0 / 12.92), rgb <= vec3<f32>(0.04045));
}
fn clamp_hdr(color: vec3<f32>, max_luminance: f32) -> vec3<f32> {
let lum = dot(color, vec3f(0.2126, 0.7152, 0.0722));
return color * min(1.0, max_luminance / max(lum, 1e-6));
}