Модераторы: Rickert
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Depth inf-on to color channels 
:(
    Опции темы
ForceKeeper
Дата 20.6.2010, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 17.3.2010
Где: Минск

Репутация: нет
Всего: нет



Такой вопрос. Разбираюсь с главой из учебника "Shaders for game programmers and artists", которая касается глубины поля. Там приводится три способа реализации. Во втором при рендеринге в текстуру, мы в альфа-канал пишем глубину пикселя, преобразуя эту информацию так, чтобы в дальнейшем использовать ее как коэффициент, с которым мы будем смешивать нормальный рендер и заблюреный. Ну и все отлично, однако *неуставное* использование альфы лишает нас возможности ввести, скажем, полупрозрачные объекты. И вот в третьем варианте предлагается писать преобразованную информацию о глубине пикселя не в альфу, а в цветные каналы доп. текстуры. И там сказано, что писать лишь в один цветовой канал нельзя, так как под него выделяется 8 бит, а альфа на 24 идет. Поэтому автор книги предлагает разбить информацию на три куска. И вот он приводит пример, как это можно сделать.
Привожу код пасса, который пишет в текстуру информацию о глубине пикселей.
Вершинный шейдер.
Код

float4x4 view_proj_matrix;
float far_clip;
struct VS_OUTPUT 
{
   float4 Pos:     POSITION;
   float1 Depth:   TEXCOORD0;
};
VS_OUTPUT vs_main( 
   float4 inPos: POSITION, 
   float2 Txr1: TEXCOORD0
)
{
   VS_OUTPUT Out;
   float4 OutPos;
   // Compute the position of the vertex
   Out.Pos = OutPos = mul(view_proj_matrix, inPos);
   // Send the depth to the pixel shader for encoding
   Out.Depth = OutPos.w/far_clip;
   return Out;
}

Пиксельный.
Код
    
float4 ps_main( 
   float4 inDepth: TEXCOORD0
) : COLOR0
{
   //  Output the depth as computed by
   //  the vertex shader
   float4 Depth;
   Depth.w = 1.0;
   Depth.x = floor(inDepth.x*127)/127;
   Depth.y = floor((inDepth.x-Depth.x)*127*127)/127;
   Depth.z = 0;
   return Depth;
}


А теперь разбор полетов.
Сначала меня смущает, что информация о глубине вершины помещается в единичный флоут (используя почему-то регистр для текстурных координат), а пиксельный шейдер принимает эту информацию как флоут4.
Потом, камрад пишет, что строка
Код

Depth.x = floor(inDepth.x*127)/127;

передаст в красный канал старшие 8 бит (так как утверждается, что инфа о глубина на входе идет в 24 бита, а каналы цвета по 8). Ну ладно, пускай железо по дефолту при несовпадении размеров так поступает. Но зачем домножать (с учетом того, что инфа в инДепс уже в интервале от 0 до 1) на 127, округлять и делить обратно? Причем еще пишется, что вообще должно юзаться 255, но сделав замену на 127 мы оберегаем себя от выхода за разрядную сетку (guard against overflows) и это позволит в дальнейшем складывать вместе несколько информаций о глубине. Я слабо себе представляю, как это нас убережет от переполнения (т.к. разница между исходным числом, числом с пляской со 127 и числом с преобразованиями при 255 совсем не велика) и каким образом использование 127, а не 255, дает нам возможность складывать *глубинную* информацию, а в противном случае - нет.

Ну и чтобы окончательно отправить меня в перезагрузку, утверждается, что для того, дабы выделить под зеленый канал средние 8 бит, нужно отнять от входной информации значение, что мы сейчас имеем в красном канале, и далее провести ту же процедуру, что и с красным в начале (To repeat
the same process with the following 8 bits of precision, you simply need to remove the 8
high bits and repeat the same process). Этим занимается строка
Код

Depth.y = floor((inDepth.x-Depth.x)*127*127)/127;

И в чем фокус? Во-первых, мне опять же непонятны эти шаманства с домножениями + во-вторых, ну ладно, отняли (при этом я не знаю, как точно ведет себя проц видюхи, когда ему нужно отнять от куска памяти в 24 бита кусок в 8), но у нас-то в любом случае исходное число в 24 бита как было, так таковым и осталось, крайняя восьмерка битов изменилась и все. И если железяка при отправке 24-битного значения в 8-битное как брало старших 8 бит, так их и возьмет. И поэтому я не знаю каким чудом в зеленом канале вдруг очутятся средние 8 бит.

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

И совсем-совсем под занавес отмечу, что я отправил всю инфу глубины без этих домножений-делений просто в красный канал и результат ни на йоту не ухудшился. Каким финальный рендер был, таким и остался. 
PM MAIL WWW   Вверх
Rpahut
Дата 20.6.2010, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Регистр TEXCOORD0 используется вероятно потому что в нем значение глубины интерполируется между вершинами. И доступ к нему через float4 потому что он и есть float4. Используется всё равно только один флоат, так что пусть его.

Деление/умножение на 127 и floor() производится видимо с целью построить 16-битную карту из 24-битной с потерей точности. Как оно работает лично мне не совсем понятно, но напрямую 24 бита в восемь вы точно не запихаете. И если после этого шаманства там правда получаются 7-битные числа, две карты можно будет сложить не вылезая за пределы имеющегося байта. Восьмибитные карты тоже можно сложить, но в зависимости от того какие в них значения может получиться полная лажа.

И ещё сдаётся мне что либо книга эта - Г, либо читаете вы её не с начала.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.0366 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.