Продолжая осваивать OpenGL и инстансинг соответственно, столкнулся с проблемой обработки пересечения поверхностей каждым из элементов инстансинга.
Моделирую ситуацию: делаю анимацию дождя при помощи инстансинга, беру базовую каплю, которая представляет собой 2 точки в верхнем левом углу, соединённых линией, после чего на основе смещения по X и Y координатам создаю ещё 200 таких же каплей в отображаемой области, а так же применяю к ним матрицу трансформации. Вот, собственно, сам шейдер:
#version 460 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aOffset;
uniform mat4 raindropsdown;
vec4 result;
void main()
{
result = raindropsdown * vec4(aPos + aOffset, 0.0, 1.0);
if ((result.x < -0.5 && result.y > -0.5) || (result.x > 0.5 && result.y > -0.5) || (result.x >= -0.5 && result.x <= 0.5 && result.y > 0.5))
gl_Position = result;
};
Столько условий из-за того, что в центре видимой области стоит дом, который по своей сути тоже плотная поверхность, через который не должен проходить дождь. Проблемы возникают непосредственно при попытке перестать отрисовывать капли, коснувшиеся поверхности.
glm::mat4 transformic;
transformic = glm::translate(transformic, glm::vec3(0.0f, (GLfloat)raindropY, 0.0f));
if (raindropY <= 3 * floor[4] + 0.05) {
raindropY = -(float)0.1f;
}
GLint transformLocRainDrops = glGetUniformLocation(shaderProgramForRaindrops, "raindropsdown");
glUniformMatrix4fv(transformLocRainDrops, 1, GL_FALSE, glm::value_ptr(transformic));
glBindVertexArray(VAOs[2]);
glDrawArraysInstanced(GL_LINES, 0, 2, 200);
glBindVertexArray(0);
raindropY = raindropY - 0.003;
Очевидно, так как я отрисовываю линию, то при отсутствии отрисовки одной из точек происходит коллапс и билеберда, появляются линии на пол экрана, которые на следующем кадре исчезают и т.д. И я, честно говоря, даже не могу толком сообразить, как это исправить. Пытался играть с прозрачностью, назначая в точке соприкосновения точке полную прозрачность, но это ведь прозрачность точке, а не линии, следовательно, думаю не в ту сторону. Может есть у кого идеи как это правильно реализовать? Есть вариант с тем, чтобы в этой самой точке соприкосновения возвращать точку с точной координатой сопротивления и нулевой прозрачностью, что-то вроде этого:
#version 460 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aOffset;
uniform mat4 raindropsdown;
vec4 result;
void main()
{
result = raindropsdown * vec4(aPos + aOffset, 0.0, 1.0);
if (result.x < -0.5 && result.y < -0.5)
gl_Position = vec4(result.x, -0.5f, 0.0f, 0.0f);
else if (result.x > 0.5 && result.y < -0.5)
gl_Position = vec4(result.x, -0.5f, 0.0f, 0.0f);
else if (result.x >= -0.5 && result.x <= 0.5 && result.y <= 0.5)
gl_Position = vec4(result.x, 0.5f, 0.0f, 0.0f);
else
gl_Position = result;
};
Но тут возникает сразу две проблемы, и точки продолжают отрисовываться и по сути теряется идея оптимизации и при этом чудные линии вообще никуда не деваются и всё становится ещё хуже, вот скрин:
Ну и ещё небольшой нюанс, на который я не нашёл внятного ответа в гугле, есть ли какой-то универсальный механизм создания событий изнутри шейдера? Например, для той же анимации разбивающихся капель? А то у меня вообще нет идей, как мне нарисовать даже пару линий в стороны в точке соприкосновения поверхностей.