// Mesh shader — renders triangle meshes (truck Shell/Solid tessellation). // // Vertex layout: position [f32;3], normal [f32;3], color [f32;4] (40 bytes) // // Lighting: simple half-Lambert with a fixed directional light so solids look // solid regardless of camera angle. Selection highlight overrides color. struct Uniforms { view_proj: mat4x4, viewport: vec2, _pad: vec2, }; @group(0) @binding(0) var u: Uniforms; struct VertexIn { @location(0) position: vec3, @location(1) normal: vec3, @location(2) color: vec4, }; struct VertexOut { @builtin(position) clip_pos: vec4, @location(0) color: vec4, @location(1) normal: vec3, }; @vertex fn vs_main(v: VertexIn) -> VertexOut { var out: VertexOut; out.clip_pos = u.view_proj * vec4(v.position, 1.0); out.color = v.color; out.normal = v.normal; return out; } @fragment fn fs_main(in: VertexOut) -> @location(0) vec4 { // Fixed directional light (world space, tilted toward the viewer). let light_dir = normalize(vec3(0.4, 0.8, 0.6)); let n = normalize(in.normal); // Half-Lambert: [0.5, 1.0] so the dark side isn't fully black. let diff = clamp(dot(n, light_dir), 0.0, 1.0) * 0.5 + 0.5; let rgb = in.color.rgb * diff; return vec4(rgb, in.color.a); }