Filtering Instances in the Vertex Shader
In my webGL2 project, I am utilizing instanced geometry to render content. Each instance contains a color component with varying alpha values, some of which may be zero.
Instead of passing instances with zero alpha values to the fragment shader for discarding, I decided to check the alpha value in the vertex shader. If the alpha value is zero, I output each vertex as vec4(-2)
to position it outside the clipping area or potentially as a 1 pixel point.
I have been unable to find specific information on how the rendering pipeline handles this scenario.
Is this approach the most effective way to eliminate instances from the rendering process?
An alternative method would involve removing the instances from the buffer, but this can be CPU-intensive when dealing with a large number of instances within JavaScript.
The Shader Code
const vertexSrc = `#version 300 es
#define alphaCut 0.0
in vec2 verts;
in vec2 pos;
in vec2 scale;
in vec2 offset;
in float rotate;
in float zIdx; // z index for zBuf clip only
in vec4 color; // RGBA to color.a == 0.0 to remove not render
in uint spriteIdx;
uniform vec4 sheetLayout[128];
uniform vec2 sheetSize;
uniform mat2 view;
uniform vec2 origin;
out vec2 spr;
out vec4 col;
void main() {
if (color.a <= alphaCut) {
gl_Position = vec4(-2); // move this instance outside the clip
return;
}
col = color;
vec4 sprite = sheetLayout[spriteIdx];
spr = sprite.xy + verts * sprite.zw / sheetSize;
vec2 loc = (verts - offset) * scale * sprite.zw;
float xdx = cos(rotate);
float xdy = sin(rotate);
loc = view * (vec2(loc.x * xdx - loc.y * xdy, loc.x * xdy + loc.y * xdx) + pos - origin);
gl_Position = vec4(loc, zIdx, 1);
}`;
const fragmentSrc = `#version 300 es
precision mediump float;
uniform sampler2D tex;
#define alphaCut 0.0;
in vec2 spr;
in vec4 col;
out vec4 pixel;
void main() {
pixel = texture(tex, spr) * col;
if (pixel.a <= alphaCut) { discard; }
}`;