mesh.wgsl
2.9 kB · wgsl · 126 lines
1struct Uniforms {2 res: vec4<f32>,3 board: vec4<f32>,4 base: vec4<f32>,5 pose: vec4<f32>,6 lens: vec4<f32>,7 light: vec4<f32>,8};9@group(0) @binding(0) var<uniform> u: Uniforms;1011const NEAR: f32 = 0.25;12const FOCAL: f32 = 1.2;1314fn spun(v: vec3<f32>) -> vec3<f32> {15 let c = cos(u.pose.x);16 let s = sin(u.pose.x);17 return vec3<f32>(c * v.x + s * v.z, v.y, -s * v.x + c * v.z);18}1920fn view() -> mat3x3<f32> {21 let cy = cos(u.pose.y);22 let sy = sin(u.pose.y);23 let cp = cos(u.pose.z);24 let sp = sin(u.pose.z);25 return mat3x3<f32>(26 vec3<f32>(cy, -sp * sy, cp * sy),27 vec3<f32>(0.0, cp, sp),28 vec3<f32>(-sy, -sp * cy, cp * cy),29 );30}3132fn project(e: vec3<f32>) -> vec4<f32> {33 let dist = u.pose.w;34 let far = dist + 4.0;35 let ortho = u.lens.z > 0.5;36 var a = 2.0 * FOCAL;37 var q = far / (far - NEAR);38 var w = dist - e.z;39 if (ortho) {40 a = 2.0 * FOCAL / dist;41 q = 1.0 / (far - NEAR);42 w = 1.0;43 }44 let x = a * (e.x + u.lens.x) * u.res.y / max(u.res.x, 1.0);45 let y = a * (e.y + u.lens.y);46 let z = q * (dist - NEAR - e.z);47 return vec4<f32>(x, y, z, w);48}4950fn facing(n: vec3<f32>, e: vec3<f32>) -> f32 {51 if (u.lens.z > 0.5) {52 return n.z;53 }54 return -(n.x * e.x + n.y * e.y + n.z * (e.z - u.pose.w));55}5657fn beam() -> vec3<f32> {58 let cl = cos(u.light.y);59 return vec3<f32>(sin(u.light.x) * cl, sin(u.light.y), cos(u.light.x) * cl);60}6162struct Tri {63 @builtin(position) pos: vec4<f32>,64 @location(0) @interpolate(flat) color: vec3<f32>,65 @location(1) @interpolate(flat) face: f32,66};6768@vertex69fn vs_main(@location(0) pos: vec3<f32>, @location(1) normal: vec3<f32>) -> Tri {70 let world = spun(pos);71 let n = spun(normal);72 let lit = (dot(n, beam()) + 1.0) * 0.5;73 let bands = u.base.w;74 let band = clamp(floor(lit * bands), 0.0, bands - 1.0);75 let t = (64.0 + floor(191.0 * band / (bands - 1.0))) / 255.0;76 let e = view() * world;77 var out: Tri;78 out.pos = project(e);79 out.color = u.base.rgb * t;80 out.face = facing(view() * n, e);81 return out;82}8384@fragment85fn fs_main(in: Tri) -> @location(0) vec4<f32> {86 return vec4<f32>(in.color, 1.0);87}8889@fragment90fn fs_back(in: Tri) -> @location(0) vec4<f32> {91 if (in.face > 0.0) {92 discard;93 }94 return vec4<f32>(in.color * u.lens.w, u.lens.w);95}9697@fragment98fn fs_front(in: Tri) -> @location(0) vec4<f32> {99 if (in.face <= 0.0) {100 discard;101 }102 return vec4<f32>(in.color * u.lens.w, u.lens.w);103}104105struct Line {106 @builtin(position) pos: vec4<f32>,107 @location(0) color: vec4<f32>,108};109110@vertex111fn vs_line(@location(0) pos: vec3<f32>, @location(1) flag: f32, @location(2) color: vec4<f32>) -> Line {112 var world = pos;113 if (flag > 0.5) {114 world = spun(pos);115 }116 var out: Line;117 out.pos = project(view() * world);118 out.pos.z = out.pos.z - 0.005 * out.pos.w;119 out.color = color;120 return out;121}122123@fragment124fn fs_line(in: Line) -> @location(0) vec4<f32> {125 return vec4<f32>(in.color.rgb * in.color.a, in.color.a);126}