/ proof-of-concept / cymbalsim
Sign in
proof-of-concept / cymbalsim
cymbalsim / src / render / shaders.wgsl
76 lines · 2.0 KBBlameHistoryRaw
1// Two vertex paths share one fragment shader: the plate mesh (static x, y
2// per node plus a per-frame record of height, slope and color) and the
3// marker geometry (explicit position, normal and color). The plate frame is
4// used directly as the world frame, with z up, so a cymbal lies flat. The 2D
5// map is the same mesh under an orthographic camera with the heights zeroed
6// (zScale = 0) and the lighting off (lit = 0).
8struct Uniforms {
9 mvp: mat4x4f,
10 eye: vec3f,
11 zScale: f32,
12 light: vec3f,
13 lit: f32,
14};
16@group(0) @binding(0) var<uniform> U: Uniforms;
18struct VOut {
19 @builtin(position) pos: vec4f,
20 @location(0) world: vec3f,
21 @location(1) normal: vec3f,
22 @location(2) color: vec3f,
23};
25struct MeshIn {
26 @location(0) xy: vec2f,
27 @location(1) z: f32,
28 @location(2) slope: vec2f,
29 @location(3) color: vec4f,
30};
32@vertex
33fn vsMesh(in: MeshIn) -> VOut {
34 let p = vec3f(in.xy, in.z * U.zScale);
35 var o: VOut;
36 o.pos = U.mvp * vec4f(p, 1.0);
37 o.world = p;
38 o.normal = vec3f(-in.slope * U.zScale, 1.0);
39 o.color = in.color.rgb;
40 return o;
43struct MarkerIn {
44 @location(0) pos: vec3f,
45 @location(1) normal: vec3f,
46 @location(2) color: vec4f,
47};
49@vertex
50fn vsMarker(in: MarkerIn) -> VOut {
51 var o: VOut;
52 o.pos = U.mvp * vec4f(in.pos, 1.0);
53 o.world = in.pos;
54 o.normal = in.normal;
55 o.color = in.color.rgb;
56 return o;
59// Lambert with a little Blinn-Phong specular; two-sided, so the underside of
60// the plate is lit when the camera goes below it.
61fn shade(color: vec3f, normal: vec3f, world: vec3f) -> vec3f {
62 if (U.lit < 0.5) { return color; }
63 let v = normalize(U.eye - world);
64 var n = normalize(normal);
65 if (dot(n, v) < 0.0) { n = -n; }
66 let l = normalize(U.light);
67 let diff = max(dot(n, l), 0.0);
68 let h = normalize(l + v);
69 let spec = pow(max(dot(n, h), 0.0), 40.0);
70 return color * (0.28 + 0.72 * diff) + vec3f(0.14) * spec;
73@fragment
74fn fsMain(in: VOut) -> @location(0) vec4f {
75 return vec4f(shade(in.color, in.normal, in.world), 1.0);
↑↓ move↵openescclose