gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
означает, что результирующая альфа
A_final = A_s * A_s + (1 - A_s) * A_d
В вашем примере после рисования черного треугольника (с альфа = 1) у нарисованного пикселя в буфере кадра будет альфа, равная
1 * 1 + (1 - 1) * 0 == 1 + 0 == 1
Так он будет полностью непрозрачным. Затем, после рисования белого треугольника (с альфа = 0,5), пиксель на пересечении двух треугольников будет иметь альфа
.5 * .5 + (1 - .5) * 1 == .25 + .5 == .75
Это означает, что окончательный цвет будет рассматриваться как частично прозрачный, и, когда он совмещен со страницей, будет виден фон страницы.
Это несколько необычная проблема в обычном OpenGL, поскольку контент обычно создается на пустом фоне. Однако это возникает, когда вы рисуете в FBO и должны объединять результаты с другим контентом в вашем контексте. Есть несколько способов справиться с этим.
Один из способов - смешать альфа-канал с gl.ONE
, gl.ONE_MINUS_SRC_ALPHA
, чтобы получить
A_final = A_s + (1 - A_s) * A_d
это то, что вы обычно хотите с альфа-смешиванием. Однако вы хотите, чтобы ваши цвета по-прежнему смешивались с gl.SRC_ALPHA
, gl.ONE_MINUS_SRC_ALPHA
. Вместо gl.blendFunc
для настройте функции смешивания цветов и альфа-смешивания отдельно. В этом случае вы бы позвонили
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
Другой вариант - использовать цвета с предварительно умноженным альфа-каналом (который на самом деле уже предполагает вы используете, например, при выборке цвета из текстуры). Если вы нарисуете второй треугольник с альфа-каналом, уже умноженным на цвет (таким образом, для полупрозрачного белого треугольника gl_FragColor
будет установлено значение vec4(.5, .5, .5, .5)
), вы можете использовать режим наложения.
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
и он будет действовать так, как вы хотите, как для цвета, так и для альфа-канала.
Второй вариант - это то, что вы обычно видите в примерах WebGL, поскольку (как уже упоминалось), WebGL уже предполагает, что ваши цвета предварительно умножены (так что vec4(1., 1., 1., .5)
выходит за пределы гаммы, вывод рендеринга не определен, а драйвер / графический процессор может выводить любые сумасшедшие цвет он хочет). Гораздо чаще встречается gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
в обычных примерах OpenGL, что приводит к некоторой путанице.
person
Brendan Kenny
schedule
18.07.2012