| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Программирование игр, графики и искусственного интеллекта > Ответы на вопросы по шейдерам |
| Автор: mr.DUDA 7.12.2005, 19:26 | ||
Скажите, какие именно скриншоты нужны - диаграммы, схемы, графики или скрины из RenderMonkey ? |
| Автор: Sardar 7.12.2005, 20:42 |
| Скрины, т.к. RenderMonkey ставить не хочеться, всё равно в плотную не занимаюсь, но интересно как это выглядит на практике. Интересен эффект "горячего воздуха", когда картинка "плывёт"/искривляеться. Статья ясная, читаеться легко. Есть моменты не до конца понятные, например, обьявляя входную структуру для вертексного шейдера обьявляем требуемую инфу, а какие вообще параметры возможны (обобщённые по функционалу)? Также вертексный шейдер как я понял получает на вход одну вершину за один "выполняемый цикл", вершины на шейдер идут потоком в не известном порядке, механизмов запомнить выполнение прошлого цикла (глобальные переменные и т.д.) нет, тогда как узнать с какой вершиной сейчас работаем? Иначе просто мало чего можно сделать с ней... а может я думаю "не в том направлении". Вообщем одной статьи явно не достаточно |
| Автор: mr.DUDA 7.12.2005, 22:09 | ||||||||
Возможны параметры следующих типов (каждый определяется своей семантикой): POSITION - координаты вершины NORMAL - нормаль к вершине TEXCOORD - текстурные координаты TANGENT и BINORMAL - используются для bump mapping, определяют тангенциальное пространство COLOR - цвет вершины, на самом деле может содержать любые пользовательские данные FOG - коэффициент затуманивания, может также рассматриваться как цвет и интенсивность тумана DEPTH - значение z-буфера для вершины BLENDWEIGHT, BLENDINDICES - слабо представляю себе их назначение, что-то вроде сглаженных координат вершины, или похоже на это SAMPLE, PSIZE, TESSFACTOR, POSITIONT - мне неизвестны Кроме этих параметров, определённых для каждой вершины, можно определить параметры для шейдерной программы в целом. Количество и формат этих параметров определяются возможностями видеокарты.
На самом деле, шейдерной программе должно быть "пофигу", что это за вершина, т.к. по идее ты не знаешь заранее, сколько всего вершин и в каком порядке вершины располагаются в модели. Ведь модель делается заранее в 3D-studio, и всем заправляет моделлер, а ему всё равно, кто и как будет эту модель использовать, не так ли ? С другой стороны, если модель формируется программно, то ничего не мешает добавить в описание вершин свои собственные (пользовательские) данные, например в VertexColor, которые попадут в шейдер через COLOR-переменную. Помимо всего прочего, обычно допускается не один а несколько наборов данных одной семантики, т.е. ты можешь передать шейдеру 3-4 дополнительных вектора, что эквивалентно 12-16 float-значениям. Согласись, этого более чем достаточно. Тем более, что твоё 3D-приложение самостоятельно определяет формат вершин и заполняет их данными, т.е. у тебя есть возможность передать шейдеру всё что угодно в каком угодно количестве.
Согласен, это всего лишь вершина айсберга. Но ведь надо с чего-то начать, правда ? Я изложил всё, о чём мне известно на текущий момент, в чём я, имхо, разобрался. Недостающие главы требуют только времени на написание, проблем не будет. Единственно, придётся попросить кого-нибудь сведущего в OpenGL и D3D сделать примеры с описанием, как прикручивать шейдер к реальной программе, т.к. пока что я работаю с движком OGRE, который абстрагируется от реализации 3D, т.е. выстраивает фасад над OpenGL и Direct3D.
На практике всё выглядит, как в реальной игре. Различий нет. Например, эффект "горячего воздуха" выглядит точно так же как в GTA:San Andreas, точно говорю. Шейдеры ведь везде одинаковые, просто тот кто их использует первым, может гнуть пальцы, а остальные типа за ним "повторяют"... Увидеть работу шейдера по скриншоту - это то же самое что снять скрин с GTA, где над асфальтом горячий воздух, и искать в полученном скрине "шейдер". Нереально. К сожалению, GIF я сделать пока не могу, а видео займёт слишком много места, уж проще скачать RenderMonkey и посмотреть там |
| Автор: mr.DUDA 7.12.2005, 23:24 |
| P.S. добавил скриншоты в статью. |
| Автор: Sardar 8.12.2005, 00:29 | ||
Так для ясности, как рисуем кадр с одним проходом:
P.S. хорошо бы обсуждение вынести в отдельный топ. |
| Автор: mr.DUDA 8.12.2005, 08:44 | ||||||||||||||||
Ну, всё не так уж и плохо Вертексный считает для трёх точек полигона позицию и что-то ещё. Это "что-то ещё" интерполируется достаточно быстрым алгоритмом, а позиция после вертексного шейдера уже показывает, куда на экране ляжет точка. То есть, по сути вертексный проецирует полигон на экран и показывает, чем этот полигон надо "заливать". Пиксельный заливает. Точек получается ровно столько, сколько их внутри треугольника на экране, не так уж и много, правда ?
Скорее, для модели или группы моделей. Полазив в samples для DX SDK, нашёл пример:
Внешние данные передаются через отдельные переменные, без семантики. Пример параметра для ps_main: uniform float diffuseLight
Всё правильно.
Да, всё так и есть, если я врубаюсь. Отсечение делает не шейдер, хотя он может повлиять на z-буфер. Точнее пока не скажу, т.к. самому надо разобраться Захлебнуться шейдеры не могут, по причине описанной в начале поста. Добавлено @ 08:50 Вот, что написано в документации D3D по рендерингу с шейдерами:
И пример кода (C#):
|
| Автор: Змий 8.12.2005, 16:02 |
| Я так понял, векторные шейдеры базируются на информации с векторов объектов, а пиксельные шейдеры прямо воздействуют на картинку? Так ли работает шейдер эффекта "горячего воздуха": сдвигает пиксели изображения в хаотичном порядке или это тоже distortion текстура? Я хотел спросить - в игре Knights of The Old Republic эффект от "толчков силы" сделан шейдером? А сам шейдер, если им было это сделано воздействует на куб изображения тем же distortion? |
| Автор: mr.DUDA 8.12.2005, 16:25 | ||||||
Неточная формулировка. Не с векторов, а с вершин полигонов объекта. Вершина (вертекс) содержит набор информации: там, к примеру, может быть или не быть текстурная координата, нормаль к вершине, цвет вершины и др. Пиксельные шейдеры как бы "заливают" треугольник, лежащий в экранной плоскости, пикселами.
Этот шейдер берёт пиксел из специальной текстуры, содержащей монохромный шум. Затем по цвету этого пиксела определяется сдвиг для текстурных координат, по которым выбирается пиксел из обычной текстуры. В качестве "обычной текстуры" в том шейдере используется всё, что было отрисовано на первом проходе рендеринга, т.е. "нормальное" содержимое кадра рассматривается в свою очередь как текстура, которую мы будем искажать на втором проходе рендеринга.
Что за куб имеется ввиду ? |
| Автор: Змий 8.12.2005, 20:22 | ||||||
Спасибо
Возможно ли редактировать эту текстуру, например для другогго типа искажений?
Энтити, символизирующее экран и подвергающееся наложению distortion текстуры, как вы сказали, когда описывали шэйдер haze. |
| Автор: mr.DUDA 9.12.2005, 09:31 | ||||||
Можно в принципе сделать 3D-текстуру, в разных слоях которой будут маски для пиксельного шейдера. В зависимости от времени выбирать слой и использовать его как маску.
Конечно! Берём DirectX Texture Tool, открываем нашу 3D-текстуру с шумом, сохраняем под другим именем, и добавляем в неё свои собственные слои, нарисованные в фотошопе
Вообще-то, не куб, а плоскость из двух полигонов, сложенных вместе - т.е. прямоугольник. Модель называется screenAlignedQuad. Quad - потому что квадрат, screenAligned - потому что координаты модели подобраны так, чтобы углы квадрата совпадали с углами экрана. |
| Автор: Змий 9.12.2005, 22:45 | ||
Вот ещё вопрос. Если например есть анимированная текстура *.gif или кадры *.jpg их можно натянуть на screenAlignedQuad чтобы она прощёлкивалась с возвратом на первый кадр после последнего до какого то момента?
А можно как нибудь обойтись без Dx Texture Tool? Мне не закачать SDK - слишком много для моего старого модема |
| Автор: mr.DUDA 10.12.2005, 00:38 | ||
Вроде бы, для таких случаев используют динамически обновляемую текстуру, а не шейдер. З.Ы. в приаттаченном архиве - Texture Tool для 9го DX SDK. Насчёт "не могу выложить" я имел ввиду что не могу выложить SDK |
| Автор: Змий 10.12.2005, 13:20 |
| Спасибо, но когда пытаюсь открыть файл, мне пишет, что не может найти d3dref.dll А также про глубину цвета. |
| Автор: mr.DUDA 10.12.2005, 21:08 |
| Нужен установленный DirectX 9.0c, без него не запустится. |
| Автор: Змий 10.12.2005, 23:26 |
| У меня сейчас стоит DirectX 9.0c. По крайней мере, он так пишет в dxdiag. Но всё равно, ошибка выскакивает. |
| Автор: mr.DUDA 11.12.2005, 14:57 |
| Может, ему именно такой DX нужен, какой установлен у меня... Или SDK надо всё-таки поставить... |
| Автор: empter 11.12.2005, 23:53 | ||
У меня SDK стоит и точно такая же проблема, то есть dll он находит а на цветовой режим все равно ругается Змий Можно использовать плагин к Фотошопу Посмотри в поисковике NVidia DDS Plugin to Photoshop |
| Автор: Змий 12.12.2005, 17:41 |
| empter спасибо, попробую. mr.DUDA, не могли бы вы сказать, по каким принципам строятся distortion текстуры? Это примерно как с бамп картами или тут необходима какая то другая техника? |
| Автор: mr.DUDA 14.12.2005, 09:10 | ||
Всё зависит от того, как планируешь их использовать. У меня всё руки не дойдут дописать статью, там всё будет Если искажающая текстура - статичная (пример: неровное стекло), достаточно 2D-текстуры, если динамичная - нужно делать многослойную aka 3D-текстуру. Многослойная отличается тем, что в ней имеется 2^N двумерных текстур одного размера, каждой присвоен номер. Обычное количество - от 2 до 16. В шейдер такая текстура попадает через обыкновенный сэмплер. Выборка пиксела происходит так: передаём в tex3D трёхмерный вектор, в котором x и y - обычные координаты в 2D, z - идентифицирует слой. Координата z изменяется от 0 до 1; если z "не попадает" точно в один из слоёв, то берутся 2 слоя "до" и "после" z, и смешиваются в зависимости от "расстояния" до воображаемого слоя z. Искажение на основе такой текстуры производится следующим образом: пиксельный шейдер получает реальные текстурные координаты, и вместо того чтобы взять по ним пиксел из "обычной" текстуры, берёт пиксел из искажающей текстуры. Полученный пиксел рассматривается как смещение от реальных текстурных координат. Есть несколько способов закодировать смещение в искажающей текстуре, самый простой и очевидный - брать r и g компоненту искажающей текстуры как смещение. Получив смещение, шейдер прибавляет его к реальным текстурным координатам и выбирает точку из "обычной" текстуры. Вроде бы всё понятно. Теперь по технике собственно создания искажающей текстуры. Самый простой способ - создать монохромную текстуру, в которой яркость пиксела определяет смещение (искажение). Например, если сделать концентрические окружности, залитые плавным градиентом от центра к краям, то получим простой статичный эффект волны. Если теперь сделать несколько слоёв, в каждом последующем смещая все окружности от центра к краям текстуры, и "слепить" 3D-текстуру из таких слоёв, получим анимированный эффект волны. Шейдер может использовать переменную "время" как переключатель между слоями (время должно изменяться плавно от 0 до 1 и далее). Если наложить такой эффект на весь экран в определённой точке, получится что-то подобное "Матрице". |
| Автор: Sardar 14.12.2005, 20:35 | ||
Какого размера должна быть такая текстура для всего экрана? Просто представляю что это 1024х768 байт (монохромная 0-255) искажающая текстура с 9 слоями это 6Мб, среднее видео 128Мб, уже забито сценой... Что то меня на экономию пробило, сейчас работаю над проектом, где памайти всег в 512кб, а задача строить динамические вебстраницы на многопоточном http сервере, да ещё в своём скриптовом языке |
| Автор: mr.DUDA 15.12.2005, 12:47 | ||||
Дело в том, что "текстура для всего экрана" и так создаётся автоматически для любого 3D-приложения - в неё всё рендерится, затем её содержимое выводится в буфер экрана. Для 1024x768x32bit получается 3Мб. Искажающая текстура не обязана быть с таким же разрешением, т.к. сэмплеру всё равно с какой текстурой он работает - текстурные координаты всегда от 0 до 1, пофигу какая текстура, хоть 1х1.
|
| Автор: Змий 31.12.2005, 15:28 |
| Спасибо. А анимированной эту текстуру сделать можно? Чтобы волны ещё и расходились. PS С новым годом! |
| Автор: mr.DUDA 31.12.2005, 17:03 | ||||||
Можно, см. моё сообщение выше:
Спасибо, тебя также! Успехов, здоровья и счастья в новом году! |
| Автор: Змий 31.12.2005, 20:35 |
| Извиняюсь, не прочитал Слои строятся по принципу каналов или необходима Dxtexture или плюгин dds? |
| Автор: mr.DUDA 31.12.2005, 22:45 | ||
Насколько мне известно, dds и только dds. Принцип такой: в одном файле хранится несколько битмапов одного размера, пронумерованных от нуля до 2^N, т.е. количество битмапов равно целой степени двойки. Ну а в шейдере вводится понятие "слой", подразумевающее работу уже не с набором отдельных битмапов, а как бы с непрерывным "слоёным пирогом", в котором номер слоя - произвольное число от 0 до 1 включительно. Выбирая, к примеру, слой 0.125 из 3D-текстуры с четырьмя битмапами, мы получим "срез" ровно посередине между нулевым и первым битмапом - плавный, интерполированный переходной слой. |
| Автор: Ch0bits 14.1.2006, 13:40 |
| Вот интересная, наглядно показывающая возможности шейдеров статейка http://www.thg.ru/graphic/20060114/index.html |
| Автор: Lеstat 30.12.2006, 11:35 |
| вот у меня еще вопрос есть! Хочу сделать освещение из фонарика... Я думаю в шейдер нужно передать координаты фонаря и точку в которую он светит. Ну или вектор куда он светит, так что возник вопрос как грамотно передать в шейдер информацию о положении фонаря? потом я еще передаю угол на который светит фонарь (по аналогии с камерами - FOV)... Дальше я думаю нужно спроектировать на поверхность на которую падает свет круг такой от фонаря и там где у нас поверхность попадает в проекцию сделать цвет белым, там где нет ничего не менять. Никак не могу врубиться в математику... не могу получить проекцию я так понимаю получать проекцию нужно в вершинном шейдере, а раскрашивать это уже в пиксельном. PS: огромное спасибо за статью!! очень помогла врубиться в основы написания шейдеров! |