2013-10-10 4 views
2

Я использую буферы визуализации до сих пор при использовании теста глубины с пользовательскими FBOs. Теперь мне нужно заменить текстуры глубины (так как мне нужно прочитать ее в шейдере). Я рассматриваю разные источники, такие как here, и вижу, что GL_FLOAT используется как тип данных. В other используются примеры GL_UNSIGNED_BYTE и иногда даже GL_INT. Также внутренний формат может быть GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32.Оптимизационные настройки для прикрепления текстуры глубины FBO

У меня вопрос, какой вариант лучше всего с точки зрения производительности и качества? Я уверен, что с компонентом глубины 32 бит глубина теста должна быть более точной, но как насчет типа данных? Какой из них обычно следует использовать?

+2

Традиционно несколько лет назад можно было использовать 24-битную глубину (с трафаретом или без него), или 16 бит на некоторых дешевых карточках. 32-битная целая глубина никогда не поддерживалась должным образом. В настоящее время я просто перейду с плавающей точкой, это более или менее универсально поддерживается, быстро и не полно с искаженным [quirks] (http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html), как целое вещество , – Damon

ответ

2

Использование GL_UNSIGNED_BYTE, GL_FLOAT и т. Д., Как вы описали на самом деле тип Pixel Transfer. Это тот тип, который использует OpenGL, когда он считывает/записывает данные о пикселях из/в буфер, в OpenGL драйвер выполняет преобразование типа данных, чтобы гарантировать совместимость прочитанных/записанных значений. В OpenGL ES это было полностью удалено, но во всех случаях внутренний формат глубины renderbuffer должен быть одним из GL_DEPTH_COMPONENT<X>{F} или GL_DEPTH<X>_STENCIL<Y>. Эти форматы определяют как тип данных, так и формат, используемые внутри.

Для обеспечения максимальной производительности совместите тип компонента с типом передачи пикселей, чтобы избежать преобразования пикселов драйверов. (например, GL_FLOAT для передачи пикселов является хорошим совпадением для GL_DEPTH_COMPONENT32F). Однако это действительно применимо только тогда, когда вы хотите использовать содержимое буфера глубины/трафарета для выполнения чего-то вне OpenGL (например, чтение или запись буфера с использованием PBO).

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

+0

Что вы подразумеваете под «ignore» Не устанавливать его вообще? Или использовать только любой тип? –

+0

@MichaelIV: Используйте любой тип, потому что я уверен, что вы передаете «NULL» в качестве пиксельных данных, когда вы вызываете 'glTexImage2D (...)' для настройки вложения текстуры. «NULL» означает, что передача пикселов в первую очередь не происходит: P Если, однако, вы собираетесь читать текстуру в клиентскую память с помощью PBO и «glReadPixels (...)», тогда формат/тип передачи пикселей будет очень важно, и вы будете следовать правилам, которые я объяснил выше, - сопоставить размер/тип компонента, чтобы минимизировать накладные расходы на драйвер. –

+0

@MichaelIV: Я понимаю, что забыл обсудить компромисс между точностью и эффективностью в своем ответе. Они уже были затронуты в комментариях к вопросу, 24-битные буферы глубины являются наиболее широко поддерживаемыми форматами оконных пикселов ... в FBOs у вас есть _LOT_ больше гибкости, но если вы можете уйти с меньшим форматом, вы получите более высокая производительность просто потому, что она уменьшает пропускную способность памяти. FP на самом деле ** меньше ** точного в целом, но допускает больший диапазон значений глубины, особенно в дробном диапазоне, очень близком к ближней плоскости; улучшая точность в некоторых областях. –

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