-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstruct.vert
More file actions
59 lines (55 loc) · 2.59 KB
/
Copy pathstruct.vert
File metadata and controls
59 lines (55 loc) · 2.59 KB
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
#version 450
// Instanced structure box vertex stage (Phase 5): city walls + houses. The unit
// cube (36 verts) is generated from gl_VertexIndex; the per-instance buffer
// supplies box centre, half-extents, type and seed. One draw call covers every
// wall segment and house. Extensible: a new structure kind is a new `type`
// value + one branch in the fragment stage — no new pipeline, no new geometry.
layout(location = 0) in vec3 iPos; // instance: box centre (world)
layout(location = 1) in vec3 iHalf; // instance: half-extents (world)
layout(location = 2) in float iType; // instance: 0 = wall, 1 = house
layout(location = 3) in float iSeed; // instance: per-structure random seed
layout(location = 4) in float iYaw; // instance: rotation about vertical (rad)
layout(push_constant) uniform Push {
mat4 mvp;
vec4 sunDir;
vec4 sunColor;
vec4 ambient;
mat4 lightMvp;
} pc;
layout(location = 0) out vec3 vNormal;
layout(location = 1) out vec3 vWorld;
layout(location = 2) out float vType;
layout(location = 3) out float vLocalY; // cube-space y in [-1,1] (roof band)
layout(location = 4) out float vSeed;
// Face-local coordinates in [-1,1]²: x across the face, y up it. A prop whose
// pattern must hold its shape whatever its size (a door's frame and handle)
// needs the FACE, not world metres — world-space patterns stretch with the
// box and slide when the prop is moved.
layout(location = 5) out vec2 vFace;
void main() {
const vec3 FN[6] = vec3[6](vec3(0, 0, 1), vec3(0, 0, -1), vec3(1, 0, 0),
vec3(-1, 0, 0), vec3(0, 1, 0), vec3(0, -1, 0));
const vec2 QUAD[6] = vec2[6](vec2(-1, -1), vec2(1, -1), vec2(1, 1),
vec2(-1, -1), vec2(1, 1), vec2(-1, 1));
int face = gl_VertexIndex / 6;
int vi = gl_VertexIndex % 6;
vec3 n = FN[face];
vec2 q = QUAD[vi];
vec3 up = abs(n.y) > 0.5 ? vec3(0, 0, 1) : vec3(0, 1, 0);
vec3 tang = normalize(cross(up, n));
vec3 bitan = cross(n, tang);
vec3 corner = n + tang * q.x + bitan * q.y; // [-1,1]^3
// Yaw about the vertical axis: oriented houses / wall segments following
// the ring curvature. The SAME rotation the collision index inverts
// (sub/collide.h), so the visible silhouette is exactly the solid one.
float c = cos(iYaw), s = sin(iYaw);
vec3 l = corner * iHalf;
vec3 world = iPos + vec3(l.x * c - l.z * s, l.y, l.x * s + l.z * c);
gl_Position = pc.mvp * vec4(world, 1.0);
vNormal = vec3(n.x * c - n.z * s, n.y, n.x * s + n.z * c);
vWorld = world;
vType = iType;
vLocalY = corner.y;
vFace = q;
vSeed = iSeed;
}