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
(
name: "VisibilityOptimizer",
resources: [
(
name: "visibilityBuffer",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 0
),
(
name: "properties",
kind: PropertyGroup([
(name: "viewProjection", kind: Matrix4()),
(name: "tileSize", kind: Int()),
]),
binding: 0
),
],
passes: [
(
name: "Primary",
draw_parameters: DrawParameters(
cull_face: None,
color_write: ColorMask(
red: true,
green: true,
blue: true,
alpha: true,
),
depth_write: false,
stencil_test: None,
depth_test: Some(LessOrEqual),
blend: None,
stencil_op: StencilOp(
fail: Keep,
zfail: Keep,
zpass: Zero,
write_mask: 0xFFFF_FFFF,
),
scissor_box: None
),
vertex_shader:
r#"
layout (location = 0) in vec3 vertexPosition;
void main()
{
gl_Position = properties.viewProjection * vec4(vertexPosition, 1.0);
}
"#,
fragment_shader:
r#"
out uint optimizedVisibilityMask;
void main()
{
int tileX = int(gl_FragCoord.x);
int tileY = int(gl_FragCoord.y);
int beginX = tileX * properties.tileSize;
int beginY = tileY * properties.tileSize;
int endX = (tileX + 1) * properties.tileSize;
int endY = (tileY + 1) * properties.tileSize;
int visibilityMask = 0;
for (int y = beginY; y < endY; ++y) {
for (int x = beginX; x < endX; ++x) {
ivec4 mask = ivec4(texelFetch(visibilityBuffer, ivec2(x, y), 0) * 255.0);
visibilityMask |= (mask.a << 24) | (mask.b << 16) | (mask.g << 8) | mask.r;
}
}
optimizedVisibilityMask = uint(visibilityMask);
}
"#,
)
]
)