Наконец-то он полностью заработал! Решением для меня было сначала нарисовать все в буфере цвета и буфере глубины, но не в буфере трафарета (в основном просто включить тест глубины перед рисованием и установить glStencilMask (0)). Затем нарисуйте элемент, который я хочу выделить, убедившись, что я запишите его в буфер трафарета с помощью glStencilMask (255) и убедитесь, что он проходит тест трафарета с помощью glStencilFunc (GL_ALWAYS, 1, 255)
Затем отключите тест глубины для визуализации блестящего контура / формы для визуализации через другие объекты с помощью glStencilMask (0) и убедитесь, что он не пройдет проверку трафарета при визуализации поверх другого куба, используя glStencilFunc (GL_NOTEQUAL , 1, 255)
Визуализируйте блестящий куб, снова включите тест глубины, и он работает!
Также убедитесь, что для glStencilOp установлено значение: glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
Таким образом, буфер трафарета будет записан только тогда, когда запись элемента в буфер трафарета не будет перекрыта другими объектами (не пройден тест глубины).
Для меня самой большой проблемой было выяснить, почему буфер трафарета будет обновляться, даже если мой объект будет закрыт другими объектами, и о чем я не подумал, так это о том, что я рендерил его раньше других объектов, поэтому было нечего перекрывать это когда он был визуализирован! поэтому убедитесь, что вы сначала визуализируете свою сцену, а затем ваши объекты, которые будут иметь это свойство, чтобы вы могли использовать функции glStencilOp
glBindFramebuffer(GL_FRAMEBUFFER, this->screenFBO);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, // stencil fail
GL_KEEP, // stencil pass, depth fail
GL_REPLACE); // stencil pass, depth pass
glStencilMask(255);
glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glStencilMask(0);
this->renderEntity(entityBuffer[0]); // skybox
glStencilMask(0);
glStencilFunc(GL_ALWAYS, 1, 255);
this->renderEntity(entityBuffer[6]); // sphere
this->renderEntity(entityBuffer[1]);
this->renderEntity(entityBuffer[2]);
this->renderEntity(entityBuffer[4]);
this->renderEntity(entityBuffer[5]);
this->renderEntity(entityBuffer[7]);
this->renderEntity(entityBuffer[8]);
this->renderEntity(entityBuffer[9]);
this->renderEntity(entityBuffer[10]);
this->renderEntity(entityBuffer[11]);
this->renderEntity(entityBuffer[12]);
glStencilFunc(GL_ALWAYS, 1, 255);
glStencilMask(255);
this->renderEntity(entityBuffer[3]); // normal cube
glStencilMask(0);
glStencilFunc(GL_NOTEQUAL, 1, 255);
glDisable(GL_DEPTH_TEST);
entityBuffer[3]->setShader(5);
entityBuffer[3]->setScale(glm::vec3(1.05));
this->renderEntity(entityBuffer[3]); // white cube
entityBuffer[3]->setScale(glm::vec3(1.0));
entityBuffer[3]->setShader(0);
glEnable(GL_DEPTH_TEST);
результат можно увидеть здесь
person
Joshua Micheletti
schedule
26.11.2020