Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Подсказки / Порядок хранения элементов матриц для вершинных шейдеров

Порядок хранения элементов матриц для вершинных шейдеров

Автор:

У многих начинающих разработчиков бывают ошибки при рендеринге, когда либо на экране ничего нет, либо всё выглядит совсем неверно. Это может быть связано с тем, что матрицы трансформации в шейдер попадают с неверным порядком хранения столбцов и строк в памяти.

К примеру, если в проекте используются матрицы из D3DX библиотеки, то для использования в ID3DXEffect/ID3D10Effect/ID3D11Effect достаточно написать такой порядок умножения в шейдере:

float4 pos = mul(in.position, worldViewProj); 

где D3DXMATRIX worldViewProj  = world * view * projection;

Аналогично, такой подход будет работать для Cg.

В случае использования IDirect3DVertexShader9/ID3D10VertexShader/ID3D11VertexShader, нужно транспонировать матрицы перед отправкой в шейдер, либо поменять порядок умножения в коде:
D3DXMATRIX worldViewProj = projection * view * world;
или в шейдере:

float4 pos = mul(worldViewProj, in.position); 

Либо использовать в функциях D3DXCompileShader* (Direct3D9) флаг компиляции D3DXSHADER_PACKMATRIX_ROWMAJOR,
для функций D3DX10CompileFrom*/D3DX11CompileFrom* (Direct3D10/Direct3D11) флаг компияции D3DCOMPILE_PACK_MATRIX_ROW_MAJOR.

Следует учесть, что порядок умножения влияет на набор инструкций в шейдере и производительность. В результате будет либо 4 инструкции dp4 идущее подряд, либо mad/mul
В первом случае перемножение будет выполняться быстрее.

При написании своих классов для работы с матрицами следует учесть эти особенности.

25 июня 2012

#графика


Обновление: 6 августа 2012

2001—2017 © GameDev.ru — Разработка игр