четверг, 13 ноября 2008 г.

Lod'ы шейдеров в Direct3D10 и отсутствие FFP

Привел от рисовку объектов при Direct3D10 рендере в порядок. Теперь они не исчезают при большом расстоянии от камеры.
В движке есть понятие Lod для шейдеров. С каким-то шагом можно задавать более сложные шейдеры для объектов. Это дает прирост производительность на старом железе(а может и на новом). К примеру возьмём дерево, которое анимируется на ветру вершинным шейдером, в шейдере есть тригонометрическая функция для нее генерируется достаточно много инструкций, очевидно дерево можно не анимировать с очень большого расстояния, в этом случае включится простой шейдер, просто трансформирующий вершину. Другой пример - нет смысла делать эффект бампа и освещения на большом расстоняии - можно ограничится диффузионным освещением или вообще без него. Конечно переключение возможно будет заметно. Аналогичная ситуация с анимацией травы. Можно сделать лоды для скелетной анимации. Но там более сложные параметры.
В случае OpenGL/Direct3D9, если не будет найден подходящий лод, то будет выставлены NULL шейдеры, т.к. для них есть фиксированный конвейер то можно вызвать IDirect3DDevice9::SetTransform(world) и glLoadMatrixf(worldViewMatrix). Для Direct3D10 в этом случае не будет ничего рисоваться. Я решил эту проблему таким образом. Для каждого формата вершин создал список шейдеров по умолчанию. В случае выставления NULL шейдера, будет браться шейдер по умолчанию, если есть вершинный буфер.
Это простое и удобное решение. Не нужно дополнительных шейдеров, тем более шейдера по умолчанию простые и короткие, поэтому их код хранится прямо в реализации класса рендера движка. Для шейдеров с альфа тестом, есть дополнительный список шейдеров по умолчанию для каждого формата, само собой с параметром - текущий AlphaRef, тут имеется ввиду значение, передаваемое в IDirect3DDevice9::SetRenderState(D3DRS_ALPHAREF, AlphaRef) в Direct3D9 и в glAlphaFunc(func, AlphaRef) в OpenGL. В Direct3D10 убран альфа тест из FFP, поэтому нужен такой параметр по которому делается discard.
Таким образом объекты перестали исчезать.

3 комментария:

IronNick комментирует...
Этот комментарий был удален автором.
IronNick комментирует...

Есть предложение. А может лучше сделать лод для материалов, а именно какие текстуры подставлять, какие шейдеры использовать и т.д.
Т.е. чтобы материалы, а не шейдеры, выстраивались в цепочку использования в зависимости от дальности.
И тут уже ложиться работа не на программиста а на "художника" материалов, который более правильно, я думаю, сможет расставить приоритеты.

Andrey комментирует...

Возможно ты прав. Ну все равно придется писать шейдеры. Непонятно как быть с текстурами. У текстур есть mip-уровни. т.е. как бы нет смысла их менять. Вот отключить некоторые текстуры, это можно, к примеру карта нормалей. Данная функциональность у меня есть. Ну что еще можно сделать для лода в материале? К примеру у меня меняется Alpha Ref c расстоянием. По идее вроде все можно в 1 материале сделать.