Compare commits

...

2 Commits

Author SHA1 Message Date
059e98c3e3 do color mapping per-pixel 2025-11-25 14:43:59 +03:00
0065a45e7d avoid crashes on dir=0 2025-11-25 14:40:53 +03:00
5 changed files with 45 additions and 3 deletions

View File

@ -20,6 +20,12 @@ impl OrbitalCamera {
self.distance * vec3(xy * x, xy * y, z) self.distance * vec3(xy * x, xy * y, z)
} }
pub fn direction(&self) -> Vec3 {
let (y, x) = self.position_yaw.sin_cos();
let (z, xy) = self.position_pitch.sin_cos();
-vec3(xy * x, xy * y, z)
}
pub fn transform(&self) -> Mat4 { pub fn transform(&self) -> Mat4 {
// for yaw=0, pitch=0: // for yaw=0, pitch=0:
// X -> -Z // X -> -Z

View File

@ -393,12 +393,15 @@ impl Core {
.map(|&v| { .map(|&v| {
let pos = obj.position + obj.radius * v; let pos = obj.position + obj.radius * v;
let normal = v; let normal = v;
let dir = (pos - camera.position()).normalize(); let mut dir = (pos - camera.position()).normalize();
if !dir.is_finite() {
dir = camera.direction();
}
let light = light_at(Hit { let light = light_at(Hit {
incident: Ray::new(pos, dir), incident: Ray::new(pos, dir),
normal, normal,
}); });
let color = colormap(light); let color = Vec3::splat(light);
render::faces::Vertex { pos, color } render::faces::Vertex { pos, color }
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),

32
src/render/colormap.wgsl Normal file
View File

@ -0,0 +1,32 @@
struct LookParams {
m: mat4x4f,
}
struct Vertex {
@location(0) pos: vec3f,
@location(1) color: vec3f,
}
struct Varying {
@builtin(position) screen: vec4f,
@location(0) color: vec4f,
}
@group(0) @binding(0) var<uniform> look: LookParams;
fn colormap(light: f32) -> vec3f {
let brightness = 3. * (1. - 1. / (1. + light));
return vec3(brightness, brightness - 1., brightness - 2.);
}
@vertex
fn on_vertex(in: Vertex) -> Varying {
let pos = look.m * vec4f(in.pos, 1.0);
let color = vec4f(in.color, 1.0);
return Varying(pos, color);
}
@fragment
fn on_fragment(in: Varying) -> @location(0) vec4f {
return vec4f(colormap(in.color.x), 1.0);
}

View File

@ -79,7 +79,7 @@ impl Pipeline {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: None, label: None,
source: wgpu::ShaderSource::Wgsl(super::SIMPLE_SHADER.into()), source: wgpu::ShaderSource::Wgsl(super::COLORMAP_SHADER.into()),
}); });
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: None, label: None,

View File

@ -2,6 +2,7 @@ pub mod faces;
pub mod lines; pub mod lines;
static SIMPLE_SHADER: &str = include_str!("simple.wgsl"); static SIMPLE_SHADER: &str = include_str!("simple.wgsl");
static COLORMAP_SHADER: &str = include_str!("colormap.wgsl");
pub const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb; pub const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24Plus; pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24Plus;