2015-07-29 2 views
2

Я использую значения по умолчанию OpenGL, такие как glDepthRangef (0.0,1.0) ;, gldepthfunc (GL_LESS); и glClearDepthf (1.f); потому что мои проекционные матрицы меняют правую координату на левую координату. Я имею в виду, что моя ближняя плоскость и дальномерные z-значения должны быть [-1, 1] в НДЦ.Буфер глубины с двумя разными проекционными матрицами

Проблема заключается в том, когда я рисую два объекта на одной FBO в том числе же БВУ, например, как этот код ниже,

glEnable(GL_DEPTH_TEST); 
    glClearDepthf(1.f); 
    glClearColor(0.0,0.0,0.0,0.0); 
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 

    drawObj1(); // this uses 1) the orthogonal projection below 
    drawObj2(); // this uses 2) the perspective projection below 

    glDisable(GL_DEPTH_TEST); 

всегда, object1 выше Object2.

1) ортогональны enter image description here

2) перспективы enter image description here

Однако, когда они используют ту же проекцию бы это ни было, оно работает отлично.

В какой части, по-вашему, мне следует пройти?

--Updated--

Coverting глаз координат в НДЦ экран координат, что на самом деле происходит?

Мое понимание состоит в том, что после обоих выступов его форма НДЦ такая же, как изображения ниже, его значение z после умножения 2) перспективная матрица не нуждается в искажении. Однако, согласно хорошему ответу дербаса, если z-значение в координате вида умножается на перспективную матрицу, значение z будет гиперболически искажено в НДЦ.

Если это так, если одна точка вершины, например, [-240.0, 0.0, -100.0] в координате глаза (зрения) с [w: 480.0, h: 320.0], и я обрезал ее с помощью [ 0,01, -100], было бы [-1,0, -1] или [something> = - 1,0, -1] в NDC? И его значение z остается таким же, как -1, не так ли? когда его z-значение искажено?

1) ортогональным enter image description here

2) Перспектива enter image description here

ответ

2

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

В случае с препроцессором значение z пробела z будет гиперболически искажено до значения NDC z. В ортогональном случае он просто масштабируется и сдвигается.

Если ваш «Obj2» лежит только в плоской плоскости z_eye = const, вы можете предварительно охарактеризовать искаженную глубину, которую он должен иметь в перспективном случае. Но если он не имеет нулевой степени в глубину, это не сработает. Я могу думать о различных подходов для решения ситуации:

  1. «Фикс» глубины объекта два в пиксельный шейдер, регулируя gl_FragDepth в соответствии с гиперболической искажением ваш г буфер ожидает.

  2. Используйте линейный z-буфер, он же. a w buffer.

Эти подходы концептуально являются взаимно противоположными.В обоих случаях вы играете с gl_FragDepth, чтобы он соответствовал соглашениям другого прохода рендеринга.

ОБНОВЛЕНИЕ

Я понимаю, потому что после того, как проекций, его форма НДЦ такое же как изображения ниже, его Z-значение после умножения 2) в перспективе матрица не должна быть искажена ,

Ну, эти изображения показывают преобразование из места клипа в НДЦ. И эта трансферация - это то, что делает матрица проекции, за которой следует разделение перспективы. Когда он находится в нормализованных устройствах, никаких дальнейших искажений не происходит. Он просто линейно преобразуется в оконное пространство z ​​в соответствии с установкой glDepthRange().

Однако, в соответствии с хорошим ответом derbass, в случае г-значение координатного умножается на перспективном матрицу Z-значение будет гиперболической искажены в НДЦ.

Перспективный матрица применяется к полному 4D однородного глаза пространственного вектора, поэтому он применяется к z_eye, а также x_eye, y_eye, а также w_eye (который, как правило, только 1, но не обязательно) ,

Таким образом, в результате NDC координаты для перспективного случая hyberbolically искажается

  f + n  2 * f * n    B 
z_ndc = ------- + ----------------- = A + ------- 
     n - f  (n - f) * z_eye   z_eye 

время, в ортогональном случае, они просто по линейному закону преобразуется в

  - 2    f + n  
z_ndc = ------- z_eye - --------- = C * z_eye + D 
     f - n   (f - n) 

Для n=1 и f=10, это будет выглядеть так (обратите внимание, что я построил диапазон частично за пределами усеченного конуса. Конечно, отсечение предотвратит эти значения от GL). plot of z_clip as function of z_eye for perspective and orthogonal projection

Если это так, если позиция одна вершина, например, [-240,0, 0.0, -100.0] в глаз (смотреть) координат с [W: 480,0, 320,0 ч:], и I обрезал его с [-0.01, -100], было бы [-1,0, -1] или [something> = - 1,0, -1] в NDC? И его значение z остается таким же, как -1, не так ли? когда его z-значение искажено?

Очки на дальнем плане всегда преобразуются в z_ndc=1, и указывает на ближайшем самолете в z_ndc=-1. Так построены проекционные матрицы, и именно здесь пересекаются два графика на графике. Поэтому для этих тривиальных случаев разные отображения вообще не имеют значения. Но для всех других расстояний они будут.

+0

спасибо. Я думаю, ты прав, но меня все еще путают. Не могли бы вы ответить на мой вопрос, который я только что обновил? – Sung

+0

@SungWoo: Я обновил свой ответ. – derhass

+0

Спасибо за ваше время. – Sung

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