Отбрасывание экземпляров в вершинном шейдере
Я использую экземплярный geom для отображения контента с использованием webGL2. Как часть процесса, каждый экземпляр имеет компонент цвета, который в некоторых случаях может иметь значение альфа-канала равное нулю.
Вместо того, чтобы передать его фрагментному шейдеру для отбрасывания, я проверяю альфа в шейдере vertext. Если ноль, то я вывожу каждый вершин как vec4(-2)
, чтобы поместить его вне клипа или, в худшем случае, иметь точку в 1 пиксель.
Я не могу найти информацию о том, как это обрабатывается каналом рендеринга.
Является ли это лучшей стратегией для удаления экземпляров из конвейера?
Альтернативой является удаление экземпляров из буфера, который в JS является интенсивной операцией ЦП при работе с 1000 экземплярами.
Шейдеры
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); // put this instance outside 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; }
}`;