[GLSL]Как сравнить значение z всех вершин в мировых координатах?

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

    gl_Position = ftransform();
    posWorld = gl_ModelViewMatrix * gl_Vertex;

Вопрос в том, могу ли я теперь получить максимальное/минимальное значение posWorld среди всех вершин? Так что я могу получить диапазон глубины вершины, но не диапазон буфера глубины.

Если это невозможно, как я могу получить значение z ближней/дальней плоскости в мировой системе координат?

с наилучшими пожеланиями,

Цзянь


person superpanda    schedule 22.09.2011    source источник
comment
gl_ModelViewMatrix переходит в пространство view, а не в мировое пространство. Вот почему он называется Model View: он переходит от модели к представлению.   -  person Nicol Bolas    schedule 24.09.2011


Ответы (2)


Да, это возможно с OpenGL. Я использую аналогичную технику для вычисления ограничивающей рамки объекта на графическом процессоре. Вот шаги:

  1. Расположить рендер-буфер размером 1x1 типа RGBA_32F в собственном FBO. Установите в качестве цели рендеринга (без глубины/трафарета, только одна цветовая плоскость). Это может быть пиксель более крупной текстуры, и в этом случае вам необходимо правильно настроить область просмотра.
  2. Очистить с базовым значением. Для «min» это будет какое-то огромное число, для «max» — отрицательное огромное.
  3. Установите функцию смешивания 'min' или 'max' соответственно с коэффициентами (1,1).
  4. Нарисуйте свою сетку с помощью шейдера, который создает точку с координатой (0,0,0,1). Выведите цвет, содержащий вашу исходную мировую позицию вершины.

Отсюда вы можете перейти к дальнейшей оптимизации. Например, вы можете получить как «минимум», так и «максимум» в одном вызове отрисовки, используя геометрический шейдер и инвертируя позицию для одного из выходных пикселей.

person kvark    schedule 24.09.2011
comment
Спасибо за ваш ответ :D Я пытался сделать это в шейдерах... и не совсем вас понял.. :( - person superpanda; 27.09.2011
comment
Я шаг за шагом объяснил, что вы изначально просили и что @Cristobal считал невозможным. Как уже упоминалось, эта схема работает в моем движке для обновления ограничивающих рамок. Дело в том, что это работает. А если не понятно - пожалуйста, задавайте более конкретные вопросы (если все же интересно). - person kvark; 27.09.2011
comment
я работаю с xip builder, и что я могу сделать, так это заменить стандартный шейдер, загрузив свои собственные файлы шейдеров, которые являются вершинным шейдером и фрагментным шейдером. И я работаю с объемными данными, а не с сеткой. можно ли заставить ваш метод работать в шейдерах? Спасибо - person superpanda; 27.09.2011
comment
Да, конечно, я делаю это в шейдерах. И будут это какие-то данные или меш - не важно. Вот мой геометрический шейдер для обновления BBox: code.google .com/p/kri/source/browse/gpu/cull/box_g.glsl. Это очень просто, основное действие выполняется в настройке состояния OpenGL клиента. - person kvark; 27.09.2011
comment
для меня доступны только вершинные/фрагментные шейдеры... геометрического шейдера нет в кадре :( - person superpanda; 27.09.2011
comment
Это не проблема. Геометрический шейдер просто разбивает данные вершин на 2 потока. Вы можете добиться того же эффекта, выполнив 2 вызова отрисовки. - person kvark; 27.09.2011

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

с другой стороны, вы можете иметь доступ к нормализованным ближним/дальним плоскостям в фрагментном шейдере, http://www.opengl.org/wiki/GLSL_Predefined_Variables#Fragment_shader_uniforms.
и с помощью некоторых юниформ-переменных вы можете приблизить или приблизить мир.

person labotsirc    schedule 22.09.2011
comment
Спасибо за ответ. Не могли бы вы дать мне подсказку о том, какие универсальные переменные использовать для преобразования от нормализованного ближнего/дальнего мира к близкому/дальнему миру? - person superpanda; 23.09.2011
comment
@superpanda Там перечислены только 3 универсальных значения, и вы должны использовать все из них. Проблема в том, что вам нужно больше, чем это, если вы хотите выйти в космос. Для начала вам нужна ваша проекционная матрица (точнее, обратная ей). Честно говоря, было бы намного проще просто передать его. Эти значения для ближнего и дальнего действия получены из значений ближнего и дальнего пространства для просмотра, которые вы используете с glFrustum или gluPerspective. - person Nicol Bolas; 24.09.2011
comment
Да, передайте матрицу проекции, как предложил Никол. - person labotsirc; 24.09.2011
comment
спасибо, передайте проекционную матрицу! Я решил эту проблему, обратившись к этой странице блога: olivers.posterous.com /linear-deep-in-glsl-for-real - person superpanda; 27.09.2011