I have a post-effect camera-shader in which I want to implement a simple spatial partitioning of the screen between two passes of the fragment shader.
The first pass should divide the screen into cells of size = 30x30 pixels, and then for each green fragment, store somehow which of those screen cells the coordinate of such green fragment is located. That information should then be available for the second pass to work with.
Well, merely dividing the screen into cells is trivial, considering that it's easy to calculate the row and column indexes of such screen-grid:
static float2 _Pixels = float2(_ScreenParams.x, _ScreenParams.y);
float2 griduv = round(input.uv * _Pixels) * _invPixels; //pixel-screen space coordinate of the current fragment being evaluated
half cellsize = 30.0f;
float gridX = griduv .x/cellsize;
float gridY = griduv .y/cellsize;
int gridrow = gridX - frac(gridX);
int gridcol = gridY - frac(gridY);
If that was not a shader task but rather a standard CPU code, it would be just a matter of saving the i
th griduv
into an array-of-list or array-of-array (e.g. float2[][] grid = new float2[gridrow*gridcol][maxNfloat2]
) at position grid[gridrow*gridcol+gridrow][i]
.
However, in a shader, for most hardwares and most DirectX and OpenGL versions, it seems to me that 1) we can't have multi-dimensional arrays, 2) we can't have resizable containers like lists and 3) we also can't pass variables and containers from one pass to the next.
As one can easily see, this situation is also not well suited for using a simple texture to store values from one pass to the next, since I would need multiple float2
into each grid cell and I can have quite many floats to store.
So, how could I proceed in such a situation? In other words, how could I store the pixel-screen coordinates of given fragments in a spatial-partitioning of the screen (in this case a simple fixed size grid of the screen), to be passed from one shader pass to the next?