1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
// Rotating cube shader v2 (simplified, no masking)
struct Uniforms {
view_proj: mat4x4f,
inv_view_proj: mat4x4f,
camera_pos_time: vec4f,
params: vec4f,
resolution: vec2f,
aspect_ratio: f32,
_pad: f32,
};
struct ObjectData {
model: mat4x4f,
inv_model: mat4x4f,
color: vec4f,
params: vec4f,
};
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@group(0) @binding(1) var<storage, read> object: ObjectData;
struct VSOut {
@builtin(position) pos: vec4f,
@location(0) world_pos: vec3f,
@location(1) normal: vec3f,
};
// Cube vertices (hardcoded)
fn get_cube_vertex(vid: u32) -> vec3f {
let positions = array<vec3f, 36>(
// Front face
vec3f(-1, -1, 1), vec3f( 1, -1, 1), vec3f( 1, 1, 1),
vec3f(-1, -1, 1), vec3f( 1, 1, 1), vec3f(-1, 1, 1),
// Back face
vec3f( 1, -1, -1), vec3f(-1, -1, -1), vec3f(-1, 1, -1),
vec3f( 1, -1, -1), vec3f(-1, 1, -1), vec3f( 1, 1, -1),
// Right face
vec3f( 1, -1, 1), vec3f( 1, -1, -1), vec3f( 1, 1, -1),
vec3f( 1, -1, 1), vec3f( 1, 1, -1), vec3f( 1, 1, 1),
// Left face
vec3f(-1, -1, -1), vec3f(-1, -1, 1), vec3f(-1, 1, 1),
vec3f(-1, -1, -1), vec3f(-1, 1, 1), vec3f(-1, 1, -1),
// Top face
vec3f(-1, 1, 1), vec3f( 1, 1, 1), vec3f( 1, 1, -1),
vec3f(-1, 1, 1), vec3f( 1, 1, -1), vec3f(-1, 1, -1),
// Bottom face
vec3f(-1, -1, -1), vec3f( 1, -1, -1), vec3f( 1, -1, 1),
vec3f(-1, -1, -1), vec3f( 1, -1, 1), vec3f(-1, -1, 1)
);
return positions[vid];
}
fn get_cube_normal(vid: u32) -> vec3f {
let face_id = vid / 6u;
let normals = array<vec3f, 6>(
vec3f( 0, 0, 1), // Front
vec3f( 0, 0, -1), // Back
vec3f( 1, 0, 0), // Right
vec3f(-1, 0, 0), // Left
vec3f( 0, 1, 0), // Top
vec3f( 0, -1, 0) // Bottom
);
return normals[face_id];
}
@vertex fn vs_main(@builtin(vertex_index) vid: u32) -> VSOut {
let local_pos = get_cube_vertex(vid);
let local_normal = get_cube_normal(vid);
let world_pos = object.model * vec4f(local_pos, 1.0);
let world_normal = normalize((object.model * vec4f(local_normal, 0.0)).xyz);
let clip_pos = uniforms.view_proj * world_pos;
return VSOut(clip_pos, world_pos.xyz, world_normal);
}
@fragment fn fs_main(@location(0) world_pos: vec3f, @location(1) normal: vec3f) -> @location(0) vec4f {
let N = normalize(normal);
let light_dir = normalize(vec3f(1.0, 1.0, 1.0));
let diffuse = max(dot(N, light_dir), 0.0);
let ambient = 0.3;
let lighting = ambient + diffuse * 0.7;
let color = object.color.rgb * lighting;
return vec4f(color, 1.0);
}
|