Запись данных текстуры в буфер глубины - PullRequest
6 голосов
/ 26 декабря 2010

Я пытаюсь реализовать метод, описанный в: Компоновка изображений с глубиной .

Идея состоит в том, чтобы использовать существующую текстуру (загруженную из изображения) в качестве маски глубины, чтобы подделать 3D.

Проблема, с которой я сталкиваюсь, заключается в том, что glDrawPixels недоступен в OpenglES. Есть ли способ сделать то же самое на iPhone?

1 Ответ

7 голосов
/ 04 января 2011

Буфер глубины более скрыт, чем вы думаете в OpenGL ES; не только отсутствует glDrawPixels, но gl_FragDepth был удален из GLSL. Поэтому вы не можете написать пользовательский фрагментный шейдер для буферизации значений в буфере глубины, поскольку вы можете выдвигать цвета.

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

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

РЕДАКТИРОВАТЬ: в целях упрощения примера, предположим, что вы упаковывали всю информацию о глубине в красный канал текстуры. Это дало бы вам буфер глубины с очень низкой точностью, но для ясности можно написать быстрый фрагментный шейдер, например:

void main()
{
    // write a value to the depth map
    gl_FragColor = vec4(gl_FragCoord.w, 0.0, 0.0, 1.0);
}

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

Чтобы затем использовать текстуру в будущем фрагментном шейдере, вы должны сделать что-то вроде:

uniform sampler2D depthMap;

void main()
{
    // read a value from the depth map
    lowp vec3 colourFromDepthMap = texture2D(depthMap, gl_FragCoord.xy);

    // discard the current fragment if it is less close than the stored value
    if(colourFromDepthMap.r > gl_FragCoord.w) discard;

    ... set gl_FragColor appropriately otherwise ...
}

РЕДАКТИРОВАТЬ2: вы можете видеть намного более умное отображение от глубины до значения RGBA здесь . Чтобы связать непосредственно с этим документом, OES_depth_texture определенно не поддерживается ни на iPad, ни на iPhone третьего поколения. Я не проводил полный тест в другом месте.

...