У меня есть небольшая система частиц спрайтов, созданная с помощью OpenGL, и я использую текстуры для рисования основного пламени. Пламя воспроизведено симметрично, чтобы показать, как оно ведет себя в небольшой коробке/сцене. И, как показано на рисунках ниже, есть две проблемы:
1- Чтобы создать несколько хорошо выглядящий эффект пламени, я хочу использовать аддитивное смешивание с моими частицами, но смешивание также принимает во внимание цвет более глубокой голубой панели и создает белое пламя.
2.1. Кроме того, для правильной реализации аддитивного смешивания я должен отключить проверку глубины при рисовании частиц, но при этом включить рисование частиц, даже если они должны быть «скрытыми».
2.2 - Если я включу тест глубины при рисовании частиц, вот как это будет выглядеть.
Если это поможет, вот текстура, которую я применяю к частицам.
Вот соответствующий код, который отображает сцену и частицы.
void drawParticles()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glBindTexture(GL_TEXTURE_2D,explosionTexture[0]);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
for (int i = 0; i < particlesNumber; ++i)
{
glPointSize(50.0f);
glBegin(GL_POINTS);
glColor4f(particlesArray[i].color[0],particlesArray[i].color[1],particlesArray[i].color[2],0.5f);
glVertex3f(particlesArray[i].position[0],particlesArray[i].position[1],particlesArray[i].position[2]);
glEnd();
}
glBindTexture(GL_TEXTURE_2D, 0);
glDisable( GL_BLEND );
glEnable( GL_DEPTH_TEST );
glPopAttrib();
}
void drawScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60.0f, (GLdouble) g_width / (GLdouble) g_height, 0.1f, 300.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( dist*sin(phi)*sin(theta), dist*cos(phi), dist*sin(phi)*cos(theta), 0, 0, 0, 0, 1, 0 );
glEnable( GL_DEPTH_TEST );
glDisable( GL_BLEND );
glBegin( GL_LINES );
glColor3f( 1.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.5f, 0.0f, 0.0f );
glColor3f( 0.0f, 1.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.5f, 0.0f );
glColor3f( 0.0f, 0.0f, 1.0f );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, 0.5f );
glEnd();
glBegin( GL_QUADS );
glColor4f( 1.0f, 1.0f, 1.0f , 0.0f);
glVertex3f( -1.0f, -0.2f, 1.0f );
glVertex3f( 1.0f, -0.2f, 1.0f );
glVertex3f( 1.0f, -0.2f, -1.0f );
glVertex3f( -1.0f, -0.2f, -1.0f );
glColor4f( 1.0f, 1.0f, 0.0f , 0.0f );
glVertex3f( 1.0f, -2.0f, 1.0f );
glVertex3f( 1.0f, -2.0f, -1.0f );
glVertex3f( 1.0f, -0.2f, -1.0f );
glVertex3f( 1.0f, -0.2f, 1.0f );
glColor4f( 1.0f, 0.0f, 1.0f , 0.0f );
glVertex3f( -1.0f, -2.0f, 1.0f );
glVertex3f( -1.0f, -2.0f, -1.0f );
glVertex3f( -1.0f, -0.2f, -1.0f );
glVertex3f( -1.0f, -0.2f, 1.0f );
glColor4f( 0.0f, 1.0f, 1.0f , 1.0f );
glVertex3f( 1.0f, -2.0f, -1.0f );
glVertex3f( -1.0f, -2.0f, -1.0f );
glVertex3f( -1.0f, -0.2f, -1.0f );
glVertex3f( 1.0f, -0.2f, -1.0f );
glEnd();
glPushMatrix();
drawParticles();
glScalef(1.0f, -1.0f, 1.0f);
drawParticles();
glPopMatrix();
glutSwapBuffers();
}
Я открыт для любых предложений, даже связанных с шейдерами (но мне было бы интересно узнать, возможно ли это сделать с помощью простого OpenGL).
ОБНОВЛЕНИЕ:
Может быть, я был неясен, меня не обязательно интересует решение со строго фиксированным конвейером, я хочу знать, как управлять аддитивным смешиванием в сцене, даже если это означает добавление кода шейдеров в мой проект.
Теперь, как указал Коломбо, включение тестирования глубины и отключение записи глубины решило мою вторую проблему. Теперь, что касается проблемы аддитивного смешивания, я до сих пор понятия не имею, как управлять аддитивным смешиванием в сцене. Несмотря на то, что в сцене может не быть таких основных цветов, проблема все еще остается, поскольку пламя по-прежнему будет белым, и я открыт, чтобы узнать, что мне делать с пиксельным шейдером, как было предложено.