Compare commits

..

5 Commits

Author SHA1 Message Date
cb500033c0 Better viewport 2024-12-29 21:58:58 +03:00
a2646f8f29 Custom size environment map 2024-12-29 21:57:48 +03:00
9c1ad95f37 Fix cube map 2024-12-29 21:57:36 +03:00
8c97ccad18 Extract tone mapping into function 2024-12-29 21:36:04 +03:00
6f6673ea1f Fix upside-down image 2024-12-29 21:30:10 +03:00
3 changed files with 28 additions and 25 deletions

View File

@ -1,4 +1,4 @@
use std::error::Error; use std::{env, error::Error};
use glam::{mat3, vec2, vec3, Mat3, Vec3}; use glam::{mat3, vec2, vec3, Mat3, Vec3};
use image::buffer::ConvertBuffer; use image::buffer::ConvertBuffer;
@ -16,6 +16,8 @@ fn make_viewport(m: Mat3) -> [Vertex; 4] {
} }
fn main() { fn main() {
let args: Vec<_> = env::args().collect();
let extent = args.get(1).and_then(|s| s.parse().ok()).unwrap_or(EXTENT);
let (device, queue) = pollster::block_on(init_gpu()).unwrap(); let (device, queue) = pollster::block_on(init_gpu()).unwrap();
let format = wgpu::TextureFormat::Rgba8UnormSrgb; let format = wgpu::TextureFormat::Rgba8UnormSrgb;
@ -30,16 +32,16 @@ fn main() {
let faces = [ let faces = [
mat3(-Vec3::Z, -Vec3::Y, Vec3::X), mat3(-Vec3::Z, -Vec3::Y, Vec3::X),
mat3(Vec3::Z, -Vec3::Y, -Vec3::X), mat3(Vec3::Z, -Vec3::Y, -Vec3::X),
mat3(Vec3::X, Vec3::Z, Vec3::Y),
mat3(Vec3::X, -Vec3::Z, -Vec3::Y), mat3(Vec3::X, -Vec3::Z, -Vec3::Y),
mat3(Vec3::X, Vec3::Z, Vec3::Y),
mat3(Vec3::X, -Vec3::Y, Vec3::Z), mat3(Vec3::X, -Vec3::Y, Vec3::Z),
mat3(-Vec3::X, -Vec3::Y, -Vec3::Z), mat3(-Vec3::X, -Vec3::Y, -Vec3::Z),
]; ];
let output = device.create_texture(&wgpu::TextureDescriptor { let output = device.create_texture(&wgpu::TextureDescriptor {
label: None, label: None,
size: wgpu::Extent3d { size: wgpu::Extent3d {
width: EXTENT, width: extent,
height: EXTENT, height: extent,
depth_or_array_layers: 6, depth_or_array_layers: 6,
}, },
mip_level_count: 1, mip_level_count: 1,
@ -52,7 +54,7 @@ fn main() {
let buffers = faces.map(|_| { let buffers = faces.map(|_| {
device.create_buffer(&wgpu::BufferDescriptor { device.create_buffer(&wgpu::BufferDescriptor {
label: None, label: None,
size: (4 * EXTENT * EXTENT) as u64, size: (4 * extent * extent) as u64,
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
mapped_at_creation: false, mapped_at_creation: false,
}) })
@ -97,13 +99,13 @@ fn main() {
buffer: &buffer, buffer: &buffer,
layout: wgpu::ImageDataLayout { layout: wgpu::ImageDataLayout {
offset: 0, offset: 0,
bytes_per_row: Some(4 * EXTENT), bytes_per_row: Some(4 * extent),
rows_per_image: Some(EXTENT), rows_per_image: Some(extent),
}, },
}, },
wgpu::Extent3d { wgpu::Extent3d {
width: EXTENT, width: extent,
height: EXTENT, height: extent,
depth_or_array_layers: 1, depth_or_array_layers: 1,
}, },
); );
@ -117,7 +119,7 @@ fn main() {
for (face, buf) in buffers.iter().enumerate() { for (face, buf) in buffers.iter().enumerate() {
s.spawn(move || { s.spawn(move || {
let img = let img =
image::RgbaImage::from_raw(EXTENT, EXTENT, buf.slice(..).get_mapped_range().to_vec()).unwrap(); image::RgbaImage::from_raw(extent, extent, buf.slice(..).get_mapped_range().to_vec()).unwrap();
let img: image::RgbImage = img.convert(); let img: image::RgbImage = img.convert();
img.save(format!("textures/env{face}.jpeg")).unwrap(); img.save(format!("textures/env{face}.jpeg")).unwrap();
}); });

View File

@ -1,6 +1,6 @@
use std::error::Error; use std::error::Error;
use glam::{vec2, vec3}; use glam::{uvec2, vec2, vec3};
use image::ImageReader; use image::ImageReader;
use present::Presenter; use present::Presenter;
use trace::{Tracer, TracerData, TracerEnv, Vertex}; use trace::{Tracer, TracerData, TracerEnv, Vertex};
@ -17,18 +17,13 @@ mod trace;
pub use trace::Sphere; pub use trace::Sphere;
fn make_viewport(w: u32, h: u32) -> [Vertex; 4] { fn make_viewport(w: u32, h: u32) -> [Vertex; 4] {
let w = w as f32; let size = uvec2(w, h).as_vec2();
let h = h as f32; let size = size.normalize();
let (w, h) = (1.0f32.max(w / h), 1.0f32.max(h / w)); let (w, h) = (size.x, size.y);
let r = 1.0f32; let r = 1.0f32;
let screen_coord = [vec2(-h, -w), vec2(h, -w), vec2(-h, w), vec2(h, w)]; let screen_coord = [vec2(-1., -1.), vec2(1., -1.), vec2(-1., 1.), vec2(1., 1.)];
let eye = vec3(-r, 0.0, 0.0); let eye = vec3(-r, 0., 0.);
let world_coord = [ let world_coord = [vec3(0., -w, -h), vec3(0., w, -h), vec3(0., -w, h), vec3(0., w, h)];
vec3(0.0, -1.0, -1.0),
vec3(0.0, 1.0, -1.0),
vec3(0.0, -1.0, 1.0),
vec3(0.0, 1.0, 1.0),
];
[0, 1, 2, 3].map(|k| Vertex { [0, 1, 2, 3].map(|k| Vertex {
eye, eye,
world: world_coord[k], world: world_coord[k],

View File

@ -12,14 +12,20 @@ struct Varying {
@vertex @vertex
fn on_vertex(in: Vertex) -> Varying { fn on_vertex(in: Vertex) -> Varying {
return Varying(in.screen, vec4(2.0 * in.screen - 1.0, 0.0, 1.0)); let uv = in.screen;
let xy = vec2(2. * uv.x - 1., 1. - 2. * uv.y);
return Varying(uv, vec4(xy, 0., 1.));
} }
@fragment @fragment
fn on_fragment(in: Varying) -> @location(0) vec4f { fn on_fragment(in: Varying) -> @location(0) vec4f {
let hdr = textureSample(tex, smp, in.tex).xyz; let pixel = textureSample(tex, smp, in.tex);
return vec4(rational_tone_map(pixel.xyz), 1.0);
}
fn rational_tone_map(hdr: vec3<f32>) -> vec3<f32> {
let luminosity = dot(hdr, vec3(0.2126, 0.7152, 0.0722)); let luminosity = dot(hdr, vec3(0.2126, 0.7152, 0.0722));
let color = hdr / luminosity; let color = hdr / luminosity;
let luma = luminosity / (luminosity + 1.0); let luma = luminosity / (luminosity + 1.0);
return vec4(luma * color, 1.0); return luma * color;
} }