Выделение объекта с использованием буфера трафарета дает неверный результат - PullRequest
2 голосов
/ 31 октября 2019

Я пытаюсь использовать буфер трафарета, чтобы нарисовать контурную границу позади модели.

Я использую 2 прохода рендеринга, сначала рендеринг модели и использую GL_ALWAYS для записи 1 в буфер трафарета, а затем я рендеринг слегка увеличенной версии модели, которая использует GL_NOTEQUAL сзначение ref 1, поэтому в основном пропускаются только фрагменты, которые находятся за пределами исходного куба, что делает подсветку.

Я получаю странный результат, контур не отображается полностью, и когда я перемещаю камеру достаточно,полностью исчезает, как будто трафаретная проверка масштабированного куба не проходит вообще. Вот суть цикла рендеринга (shader3 просто выводит цвет для границы):

while (!glfwWindowShouldClose(window))
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClearStencil(0);
    renderer.Clear();    
    ...
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f);
    UniformMat4f projectionUniform("u_Projection");
    projectionUniform.SetValues(projection);

    glm::mat4 view = camera.GetView();
    UniformMat4f viewUniform("u_View");
    viewUniform.SetValues(view);

    modelUniform.SetValues(glm::translate(glm::mat4(1.0f), glm::vec3(5.0f, 0.0f, 0.0f)));

    shader1.SetUniform(projectionUniform);
    shader1.SetUniform(viewUniform);
    shader1.SetUniform(modelUniform);

    glStencilFunc(GL_ALWAYS, 1, 0xFF);
    glStencilMask(0xFF);

    renderer.Draw(model, shader1);

    modelUniform.SetValues(glm::scale(glm::translate(glm::mat4(1.0f), glm::vec3(5.0f, 0.0f, 0.0f)), glm::vec3(1.1f, 1.1f, 1.1f)));
    shader3.SetUniform(projectionUniform);
    shader3.SetUniform(viewUniform);
    shader3.SetUniform(modelUniform);

    glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    glStencilMask(0x00);
    glDisable(GL_DEPTH_TEST);
    renderer.Draw(model, shader3);
    glEnable(GL_DEPTH_TEST);
}

Сначала я попробовал это с моделью nanosuit из crysis, и она работает, как я описал, не показывая все частии в конечном итоге исчезает при перемещении камеры. Я решил попробовать простую геометрию, чтобы проверить это, и попытался очертить простой куб и получил тот же результат: enter image description here

1 Ответ

3 голосов
/ 31 октября 2019

Проблема заключается в вызове glStencilMask(0x00); в конце основного цикла. значение по умолчанию для трафаретной маски 0xff (8 бит см. glStencilMask). OpenGL - это государственный двигатель. Состояние сохраняется до тех пор, пока оно снова не изменится (даже за кадрами).
glClear учитывает состояние маски цвета, глубины и трафарета. Если маска трафарета 0x00, то буфер трафарета вообще не очищается.

Установите маску трафарета 0xff, прежде чем очистить буфер трафарета для решения проблемы:

glStencilMask(0xFF);
renderer.Clear(); 
...