Я работаю над фронтальным рендером для 2D-движка с использованием ортографической проекции. Я хочу использовать буфер глубины, чтобы избежать перерисовки. У меня есть 16-битный буфер глубины, камера с Z = 100, смотрящая на Z = 0, zNear - 1, а zFar - 1000. Каждый визуализированный спрайт устанавливает свои координаты Z во все более удаленные значения, что позволяет тесту глубины пропустить рендеринг. все, что находится внизу.
Однако я знаю, что положение Z в конечном итоге со значениями буфера Z является нелинейным. Я хочу использовать полное разрешение 16-битного буфера глубины, т.е. разрешить 65536 уникальных значений. Поэтому для каждого отображаемого спрайта я хочу увеличить позицию Z до следующей позиции, чтобы она соответствовала следующему уникальному значению буфера глубины.
Другими словами, я хочу повернуть увеличивающийся индекс (0, 1, 2, 3 ...) спрайта, который рисуется, в соответствующую позицию Z для каждого спрайта, чтобы иметь уникальное значение буфера глубины. Я не уверен в математике за этим. Какой расчет для этого?
Заметьте, я работаю в WebGL (в основном OpenGL ES 2), и мне нужно поддерживать широкий спектр аппаратного обеспечения, поэтому, хотя такие расширения, как gl_FragDepth, могут сделать это проще, я не могу использовать его по соображениям совместимости.
источник
Ответы:
Действительно, значения, хранящиеся в z-буфере, являются не линейными по отношению к фактическим z-координатам ваших объектов, а к их обратным значениям, чтобы дать большее разрешение тому, что находится вблизи глаза, чем тому, что ближе к задней плоскости.
Что вы делаете, что вы карту вашим ,
zNear
чтобы0
и вашиzFar
к1
. ДляzNear=1
иzFar=2
он должен выглядеть следующим образомСпособ расчета этого определяется:
куда
... и z_buffer_value является целым числом.
Выше приведено уравнение любезности этой удивительной страницы , которая действительно хорошо объясняет z-буферы.
Итак, чтобы найти необходимое
z
для данногоz_buffer_value
, мы просто очищаемz
:источник
z_buffer_value = k * (a + (b / z))
и просто переставлю для решенияz
, то я получу:z = b / ((z_buffer_value / k) - a)
- Как вы пришли к другой последней формуле?(v / k) - a => (v - k * a) / k
и рушитесь(k * b) / (v - (k * a))
. Это тот же результат.Может быть, вам следует изменить свой подход к чему-то более простому. Что я буду делать; Сохраняйте глубину Z, но сохраняйте список того, что вы делаете. Упорядочите этот список на основе значения глубины z и отобразите объекты в порядке списка.
Надеюсь, это поможет. Люди всегда говорят мне, чтобы все было просто.
источник
Так как у вас уже есть отсортированный список объектов для рендеринга (спереди назад), вам действительно нужно увеличить индекс Z? Разве вы не можете использовать «меньше или равно» для «функции проверки»? Таким образом, он на самом деле проверяет, нарисован ли уже определенный пиксель или нет.
источник