PAOLWMH7TLJLNAWBJBWP7KB7YGDFUPASMTFU33KZ3QW5JXJMPXCAC
KID2E3YKLHUFPHWYYGRQZTX73THWMAXQWPT5XZEJJO46BCQD27HQC
GHIHJCWBCGFZI4AG66L7WG4WKJ467DXFBRBNLT4ZULSN7ZVBJI6AC
GROTV3H2V6BHU5CA7WSLVYDCWAR7GHUP5JV2QOGPLJ6N3553T4MAC
MT6IBX7SGLE26XIFZY53WYNHSJZMSDVDRJP3VYPXIQ4DKY75XVXAC
TYNRXPBJZM6GLDBYVMFJS6NVWX7MFRQSHHDOEM6I7EG5CG6UIBKQC
L6RIUKGLJZLAOKFGUDTZKBPP4HUBPEZAKHJEQHO34WFF62AB2ZIQC
X5EMQBC4BFNJOOHS2QMF4UB4QH6JKSALK6RXLK6B7SP6MNYSAP6QC
4RVKY4GPSLJ354NLVZDZFB7UFRMOTIC22NQIHYPEU6FKYLKBN75QC
NS7EOR3SRISITX6SBHBOJIYTINDN2ZBL2QY64H6FNJJ3I2I3PYGQC
fn meets_thresh(color: vec4<f32>) -> bool {
// stack overflow magic \sqrt{0.299\cdot r^{2}+0.587\cdot g^{2}+0.114\cdot b^{2}}
let brightness = sqrt(dot(color.rgb * color.rgb, vec3<f32>(0.299, 0.587, 0.114)));
return brightness > 0.1;
}
const PI = 3.14159265359;
const STD_DEV: f32 = 6.8;
fn weight_calc(i: u32) -> f32 {
let STD_DEV_P2 = pow(STD_DEV, 2.0);
// use the gaussian kernel, until it's too slow otherwise
return (1.0 / sqrt(2.0 * PI * STD_DEV_P2)) * exp(-pow(f32(i), 2.0) / (2.0 * STD_DEV_P2));
}
var textureOffset = vec2<f32>(1) / vec2<f32>(textureDimensions(t_world));
var result = in.color * textureSample(t_world, s_world, in.tex_coords);
let strength = 2.0;
var added: vec4<f32>;
// let offset = vec2<f32>(textureOffset.x, textureOffset.y);
let offset_y = vec2<f32>(0.0, textureOffset.y);
let offset_x = vec2<f32>(textureOffset.x, 0.0);
for(var i: u32 = 0; i < 5; i++) {
let new_color_a = textureSample(t_world, s_world, in.tex_coords + offset_x * f32(i));
let new_color_b = textureSample(t_world, s_world, in.tex_coords - offset_x * f32(i));
if (meets_thresh(new_color_a)) {
// result += vec4<f32>(new_color_a.rgb * weight[i], 0);
added += vec4<f32>(new_color_a.rgb, 1.0 / strength) * weight_calc(i) * strength;
}
if (meets_thresh(new_color_b)) {
// result += vec4<f32>(new_color_b.rgb * weight[i], 0);
added += vec4<f32>(new_color_b.rgb, 1.0 / strength) * weight_calc(i) * strength;
}
let new_color_c = textureSample(t_world, s_world, in.tex_coords + offset_y * f32(i)) + added;
let new_color_d = textureSample(t_world, s_world, in.tex_coords - offset_y * f32(i)) + added;
if (meets_thresh(new_color_c)) {
// result += vec4<f32>(new_color_a.rgb * weight[i], 0);
added += vec4<f32>(new_color_c.rgb, 1.0 / strength) * weight_calc(i) * strength;
}
if (meets_thresh(new_color_d)) {
// result += vec4<f32>(new_color_b.rgb * weight[i], 0);
added += vec4<f32>(new_color_d.rgb, 1.0 / strength) * weight_calc(i) * strength;
}
}
// We do it this weird way, cuz the world texture is *not* HDR atm
let hdr = result + added;
let sdr = hdr::aces_tone_map(hdr.rgb);
result = vec4<f32>(sdr, hdr.a);
pub async fn new(window: Window) -> color_eyre::Result<Self> {
fn create_composer(_assets: &AssetCache) -> Result<compose::Composer, compose::ComposerError> {
let mut composer = compose::Composer::default();
// HDR module
let hdr_module_src = include_str!("./hdr.wgsl");
let (name, imports, shader_defs) = compose::get_preprocessor_data(hdr_module_src);
composer.add_composable_module(compose::ComposableModuleDescriptor {
as_name: name,
source: hdr_module_src,
file_path: "hdr.wgsl",
language: compose::ShaderLanguage::Wgsl,
additional_imports: &imports,
shader_defs,
})?;
Ok(composer)
}
pub async fn new(window: Window, assets: &AssetCache) -> color_eyre::Result<Self> {
// let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
// label: Some("world shader"),
// source: wgpu::ShaderSource::Wgsl(include_str!("world_shader.wgsl").into()),
// });
let composed_world_shader = composer.make_naga_module(compose::NagaModuleDescriptor {
source: include_str!("world_shader.wgsl"),
file_path: "world_shader.wgsl",
shader_type: compose::ShaderType::Wgsl,
shader_defs: HashMap::new(),
additional_imports: &[],
})?;
let mut validator = naga::valid::Validator::new(
naga::valid::ValidationFlags::default(),
naga::valid::Capabilities::default(),
);
let composed_world_shader_module_info = validator.validate(&composed_world_shader)?;
let shader_source = naga::back::wgsl::write_string(
&composed_world_shader,
&composed_world_shader_module_info,
naga::back::wgsl::WriterFlags::EXPLICIT_TYPES,
)?;
#define_import_path hdr
// Maps HDR values to linear values
// Based on http://www.oscars.org/science-technology/sci-tech-projects/aces
fn aces_tone_map(hdr: vec3<f32>) -> vec3<f32> {
let m1 = mat3x3(
0.59719, 0.07600, 0.02840,
0.35458, 0.90834, 0.13383,
0.04823, 0.01566, 0.83777,
);
let m2 = mat3x3(
1.60475, -0.10208, -0.00327,
-0.53108, 1.10813, -0.07276,
-0.07367, -0.00605, 1.07602,
);
let v = m1 * hdr;
let a = v * (v + 0.0245786) - 0.000090537;
let b = v * (0.983729 * v + 0.4329510) + 0.238081;
return clamp(m2 * (a / b), vec3(0.0), vec3(1.0));
}
name = "naga_oil"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ea62ae0f2787456afca7209ca180522b41f00cbe159ee369eba1e07d365cd1"
dependencies = [
"bit-set",
"codespan-reporting",
"data-encoding",
"indexmap",
"naga",
"once_cell",
"regex",
"regex-syntax",
"rustc-hash",
"thiserror",
"tracing",
"unicode-ident",
]
[[package]]