вторник, 30 декабря 2008 г.

Lights & shadows test

Реализую классы сцены, по принципу, рассказанному в предыдущей серии :) 
    
    Не всё оказалось гладким. Точнее всё оказалось грубым и с зазубринами. Для начала неожиданно для себя узнал что стандартный вектор STL переалоцирует всю память, при резервировании. Далее оказалось что этот самый вектор требует ещё и конструктор копии для сложных агрегатных классов. В итоге – два дня на исправление моего ageDynArray (основанного на STL векторе) плюс нудное подписывание конструкторов копий для всех сложных агрегатных классов (коих у меня оказалось 12 штук).  Раньше я ничего не замечал ибо клал в свой ageDynArray только относительно простые классы, для которых компилятор генерирует конструктор копии автоматически. 

    Напоследок была ещё одна весёлая штука – оказалось если и в базовом классе и в классе наследнике есть перегруженный оператор присваивания, то это отнюдь не означает что при его вызове из класса наследника, он вызовется автоматически и в базовом классе. Раньше я с такой ситуацией не сталкивался, поэтому по простоте душевной был уверен что он, как и конструктор, вызовется автоматически. Надо думаю ещё раз Страуструпа почитать на досуге :)

    В итоге, класс сцены, хоть и со скрипом, но заработал. Добавил в него пока DynObjects, StatObjects и источники света. Для тестирования класса собрал небольшую демку, в которой можно добавлять бочки (DynObjects), которые падают на статический камень (StatObjects). Ну ещё источники света можно добавлять.

Вот:



понедельник, 22 декабря 2008 г.

Иерархия игровых объектов

Работаю над иерархией и общей структурой объектов. Сначала в движке планировал разбить иерархию объектов на два класса – сцена и игровой уровень. Предполагалось, что в сцене мы храним сами пулы простых объектов, а в классе уровня – глобальные ссылки на них и пулы сложных объектов, собирающие несколько ссылок на простые объекты. Кроме того, логически, уровнь будет содержать классы конкретной игры, а сцена – более общие классы.

Вот такая была схема:

class Scene 
{      
 Lights      
 Particles      
 Decals      
 SceneObjects 
}  
class GameObject 
{           
 LightsID           
 ParticlesID           
 DecalsID           
 SceneObjectsID  
}  
class GameLevel 
{           
 ParticlesType      
 DecalsType      
 ActorsType      
 StaticsType      
 DynamicsType        
 LightsID      
 ParticlesID      
 DecalsID       
 Actors:GameObject;      
 Static:GameObject;      
 Dynamic:GameObject;       
}

Однако, при ближайшем рассмотрении всё пошло пи… короче такая схемка не покатит. И вот почему. Во-первых, отсечение по ок-трии в целях оптимизации надо будет делать в  классе уровня, ибо отсечь один GameObject быстрее чем кучу SceneObjects, Particles и других его составляющих. Во-вторых, сомнительная радость размазывать хранение параметров для типов объекта по двум классам (например партиклы, декалы). В третьих же сериализация опять таки достаётся классу уровня.

Вот таким макаром класс Сцены становится всё худее и худее, а его значимость – всё меньше и меньше.

Вообщем волевым решением я всё перенёс в мега-класс GameScene:

class ageGameScene: public ageSingleton 
{    
 ageResourseManager  ActorsType;   
 ageResourseManager  DynObjectsType;   
 ageResourseManager  StatObjectsType;   
 ageResourseManager  StatParticlesType;   
 ageResourseManager  StatDecalsType;     
 ageCDynArray        SceneObjects;    
 ageCDynArray          Cameras;     
 ageCDynArray          Lights;    
 ageCDynArray          Decals;    
 ageCDynArray      Particles;     
 ageCDynArray          Actors;    
 ageCDynArray        DynObjects;    
 ageCDynArray        StatObjects;      

 //world objects   
 ageSimpleArray<int>      ActorsID;    
 ageSimpleArray<int>      DynObjectsID;    
 ageSimpleArray<int>      StatObjectsID;    
 ageSimpleArray<int>      LightsID;    
 ageSimpleArray<int>      ParticlesID;    
 ageSimpleArray<int>      DecalsID;    
 int               CameraID;  
};

Вот такой жирдяй-класс. В нём же практически вся игра будет :-D

----- 
К слову о проектировании. В голове эти все объекты у меня выглядят таким образом :-D 

