Another project
1struct Uniform {
2 clip_from_world: mat4x4<f32>,
3 light_dir: vec4<f32>,
4 fill_dir: vec4<f32>,
5 base_color: vec4<f32>,
6 background: vec4<f32>,
7 eye_world: vec4<f32>,
8 ambient: f32,
9 shading_model: u32,
10 face_mode: u32,
11 pad0: f32,
12};
13
14const SHADING_PHONG: u32 = 1u;
15const FACE_OCCLUDER: u32 = 1u;
16const SPECULAR_STRENGTH: f32 = 0.35;
17const SHININESS: f32 = 48.0;
18
19@group(0) @binding(0) var<uniform> u: Uniform;
20
21struct VsOut {
22 @builtin(position) clip: vec4<f32>,
23 @location(0) world_normal: vec3<f32>,
24 @location(1) world_pos: vec3<f32>,
25 @location(2) @interpolate(flat) pick_id: u32,
26 @location(3) vertex_color: vec4<f32>,
27};
28
29struct FsOut {
30 @location(0) color: vec4<f32>,
31 @location(1) pick_id: u32,
32};
33
34@vertex
35fn vs(
36 @location(0) position: vec3<f32>,
37 @location(1) normal: vec3<f32>,
38 @location(2) color: vec4<f32>,
39 @location(3) pick_id: u32,
40) -> VsOut {
41 var out: VsOut;
42 out.clip = u.clip_from_world * vec4<f32>(position, 1.0);
43 out.world_normal = normal;
44 out.world_pos = position;
45 out.pick_id = pick_id;
46 out.vertex_color = color;
47 return out;
48}
49
50@fragment
51fn fs(in: VsOut) -> FsOut {
52 if (u.face_mode == FACE_OCCLUDER) {
53 var occluded: FsOut;
54 occluded.color = u.background;
55 occluded.pick_id = in.pick_id;
56 return occluded;
57 }
58
59 let n = normalize(in.world_normal);
60 let l = normalize(u.light_dir.xyz);
61 let ndl = dot(n, l);
62 let key = max(ndl, 0.0);
63 let fill = max(dot(n, normalize(u.fill_dir.xyz)), 0.0) * u.fill_dir.w;
64 let wrap = 0.5 * ndl + 0.5;
65 let ambient = u.ambient * wrap * wrap;
66 let diffuse = min(key + fill, 1.0);
67 let shade = ambient + (1.0 - u.ambient) * diffuse;
68 let surface = u.base_color.rgb * in.vertex_color.rgb;
69 var rgb = surface * shade;
70
71 if (u.shading_model == SHADING_PHONG) {
72 let view = normalize(u.eye_world.xyz - in.world_pos);
73 let reflection = reflect(-l, n);
74 let specular = pow(max(dot(view, reflection), 0.0), SHININESS) * SPECULAR_STRENGTH;
75 rgb = rgb + vec3<f32>(specular);
76 }
77
78 var out: FsOut;
79 out.color = vec4<f32>(rgb, u.base_color.a * in.vertex_color.a);
80 out.pick_id = in.pick_id;
81 return out;
82}