forked from 1b-agent/opencadstudio-upstream
48 lines
1.4 KiB
WebGPU Shading Language
48 lines
1.4 KiB
WebGPU Shading Language
// 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<f32>,
|
|
viewport: vec2<f32>,
|
|
_pad: vec2<f32>,
|
|
};
|
|
|
|
@group(0) @binding(0)
|
|
var<uniform> u: Uniforms;
|
|
|
|
struct VertexIn {
|
|
@location(0) position: vec3<f32>,
|
|
@location(1) normal: vec3<f32>,
|
|
@location(2) color: vec4<f32>,
|
|
};
|
|
|
|
struct VertexOut {
|
|
@builtin(position) clip_pos: vec4<f32>,
|
|
@location(0) color: vec4<f32>,
|
|
@location(1) normal: vec3<f32>,
|
|
};
|
|
|
|
@vertex
|
|
fn vs_main(v: VertexIn) -> VertexOut {
|
|
var out: VertexOut;
|
|
out.clip_pos = u.view_proj * vec4<f32>(v.position, 1.0);
|
|
out.color = v.color;
|
|
out.normal = v.normal;
|
|
return out;
|
|
}
|
|
|
|
@fragment
|
|
fn fs_main(in: VertexOut) -> @location(0) vec4<f32> {
|
|
// Fixed directional light (world space, tilted toward the viewer).
|
|
let light_dir = normalize(vec3<f32>(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<f32>(rgb, in.color.a);
|
|
}
|