Как рассчитать gl_FragCoord в glsl

Хорошо, в моем фрагментном шейдере 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?


person DaedalusFall    schedule 17.08.2009    source источник


Ответы (3)


gl_FragCoord - это координаты экрана, поэтому вам потребуется информация о размере экрана и т. д., чтобы создать его на основе позиции. Созданный вами fake_frag_coord будет соответствовать точке на экране в нормированных координатах устройства, я думаю (от -1 до 1). Поэтому, если вы умножите размер экрана на половину в определенном измерении, а затем прибавите этот размер, вы получите фактические пиксели экрана.

person Jay Kominek    schedule 17.08.2009
comment
Я был неправ в том, что вы ошибаетесь, но прав в том, что вы используете gl_ModelViewProjectionMatrix * gl_Vertex, что может привести к ошибкам вычислений. - person Razzupaltuff; 08.09.2009
comment
Nitpick: это на самом деле даст вам координаты пространства отсечения, а не нормализованные координаты устройства, поскольку вы не выполняете разделение перспективы, которое происходит во время процесса растеризации (между вершинным шейдером и фрагментным шейдером). glprogramming.com/red/chapter03.html#name1 - person Pike65; 19.08.2011
comment
@ Pike65 Это не просто придирка, это должно привести к совершенно другим значениям для перспективной проекции. - person Christian Rau; 09.02.2012
comment
доза gl_FragCoord.xy==gl_Position.xy/gl_Position.w будет делать перспективное деление? - person toolchainX; 21.03.2013

Проблема заключается в том, что gl_ModelViewProjectionMatrix * gl_Vertex, вычисляемый в шейдере, не всегда соответствует тому, что дает фиксированный конвейер функций. Чтобы получить идентичные результаты, используйте fake_frag_coord = ftransform().

Редактировать:

А затем масштабируйте его с размерами вашего экрана.

person Razzupaltuff    schedule 07.09.2009
comment
ftransform выдает позицию, а не координату фрагмента. Вопрос не в том, как получить должность. - person Jay Kominek; 08.09.2009
comment
Мой ответ не был полностью неправильным. Вам нужно масштабировать fake_frag_coord с размерами экрана, но вы можете получить разные результаты в зависимости от того, используете ли вы fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex или = ftransform(). - person Razzupaltuff; 08.09.2009

Хотелось бы, чтобы у меня было больше репутации, чтобы я тоже мог придираться. Вот что я знаю. OpenGL автоматически выполняет Divide-By-W для вас, поэтому к тому времени, когда позиция поступает во фрагментный шейдер, она уже находится в координатах NDC, и к тому времени W будет равно 1,0, единственный раз, когда вам нужно делить на W, это если вы хотите проделать ту же математику на стороне процессора и получить те же результаты, ИЛИ, если вы по какой-то странной причине хотите получить координаты NDC в своем вершинном шейдере.

person Homer    schedule 08.07.2015
comment
gl_FragCoord нет в NDC. Это в координатах окна. - person Reto Koradi; 09.07.2015