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
| #version 450
layout(binding = 0) uniform UniformBufferObject { int width; int height; vec2 vertex_a; vec2 vertex_b; vec2 vertex_c; } ubo;
layout(std430, binding = 1) buffer rasterize_in_out { int rasterize[]; };
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
int CalArea(ivec2 p1, ivec2 p2, ivec2 p3) { return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); }
bool BaryCentric(ivec2 pos) { ivec2 p1 = ivec2(ubo.vertex_a); ivec2 p2 = ivec2(ubo.vertex_b); ivec2 p3 = ivec2(ubo.vertex_c);
int area1 = CalArea(p1, p2, pos); int area2 = CalArea(p2, p3, pos); int area3 = CalArea(p3, p1, pos);
return area1 >= 0 && area2 >= 0 && area3 >= 0; }
void main() { ivec2 gid = ivec2(gl_GlobalInvocationID.xy); const int row = gid.y; const int col = gid.x; if (row >= ubo.height || col >= ubo.width) return;
int ax = ivec2(ubo.vertex_a).x; int ay = ivec2(ubo.vertex_a).y; int bx = ivec2(ubo.vertex_b).x; int by = ivec2(ubo.vertex_b).y; int cx = ivec2(ubo.vertex_c).x; int cy = ivec2(ubo.vertex_c).y;
int top = min(min(ay, by), cy); int bottom = max(max(ay, by), cy); int left = min(min(ax, bx), cx); int right = max(max(ax, bx), cx);
if (row < top || row > bottom || col < left || col > right) return;
bool in_triangle = BaryCentric(ivec2(col, row)); if (in_triangle) { rasterize[row * ubo.width + col] = 1; } }
|