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}