1 / 38

Разработка системы шейдерных материалов

Разработка системы шейдерных материалов. Андрей Аксенов shodan NOSPAM @ NOSPAM shodan.ru КРИ ’2005. Обозначения. шейдер конкретная GPU микропрограмма , загружаемая в память GPU константа передающаяся в шейдер параметр любое свойство материала ( в основном доступное дизайнеру).

benard
Download Presentation

Разработка системы шейдерных материалов

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Разработка системы шейдерных материалов Андрей Аксенов shodanNOSPAM@NOSPAMshodan.ru КРИ’2005

  2. Обозначения • шейдер • конкретная GPU микропрограмма, загружаемая в память GPU • константа • передающаяся в шейдер • параметр • любоесвойство материала (в основном доступное дизайнеру)

  3. Обозначения (2) • текстура • один из видов параметра • прешейдер • формула вычисления константыиз параметровматериала и сцены • пин • переменная времени компиляции, влияющая на выбор конкретного шейдера

  4. Обозначения (3) • привязка (биндинг) • процесс назнчения текстур в текстурные стейджи, заливки шейдерных констант, итп • материал • набор шейдеров и параметров (общая статическая таблица для всех объектов класса и агрегированные значения параметров в объектах)

  5. 2002-й год… Это была тестовая карта!

  6. Начальный проект шейдинга • проходы • shadow map • diffuse / specular (основной) • EM / EMBM (опционально) • пины (разбиения шейдеров) • static / skinned ( 1/2/3/4 кости ) • NV / ATI ( наличие SM hack ) • EM / EMBM

  7. Эволюцияшейдинга • дополнительные пины • тип тумана ( range / height ) • коррекция блендинга для тумана • итд итп • небольшой комбинаторный взрыв • ~150 шейдеров • 3..5 факторов для выбора шейдера • 8 разных мест для ручной регистрации каждого шейдера

  8. Эволюцияшейдинга (2) • единый общий класс материала • 5 текстур • ~15 параметров • сложности управления • неочевидные факторы и сложная функцияпривязки материала (пример: (pBump!=NULL) ) • трудоемкость дальнейшего разбиения шейдеров

  9. Расширение единого класса? • означает добавление параметров • как минимум 8семантик текстур • как минимум 20-30 параметров • одновременно не используются • означает еще большую сложность • функция привязки более 1000 строк • еще больше заполняемых вручную таблиц выбора шейдеров…

  10. Нужна система материалов! • система материалов? • некоторый общий (для нескольких проектов) код, которыймаксимально автоматизирует создание новых видов шейдерных материалов и их внедрение в проекты

  11. Требования к системе • простота создания новых материалов • как минимум, регистрация нового материала не более, чем в 1-2 местах • как максимум, загрузка на лету • простота создания новых пинов • иначе добавлять к существующим материалам функциональность слишком трудоемко

  12. Требования к системе (2) • простота создания новых shading path и проходов внутри shading path • shading path отличается от пина тем, что влияет на число проходов и привязку каждого прохода • простота создания прешейдеров • в хардкоде “прешейдер” задавался в функции привязки, отдельно от материала - неудобно

  13. Требования к системе (3) • менеджмент упакованных и композитных текстур • для облегчения работы дизайнеров и минимизации человеческих ошибок • автоматическая упаковка в DXT • автоматическое смешивание каналов исходных текстур (не используемых напрямую) в одну, используемую шейдером ( bump.rgb + gloss.a )

  14. Почему не D3DXEffect? • проблема черного ящика • а точнее, имеющегося качества и скоростиподдержки… • проблемы кодогенерации FXC • недостаточно хорошая оптимизация • недостаточно гибкая привязка констант • полное отсутствие контроля за прешейдерами

  15. Почему не D3DXEffect? (2) • проблема сортировки по текстурам и шейдерам • как сделать эффективно? • проблема сопряжения со специфичными типами данных • контроллеры анимации • композитные текстуры • решаемо посредством оберток, но нет гарантий эффективности

  16. Архитектура системы • class FXMaterial_c • базовый абстрактный интерфейс • реализация общей функциональности • конкретные реализацииматериалов • class FXMaterial_Diffuse_c : public FXMaterial_c • агрегирует конкретные параметры • реализует функции привязки

  17. Архитектура системы (2) • препроцессор спецификаций FXPP (FX Preprocessor) • генерирует весь C++ код реализации материала ( FXMaterial_Diffuse_c ) • в том числе, заранее компилирует все возможные уникальные HW шейдера, необходимые данному виду материала • использует спецификацию материала

  18. Блок спецификации material { // пины compilevar USE_BONES; compilevar USE_SHADOW; compilevar USE_SHADOW4SAMPLE; compilevar USE_FOG_TYPE; compilevar USE_OMNIGROUPS; // параметры материала texmap texDiffuse { uiname="Diffuse map"; } uivar color3 cLuminosity; uivar color3 cDiffuse; uivar float fShadowTransp; uivar texgen2 tgDiffuse; // ...

  19. Блок спецификации (2) path default { pass 0 { stage 0 = scene.ShadowMap; stage 3 = texDiffuse; float4 vs.g_cAmbiLumi = mat.cLuminosity + mat.cDiffuse*scene.cSunAmbient; float4 vs.g_cTotalDiffuse = mat.cDiffuse*scene.cSunDiffuse; float4 vs.g_cMatDiffuse = mat.cDiffuse; float4 vs.g_tgDiffuse0 = mat.tgDiffuse.GetXform(0); float4 vs.g_tgDiffuse1 = mat.tgDiffuse.GetXform(1); float4 ps.g_cShadowTransp = { 0, 0, 1-scene.fShadowTransp*mat.fShadowTransp/2.0f, scene.fShadowTransp*mat.fShadowTransp/2.0f }; float4 ps.g_cAlpha = { 0, 0, 0, frag.iAlpha/255.0f }; } }

  20. Задание шейдеров • по имени (жесткая схема именования) • либо ассемблер, либо HLSL • общий код через # include • возможность копирования реализации // HLSL LitVertex_t vs_default_pass0 ( SkinVertex_t IN ) { ... } // asm VertexShader vs_default_pass0 = asm { ... } // implementation copy VertexShader vs_r9700_pass0 = vs_default_pass0;

  21. Препроцессинг FX • разбор спецификации • компиляция всех возможных шейдеров • варьируем значения пинов • привязываем константы: • uniform float4 g_cDiffuse : register ( c13 ); • #define VS_g_cDiffuse c13 • отсев дублирующихся шейдеров • генерирование C++ кода материалов • генерирование общего C++ кода

  22. C++ код материала • бинарные данные шейдеров • таблица шейдеров, ее инициализация • дескриптор параметров • функция привязки шейдеров • выборка по таблице в зависимости от shading path, номера прохода и значений пинов • функции привязки констант • в зависимости от shading path, прохода, пинов • разделение на per-material / per-instance

  23. Общий C++ код • списки (enum) ID материалов • константы ( FX_PINS_TOTAL итп ) • функция создания материала по ID • декларации классов • инициализация • запросы к дескрипторам материалов по ID • union FXInstanceFlags_u содержащийпины в виде битовых полей

  24. Функциональность FXMaterial_c • общие параметры ( альфареф, флаги,… ) • бинарный и текстовый сериализаторы • управление текстурами, в том числе упакованными и композитными • управление значениями параметров • привязка рендерстейтов • поддерживающие функции ( GetFlags, operator =, ит.п. )

  25. Дескриптор параметров для каждого параметра заданы: • тип ( eg. COLOR ) • UI имя ( eg. “Diffuse color” ) • техническое имя ( eg. “cDiffuse” ) • смещение в базовом классе • флаг доступности дизайнеру через UI • диапазон возможных значений ( для UI )

  26. Как решены проблемы D3DX? • проблемы поддержки нету • проблемы оптимизации – обходим, используя ассемблерные шейдеры • проблемы привязки – решаем, привязывая константы из FXPP • проблему прешейдеров – решаем, генерируя C++ код привязки констант • который в итоге компилируется в инлайновые SSE инструкции

  27. Как решены проблемы D3DX?(2) • cортировка – по следующему 64-битному ключу: struct { DWORD m_uMesh : LOG2<MAX_MESHES>::Value; DWORD m_uPins : FX_PINS_TOTAL; DWORD m_uMaterial : LOG2<FXMAT_TOTAL>::Value; DWORD m_uTexture : LOG2<MAX_TEXTURES>::Value; }; __int64 m_uValue; • порядок полей определяет приоритеты сортировки

  28. Специальные типы параметров на примере композитных текстур: • введен подтип у типа параметра FXPARAM_TEXTURE • введено два новых ключевых слова compositemap, submap в спецификацию • доработана функция SetMap • написаны функции обновления и сохранения Итого: 1-2 рабочих дняна сложный (!) тип.

  29. Известные проблемы • отсутствие (пока) разных типов инстанса • для разных моделей нужная разная per-instance информация • примеры – fading, instancing • отсутствие (пока) удобных деклараций для сложных массивов констант • примеры – skinning, упаковка групп источников света • дублирование кода между некоторыми видами материалов ( Diffuse, DiffuseEnv )

  30. Итоги • добавление новых (фактически, Иных) материалов –сводится к созданию FX-файла в директории с материалами • конечно, неплохо бы еще и в dependencies прописать… • добавление новых пинов – сводится к добавлению одной строчки в FXPP • например, добавление нового типа тумана или портирование всех шейдеров на ps_1_4

  31. Итоги (2) • разработка окупается • на разработку ушло МНОГО времени • на добавление в хардкод и отладку одних только автоматически добавленных в новой системы разбиений по пинам –ушло бы времясравнимого порядка • стоит ли писать свою систему? • вопрос неоднозначный! • если не устраивает хардкод (много шейдеров) • если не устраивает D3DX

  32. Занимательная нумерология • 45-50 дней по трекеру, планировалось 15 • 11 видов материалов, 89 килобайт FX • всего компилируется 2842 варианта HW шейдеров, из них 532 уникальны • компиляция длится 75 секунд • генерируется 75809 строк C++,3298 KB • за вычетом собственнобинарных шейдеров, остается 5239 строк, или 328 KB • FXPP это 2268 строккода, или 61 KB, и самое страшное…

  33. Занимательная нумерология (2) • FXPP написан на Perl. # store original line numbers $l = 0; $fx =~ s/^/++$l.":"/gems; # remove /*...*/ comments $fx =~ s/\/\*.*?\*\///gms; # remove // comments $fx =~ s/^((([^\/"\n])|("[^"]*"))*)\/\/.*$/\1/gm; # ... # build material types list $i = 0; print OUT "enum FXMaterial_e\n{\n", join ( ",\n", map { uc "\tFXMAT_$_ = " . $i++ } @g_fx_names ), ",\n\tFXMAT_TOTAL\n};\n\n";

  34. MIR

  35. FIN

More Related