пятница, 19 декабря 2008 г.

Физика: первые тесты

Чтож пока с рендером я решил завязать. На очереди – иерархия объектов.

class ageRenderObject 
};  

class agePhysicsObject 
};  

class ageSceneObject 
{   
 class ageRenderObject;   
 class agePhysicsObject; 
};

Вот, поднимаясь по иерархии вверх я создал класс ageSceneObject который включает в себя отрисовочный объект ageRenderObject (с которым я работал ранее) а также объект физического движка agePhysicsObject. В нём (ageSceneObject) происходит их синхронизация. Новонаписанный класс agePhysicsObject является просто обёрткой над классом физикса NxActor, и имеет специфический для моего движка функционал. Как например загрузка физической оболочки из файла.

Естественно вручную задавать оболочки это очень плохая идея. Поэтому я потратил пару дней на изучение плагинов и программ для их визуального создания и остановился бесплатном редакторе Scythe (http://www.physicseditor.com/)

Что я могу про него сказать? Хороший, интуитивно понятный редактор и прозрачный формат выходного файла. Конечно для загрузки оболочек можно использовать и их API, однако там очень много лишнего, поэтому я написал свой загрузчик их формата (благо его описание присутствует на их сайте в разделе downloads)

Вот видео того, что получилось: 


И тоже самое но с отладочной информацией: 

среда, 17 декабря 2008 г.

Рендер: да будут тени!

Ну вот, прикрутил я наконец тени. Не обошлось конечно без проблем (http://www.gamedev.ru/code/forum/?id=88870), но спасибо форумчанам геймдева, помогли найти кое-какие опечатки в коде :)

Вообще в деферреде оказался один такой жирный минус – большая нагрузка на пиксельные шейдеры. Вот из-за этого и получилось так, что PCF размытие тени ни в какую не влезает по количеству инструкций в шейдеры версии 2.0, так что пока пришлось для тенюшек компилировать пиксельные шейдеры в версию 3.0. Это конечно совсем не айс, так как я всё таки решил поддерживать и 2.0, поэтому в будущем постараюсь как-нибудь упихать, хоть простенькие PCF2x2, в версию 2.0.

Также сделал поддержку объектов с альфа-дырками (см. на рисунке ветхий край ржавого заборчика) и рендинг от них теней.


воскресенье, 7 декабря 2008 г.

Рендер: освещение закончено... вроде

Освещение закончено. Все типы источников отлажены и работают. Хотя я пока не сделал оптимизации со стенсел-буфером, но думаю это подождёт. Теперь буду прикручивать обратно тени в движок :)

Точечный: 


Направленный: 


Конический: 

понедельник, 24 ноября 2008 г.

Принцип модульной конструкции роботов

Все роботы в игре будут состоять из следующих частей: 

  • Корпус 
  • Двигательный модуль 
  • Шасси 
  • Навесное оборудование

Некоторых частей естественно может и не быть или наоборот прицеплено несколько. Всё это будет зависеть от их типа и класса робота.

Художник Grizo (aka Snake) сделал рисунок, объясняющий принцип сборки роботов из составных частей.

Рендер: deferred освещение

Начал делать освещение на деферред. Сделал пока освещение от направленных и точечных источников. Освещение естественно полностью bump-specular. При написании шейдера ГБуфера появилась идея использовать дополнительные карты нормалей для повреждённых деталей и увеличение контрасности бампа (normalFromMap.z/=damage_factor;) соразмерно величине этих повреждений. Вообщем идея интересная и вроде не особо сложная в реализации... покрайней мере пока так кажется :)

Ещё хочу сказать спасибо тов. Zeux за лекцию R.E.N.D.E.R. (http://www.gamedev.ru/community/gamedev_lecture/articles/r_e_n_de_r) о том, как реализован деферред рендер в Сталкере. Много интересной и полезной информации которой я сразу и воспользовался :)

Привожу скрины с текущего билда движка. В сцене действует один направленый источник (белый) и один точечный (красный). 




понедельник, 17 ноября 2008 г.

Рендер: Deferred shading

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

  1. В игре будет унифицированная модель освещения (Фонг) 
  2. В кадре будет приличное кол-во DIP-ов 
  3. Много точечных (и не очень) источников света 
  4. В кадре отсутствуют полупрозрачные объекты aka стёкла 
  5. Будут пост-эффекты типа SSAO которым всё равно нужны нормали )

