2009-08-17 10 views
14

Хорошо, в моем шейдере фрагмента GLSL Я хочу иметь возможность рассчитать расстояние фрагмента от определенной строки в пространстве.Как вычислить gl_FragCoord в 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?

ответ

11

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

+1

Я ошибался в том, что вы ошибаетесь, но это касается использования gl_ModelViewProjectionMatrix * gl_Vertex, потенциально представляющего ошибки вычисления. – karx11erx

+2

Nitpick: это фактически даст вам координаты клип-пространства, а не нормализованные координаты устройства, так как вы не выполняете разделение перспективы, которое происходит во время процесса растеризации (между шейдером вершин и шейдером фрагмента). http://www.glprogramming.com/red/chapter03.html#name1 – Pike65

+0

@ Pike65 Это не просто ничто, это должно привести к совершенно другим значениям для перспективной проекции. –

0

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

Edit:

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

+0

ftransform создает позицию, а не фрагкодер. Вопрос заключается не в том, как получить позицию. –

+0

Мой ответ был не совсем ошибочным. Вам нужно масштабировать fake_frag_coord с вашими размерами экрана, но вы можете получать разные результаты в зависимости от того, используете ли вы fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex или = ftransform(). – karx11erx

-2
varying vec2 fake_frag_coord; 
//in vertex shader: 

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy 
0

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

+1

'gl_FragCoord' ** не ** в НДЦ. Он находится в координатах окна. –

 Смежные вопросы

  • Нет связанных вопросов^_^