Source browser
examples/shaders/nonmax.cpp
Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.
File fingerprint
1#ifdef __cplusplus // Expose host declarations only when a C++ compiler reads this shader.
2#include "shdr.h" // Include shdr.h declarations.
3#endif // Finish this conditional compilation branch.
4
5// Keep positive response peaks, deterministic index ordering breaks equal-value ties.
6layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; // Group 64 independent invocations along x.
7layout(std430, binding = 0) readonly buffer Inputs { // Read the preceding stage's input elements through buffer binding 0.
8 float input_values[]; // Store the preceding stage's input elements.
9}; // Finish this declaration.
10layout(std430, binding = 1) writeonly buffer Outputs { // Write this stage's output elements through buffer binding 1.
11 uint output_values[]; // Store this stage's output elements.
12}; // Finish this declaration.
13uniform uint width; // Set the row width of the flattened image buffer.
14uniform uint height; // Set the number of rows in the image buffer.
15uniform float threshold; // Set the smallest response that can be accepted as a corner.
16
17void main() { // Select this pixel only when it is a deterministic positive local maximum.
18 uint i = gl_GlobalInvocationID.x; // Select this invocation's global x coordinate.
19 if (i >= width * height) // Guard the flattened image against padding invocations.
20 return; // Stop this invocation before performing another resource access.
21 output_values[i] = 0u; // Clear the output flag before checking this candidate.
22 float value = input_values[i]; // Read the candidate corner response.
23 if (value <= threshold) // Reject weak responses before inspecting the neighborhood.
24 return; // Stop this invocation before performing another resource access.
25 int x = int(i % width), y = int(i / width); // Recover the column and row from the flattened pixel index.
26 for (int dy = -1; dy <= 1; ++dy) { // Visit the three neighboring rows.
27 for (int dx = -1; dx <= 1; ++dx) { // Visit the three neighboring columns.
28 int nx = clamp(x + dx, 0, int(width) - 1); // Clamp this neighbor column to the valid image.
29 int ny = clamp(y + dy, 0, int(height) - 1); // Clamp this neighbor row to the valid image.
30 uint neighbor_index = uint(ny) * width + uint(nx); // Flatten the neighbor coordinate for a deterministic tie break.
31 float neighbor = input_values[neighbor_index]; // Read the neighboring corner response.
32 if (neighbor > value || (neighbor == value && neighbor_index < i)) // Reject stronger neighbors and choose the smallest index for equal responses.
33 return; // Stop this invocation before performing another resource access.
34 } // End this block.
35 } // End this block.
36 output_values[i] = 1u; // Mark this surviving positive local maximum.
37} // End this block.