Ну и так, без пункта ещё добавлю, что мороки с дефередом гораздо меньше чем с форвардом: не надо делать списки освещаемых этой лампочкой объектов, нет кучи разных шейдеров... 
И лампочки новые добавлять - одно удовольствие :)

четверг, 30 октября 2008 г.

Движок: загрузка объектов

Работаю над загрузчиком объектов. Переписал кое-какие части и сделал многое по нормальному. Дополнил формат объектов (использую для всех данных XML формат). 
Вот плоды моих экспериментов (всё-таки мои тени смотрятся очень даже ничего):


понедельник, 20 октября 2008 г.

Набросок кусочка уровня

Вот решил набросать в Максе кусочек уровня, чтобы посмотреть как ранее созданные модели вместе будут смотрется. Вцелом я доволен результатом, более менее в одном стиле, но всё же кое-что придётся наверно перекрашивать или играться с гаммой\яркостью\контрастом. Ну это уже ближе к созданию уровней будет.


Модели: ветхий забор, платформы, опора

дряхлый поломаный заборчик для уровня "свалка":


платформы для уровня "завод":


опора металлических ферм для уровня "завод":



воскресенье, 5 октября 2008 г.

Рендер: освещение (переделан пайплайн)

А вот не всё так радостно оказалось, как планировалось :) 
Т.к. нам при наложении теней (и освещения собсна тоже) от нескольких источников надо различать какая тень от какого источника рендится. Ибо сложение освещения идёт по формуле:

Light1*Shadow1+Light2*Shadow2+...+LightN*ShadowN

А по технике складывания в один буфер получается что

Light1*(Shadow1*Shadow2*...*ShadowN) + Light2*(Shadow1*Shadow2*...*ShadowN) +... + LightN*(Shadow1*Shadow2*...*ShadowN)

