Как вычислить gl_FragCoord в glsl
-
18-09-2019 - |
Вопрос
Хорошо, в моем фрагментном шейдере GLSL я хочу иметь возможность вычислять расстояние фрагмента от определенной линии в пространстве.
В результате я сначала пытаюсь использовать изменяющийся набор vec2 в своем вершинном шейдере, чтобы отразить то, что в итоге получается. gl_FragCoord
:
varying vec2 fake_frag_coord;
//in vertex shader:
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
fake_frag_coord=(gl_ModelViewProjectionMatrix * gl_Vertex).xy;
Теперь во фрагментном шейдере я ожидаю:
gl_FragCoord.xy==fake_frag_coord
Но это не так.Какую операцию выполняет конвейер? gl_Position
превратить это в gl_FragCoord
что я пренебрегаю делать fake_frag_coord
?
Решение
gl_FragCoord — это координаты экрана, поэтому вам потребуется информация о размере экрана и тому подобном, чтобы создать его на основе позиции.Я думаю, что созданный вами fake_frag_coord будет соответствовать точке на экране в нормализованных координатах устройства (от -1 до 1).Итак, если вы умножите на половину размер экрана в определенном измерении, а затем прибавите этот размер, вы получите реальные пиксели экрана.
Другие советы
Проблема в том, что gl_ModelViewProjectionMatrix * gl_Vertex, вычисленная в шейдере, не всегда соответствует тому, что дает конвейер фиксированных функций.Чтобы получить идентичные результаты, выполните fake_frag_coord = ftransform().
Редактировать:
А затем масштабируйте его в соответствии с размерами вашего экрана.
Мне бы хотелось иметь больше репутации, чтобы я тоже мог придираться.Вот что я знаю.OpenGL автоматически выполняет за вас деление на W, поэтому к тому времени, когда позиция поступает во фрагментный шейдер, она уже находится в координатах NDC, и к тому времени W будет равно 1,0, единственный раз, когда вам нужно разделить на W, это если вы хотите выполнить те же математические вычисления на стороне ЦП и получить те же результаты, ИЛИ, если вы по какой-то странной причине хотели получить координаты NDC в своем вершинном шейдере.
varying vec2 fake_frag_coord;
//in vertex shader:
fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy