ОРИГИНАЛ:
Я спрашивал об этой теме раньше, но мой первоначальный пример был немного неполным, и я думаю, что теперь я могу более конкретно рассказать о своей проблеме.
Для контекста я использую openGL 3.3 на старом компьютере Apple Mac и пытаюсь визуализировать перекрывающиеся слои четырехугольников.Каждый четырехугольник сопоставляется с фрагментом текстуры png 4096 x 4096, которая имеет области полной прозрачности.
Я хочу использовать альфа-смешение, чтобы прозрачные участки слоя N открывали непрозрачные части слоя N - 1(за этим).Поскольку мне не нужна полупрозрачность, я хотел бы знать - есть ли способ настроить glBlendFuncSeparate
, чтобы цвет фрагмента был просто самым непрозрачным текселем - дополнительного умножения не требуется?
Я пробовал что-то вроде этого:
glBlendFuncSeparate(GL_SRC_COLOR, GL_DST_COLOR, GL_ONE, GL_ZERO);
но я думаю, что я полностью неправильно понимаю значение параметров.Я думал, что они имели в виду: сохранить исходный цвет и установить его в качестве целевого цвета ... применить оригинальную альфа.(Я знаю, что это абсолютно неправильно).
Изначально я думал, что это вопрос xyz, и искал другие причины, по которым я замечаю проблемы с производительностью, но даже если приведенный выше вызов функции приводит к совершенно неправильным цветам, он вызываетмоя анимация должна работать плавно даже в случае перевода hello-triangle + sin (time).
Я бы опубликовал часть своего кода, но он состоит в основном из настройки буферов вершин и объявлений больших статических массивов для тестирования.Мои шейдеры в основном являются сквозными: (например, основная функция в моем фрагментном шейдере:)
void main(void)
{
vec4 texel = texture(tex0, v_uv);
color = vec4(texel.rgb, texel.a);
}
и текстуры загружаются правильно.Я настроил рендеринг от начала до конца.
Как бы я настроил этот вид рендеринга?
Заранее спасибо.
ОБНОВЛЕНИЕ:
Я пробовал:
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
, но появляется только передний слой с непрозрачным белым для его прозрачности.Я проверил значения RGBA, и кажется, что прозрачные секции - [1.0, 1.0, 1.0, 0.0], поэтому мне кажется, что мне нужно игнорировать цвет, когда альфа равен 0.0, даже если цвет не равен [0.0, 0.0, 0.0,а].Чтобы смоделировать это, я добавил оператор if (alpha is 0.0), then discard;
, но затем задержка возвращается.
Таким образом, функции не совсем корректны, или что-то еще не так.
Для получения дополнительной информации о моей настройке:
(я разместил свою большую текстуру внизу)
Данные вершин и индексов для каждого слоя будут слишком длинными для размещения, но для каждого из пяти слоев будет три квадра (Я передаю положение камеры шейдеру и использую значение положения z для смещений).Это может быть отдельным источником неэффективности.
Полный фрагмент и вершинные шейдеры:
// vertex
#version 330 core
precision highp float;
layout (location = 0) in vec3 a_position;
layout (location = 1) in vec2 a_uv;
out vec2 v_uv;
uniform mat4 u_matrix;
uniform float u_aspect;
uniform vec3 u_position_cam;
uniform int u_count_layers;
void main(void)
{
// scroll speed depends on the inverse of the z position
float speed_factor = (1.0 / pow(2.0, u_count_layers - a_position.z));
// x offset
float X = -u_position_cam.x * speed_factor;
// make sure the bg quad jumps back to the correct position
X = mod(X, (u_aspect) * 2.0);
X += a_position.x;
// y offset
float Y = -clamp(u_position_cam.y, 0.0, 2.0) * speed_factor;
Y += a_position.y;
gl_Position = u_matrix * vec4(X, Y, a_position.z, 1.0);
v_uv = a_uv;
}
// фрагмент
#version 330 core
precision highp float;
in vec2 v_uv;
uniform sampler2D tex0;
out vec4 color;
void main(void)
{
vec4 texel = texture(tex0, v_uv);
color = vec4(texel);
}
Этот в основном неразрешенный вопрос о переполнении стека обсуждает проблему, с которой я сталкиваюсь - короче говоря, многие перекрывающиеся прозрачные фигуры вызывают отставание, но если одни и те же фигуры не перекрываются, то все в порядке.Конечно, альтернативный алгоритм наложения еще не найден.
Думая о числах - каждая секция текстуры покрывает 1280 x 720 пикселей.Есть 5 слоев, 3 квадра в каждом.Для каждого пикселя я делаю одну и ту же работу N слоев раз, так что 4 608 000?Я думаю, это может быть слишком дорого.Я также делаю странную арифметику по модулю и смещения.Если способ, которым я пытаюсь добиться прокрутки параллакса, слишком неуклюж, то как это будет сделано эффективно?Я готов изменить свой алгоритм / настройку, если определенно есть лучший способ сделать это.Мне любопытно, как правильно настроить текстуры и прозрачные слои, чтобы избежать проблем, с которыми я сталкиваюсь.
Мысль: а что, если я рендерил спереди назад?Как изменились бы функции смешивания?(Я знаю, что вы обычно визуализируете прозрачные объекты сзади вперед, но здесь мне просто нужно прекратить проверку слоев, как только я нажму один с альфа == 1.0).
![4096x4096 bg texture](https://i.stack.imgur.com/9Cdt0.png)