Короче нифига неправильно затенялось :(  (http://www.gamedev.ru/code/forum/?id=85226)

Вообщем переколдовал я рендер и решил проблему через MRT. При освещении в RT1 рендится бамп и освещение, в RT2 – только тени с освещением. Потом RT2 фильтруется и накладывается на RT1. Таким образом получаем чёткий бамп с наложенным на него освещением и подразмытыми тенями. Проверка на растекание тени через края объектов также присутствует. Реализованы все виды освещения Directional, Omni, Spot.

Теперь займусь наверно общей архитектурой игры – иерархия объектов, отсечения и всё такое.


понедельник, 15 сентября 2008 г.

Модели: тех-блок, бочка

Технический блок, напичканой разной фигнёй - кнопками, проводами, переключателями...




Просто бочка



понедельник, 8 сентября 2008 г.

Модели: Насосная станция

Первые наброски зданий. Насосная станция. Текстуры пока WIP, не везде довёл до ума.

пятница, 5 сентября 2008 г.

Первый свет. Пайплайн рендера

Освещение

Освещение – очень важная деталь в современном рендинге. Думаю гдето 30% визуальной привлекательности картинки – хороший свет и тени. Оно придаёт объём и делает картинку более выразительной.

В проекте будем использовать попиксельное освещение, для теней – шадоумапы, простейший бамп, спекуляр, возможно SSAO.

В игре будут следующие типы источников:

Глобальное освещение. Глобальное освещение представлено виде одного направленного источника плюс небольшой амбиент. Резмер теневой карты – 1280x1280 пикселей. Возможно будет также реализовано SSAO.

Подсветка участков уровня. Предположительно только конусные источники (Фонари, прожекторы). Освещают существенную часть уровня (до 2/3 игрового экрана) Размер теневых карт (в зависимости от размера источника) – 512, 256, 128. Также сюда входят споты и с анимированным прожектором – это крутящиеся винты вентиляции и т.п.

Мелкие и совсем мелкие источники. Предположительно только точечные источники. Это всплохи света при стрельбе персонажей, маленькие лампочки, горящие детали и т.д. Для них не предполагается использовать тени. Однако если удастся удачно сделать тени для точечного источника с помощью всего двух рендер-таргетов (трапезоид) то возможно и их оборудуем тенями. Покрайней мере для всплохов освещения при стрельбе.

 

Пайплайн рендера

Пайплайн рендера на данный момент таков:

  1. Z-проход. Заполняем Z-буфер. Получаем Z-текстуру. Если используется SSAO – рендерим буферы нормалей и позиции.
  2. Рендер теней в буфер теней. Для каждого источника рендим Z-текстуру и после переключаем камеру и рендим наши тени для этого источника в буфер теней. Повторяем операцию для всех лампочек, имеющих тени. На этом этапе НЕ ИСПОЛЬЗУЕМ вообще никакого сглаживания. Даже ПЦФ.
  3. Размываем двумя проходами гаусс-фильтра наш буфер теней. Подтёки теней устраняем при помощи Z-Текстуры (которую получили в пункте 1).
  4. Далее рендим освещение от каждой из лампочек в буфер цвета. Используем простой бамп (это всё пока без диффузной составляющей)
  5. Вот теперь рендим диффузную составляющую.
  6. Ну и наконец COMBINE! Всё собираем и выводим на экран.

Пока реализованы в движке тени для направленного источника, без размытия теневого буфера. Вот что имеем на данный момент:

 

четверг, 28 августа 2008 г.

Частицы, PhysX, Модели

Движок. Частицы

Как я уже говорил, я переписываю свой старый движок на новый лад. Стараясь исправлять все прошлые косяки в архитектуре. Вот сейчас дошёл до системы частиц. То что было в старом движке было довольно косячное, не было многих нужных параметров (масса, гравитация, ветер). Поэтому я решил полностью переделать этот модуль… на основе примера с codeproject. (Мы против велосипедов) Процесс портирования занял около 4 часов, больше связанный с изменением семантики и перешиванием рендера (в примере были поинт спрайты, а я юзаю квады. Кроме того было сделано разделение на ParticleEmitter и ParticleSystem). Логика движения частиц осталась нетронутой. Пока так сгодится. В итоге первый костёрчик в проекте заработал к вечеру :)




PhysX

Вчера изучал утилиту PhysXViewer. Довольно полезная штука, обтягивает геометрию физическими примитивами и\или строит упрощенную физ. модель. Думаю её стоит заюзать в проекте. Однако не понравился интерфейс, и, что более важно, то что она на выходе генерит. А генерит она XML набитый до отказа всякими установками сцены, флажки и т.д. Короче среди этого безобразия лежат нужные данные по созданным примитивам. Поэтому возможно придётся написать утилитку-чистильщик, которая удалит всю не нужную белиберду

Модели

Апдейт. Мелочёвка для уровня.

Электронагнетатель. Наверху эмиттер который будет искрится системой частиц


Просто железные блоки для локации "свалка"


Башня. Предположительно наверху будет вращающаяся турель

вторник, 26 августа 2008 г.

Наброски в Максе



и сразу публикую наброски, чтоб понятно было про что вообще речь идёт:




А в игре будут они в таком масштабе:




Вот примерно такой аляповатый арт планируется в игре. Если я конечно моделить лучше не научусь... что сильно врятли

Начало проекта

Вот и пришло время нового проекта. Отдохнув от очередного провала(http://www.gamedev.ru/projects/forum/?id=73077) и полностью разочаровавшись в командах энтузиастов, я с чистой совестью решил делать что-то новое. Поразмыслив немного пришёл к выводу что проект принесёт больше пользы, если я буду описывать его разработку в блоге (всегда хотел попробовать вести блог), ну а так как мой хостинг только HTML держит, то...

Итак. Поинты проекта на данный момент такие:

  • Игра про роботов (Не, ну а чё? :)
  • Фишка игры в том, что роботов можно собирать из отдельных частей
  • Механика как в старичке Scary Nightmare (вид сверху, управление аля алиен шутер). Возможно будет введены некоторые РПГ элементы
  • Сюжет ну о-о-очень секретный :)


Техническая сторона вопроса:

  • Третья ипостась моего недодвижка
  • DirectX9\C++\Шейдеры 2.0
  • Мидлваре – PhysX,pugiXML,Lua,OggVorbis
  • Предположительно пока всё делаю сам. Арт\Звуки\код


Почему такой выбор:

  • Анимировать не умею, поэтому роботы не человекоподобные
  • Вид сверху – проще движок, нет лода, оклюжена и прочего геморроя
  • Геймплей знаком. Многое прорабатывалось мной в Scary Nightmare
  • Техногенный арт проще делать, чем для скажем средневековья. И не надо соблюдать реальные пропорции\вид\цвет и т.д.


Вот с этим на борту и выступаем. Проект делается “Фор Фан”(TM) и в свободное от работы время. Поэтому частых обновлений не ждите.