Предотвращает ли отбрасывание во фрагментном шейдере модификации буфера трафарета?

Я хочу, чтобы discard в моем шейдере фрагментов предотвращало запись этого фрагмента в буфер трафарета; У меня была идея визуального эффекта в моей игре, и ее можно было бы реализовать, если бы я мог полагаться на это поведение для discard.

Мой фрагментный шейдер не делает ничего особенного; он просто сэмплирует текстуру, и если альфа близка к 0, то discard иначе пишет.

void main()
{
    vec4 texColor = texture(tex, texCoord);
    if(texColor.a < 0.5f)
    {
        discard;
    }
    FragColor = texColor;
}

Однако, похоже, что я не могу полагаться на discard предотвращение записи трафаретного буфера в :

Если тестирование трафарета активно, отброшенные фрагменты все еще могут влиять на буфер трафарета. Тест шаблона может изменить буфер шаблона даже в случае сбоя теста шаблона или глубины. И поскольку тест трафарета выполняется до теста глубины, сбои теста глубины не могут помешать тесту шаблона обновить буфер трафарета.

Мне нужно, чтобы тест трафарета был активен во время рендеринга. Могу ли я не полагаться на discard, предотвращающий запись в буфер трафарета?


person Mr. Smith    schedule 13.08.2020    source источник


Ответы (1)


По обычным правилам порядка операций OpenGL тест трафарета происходит после выполнения фрагментного шейдера. Таким образом, фрагментный шейдер, выполняющий оператор discard, предотвратит запись в изображения фреймбуфера. За одним исключением.

Это исключение состоит в том, что порядок операций может быть изменен явным запросом FS. Если такой запрос не получен, все должно происходить в соответствии с первоначальным порядком (поэтому используется discard отключает ранние тесты фрагментов в качестве оптимизации).

В рассматриваемом абзаце говорится о том, как часть операции, называемой тестом трафарета, включает в себя потенциальное обновление буфера трафарета. То есть тест трафарета может как отбрасывать фрагмент, и изменять значение буфера трафарета в зависимости от того, как он был отброшен. Это отличается от теста глубины, который в случае неудачи никогда не обновляет значение буфера глубины.

person Nicol Bolas    schedule 14.08.2020
comment
Но это также то, о чем я говорю; Мне нужно, чтобы он не записывался в буфер трафарета, если я discard -- это буквально заголовок моего вопроса. - person Mr. Smith; 14.08.2020
comment
@Mr.Smith: я не уверен, как я мог бы быть более ясным, не удаляя важную информацию. Если вы не явно форсируете ранние тесты фрагментов, то фрагмент будет отброшен перед тестом шаблона, потому что тест шаблона выполняется после FS. То, что написано в моем третьем абзаце, объясняет, о чем говорила Вики, но это имеет значение только в том случае, если вы дошли до теста трафарета. Чего не произойдет, если вы заранее отбросите фрагмент, потому что... отбрасывание означает именно это. - person Nicol Bolas; 14.08.2020
comment
Охххх; Теперь я понимаю; Благодарность! Теперь, если бы я мог понять, почему Stackoverflow решил, что это хорошая идея, чтобы не дать мне отменить мой -1 ›.› - person Mr. Smith; 14.08.2020
comment
@Mr.Smith: Голоса против через 5 минут могут быть отозваны только после редактирования сообщения (что я только что сделал). Это делается для предотвращения конкурентного понижения, когда вы понижаете конкурирующий ответ, чтобы сделать свой более заметным, а затем через некоторое время отзываете свое отрицательное голосование, чтобы вернуть -1. - person Nicol Bolas; 14.08.2020