Вывод координат из вершинного шейдера Cg

В статье здесь говорится:

Это достигается делением x, y и z на w. Полученные координаты называются нормализованными координатами устройства. Теперь все видимые геометрические данные лежат в кубе с позициями между ‹-1, -1, -1> и ‹1, 1, 1> в OpenGL и между ‹-1, -1, 0> и ‹1, 1 , 1> в Direct3D.

Это создает проблему для кросс-платформенных шейдеров, которые хотят проверить координату Z по какой-то конкретной причине. Есть ли способ получить координату Z в том же диапазоне, независимо от платформы?


person Mr. Boy    schedule 14.11.2011    source источник


Ответы (3)


Где вы проводите это тестирование Z, которое вы хотите сделать?

Если вы делаете это во фрагментном шейдере, вам все равно. gl_FragCoord.z или любой эквивалент Cg находится в пространстве окна. Протяженность оконного пространства по оси Z определяется как glDepthRange; по умолчанию он изменяется от 0 до 1.

Если вы выполняете этот тест в вершинном шейдере, вам просто придется с этим смириться. Лучше провести тест в пространстве камеры, а не в пространстве клипа или в пространстве NDC. По крайней мере, тогда вы обычно имеете дело с расстояниями мирового масштаба.

person Nicol Bolas    schedule 14.11.2011
comment
Меня немного смутило обсуждение того, что у фрагментных шейдеров другой диапазон Z. Разве дело не в том, что вершинный шейдер выдает Z (и все другие значения), интерполированные по полигону и используемые фрагментным шейдером? Если нет, то какие этапы я пропустил? - person Mr. Boy; 15.11.2011
comment
@John: позиции, выдаваемые вершинным шейдером, находятся в однородных координатах пространства отсечения. Затем эти позиции обрезаются, разделяются по перспективе и трансформируются в пространство окна. Вот что определяют glViewport и glDepthRange: пространство между NDC и окном. Подробности можно найти здесь. - person Nicol Bolas; 15.11.2011
comment
В моем случае я использую орфографическую проекцию. Означает ли это, что позиции, выводимые моим VS, будут такими же, как и позиции, переданные на этап PS? Они кажутся, X/Y по крайней мере. - person Mr. Boy; 15.11.2011
comment
@John: я не знаю, как с этим справляются Cg или HLSL, но в OpenGL gl_FragCoord находится в пространстве window. Таким образом, это относительно окна просмотра, которое вы установили с помощью glViewport и glDepthRange. Так что нет, не будет. - person Nicol Bolas; 15.11.2011
comment
да моя ошибка. Я думал, что мы всегда работали в диапазоне [0,1], т.е. независимо от размеров цели рендеринга. - person Mr. Boy; 16.11.2011

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

Первое, что приходит на ум, это использовать glDepthRange (или его возможный аналог D3D), чтобы изменить отображение с NDC z на глубину. Но это не сработает, так как передача [-1,1] в glDepthRange просто зажмет его на [0,1] и в D3D тоже нельзя установить на [0.5,1], так как до этого все равно все будет обрезано против [0,1].

Но я не думаю, что вам это нужно слишком часто, так как в шейдере фрагмента/пикселя вы получаете координаты окна с нормализованной глубиной [0,1] (я ожидаю, что Cg будет вести себя здесь аналогично GLSL). И в вершинном шейдере вам все равно чаще понадобится глубина мира или пространства просмотра, а не NDC z. Если вам это действительно нужно, вы можете просто принять решение на основе определения препроцессора в шейдере.

person Christian Rau    schedule 14.11.2011

Обычно избегают использования нелинейного значения z/w пространства NDC. Обычно это делается путем передачи абсолютного расстояния до вершины Z путем дополнительного варьирования. Таким образом, вещи остаются портативными.

person datenwolf    schedule 14.11.2011
comment
Этот ответ кажется очень полезным, но я не совсем его понимаю! Можете ли вы (или кто-то другой) пояснить, как меня смущает язык? - person Mr. Boy; 15.11.2011
comment
@John: Какая часть этого языка вас смущает? Если вам нужно линейное значение Z, вы просто получаете линейное значение Z из вершинного шейдера и передаете его вручную. - person Nicol Bolas; 15.11.2011
comment
@NicolBolas - передача абсолютного расстояния до вершины Z дополнительным изменением не имеет смысла, это неправильный английский. - person Mr. Boy; 15.11.2011
comment
@John: вариация в этом предложении не прилагательное, а существительное. - person datenwolf; 15.11.2011
comment
@datenwolf: разное не существительное, из него нельзя сделать одно :). Я думаю, что вы говорите, что обычно это делается путем передачи абсолютного расстояния Z вершины + дополнительного значения? Возможно, вы можете добавить конкретный/алгебраический пример для пояснения. - person Mr. Boy; 15.11.2011
comment
@John: Именно в этом контексте. В GLSL переменная — это переменная особого типа, передаваемая от одного этапа шейдера к следующему этапу шейдера. - person datenwolf; 15.11.2011