Использование хардварной тесселяции карт АТИ в DX9

Jul 15, 2008 11:44

Возможно вы слышали, что в ДХ10 видеокартах АТИ, начиная с серии 2*** имеется хардварный тесселятор геометрии. Кто-то, возможно, видел его работу в GPU Mesh Mapper или Render Monkey 1.81. Но до сих пор я не видел информации ни от АМД ни от кого другого по поводу того, как его использовать. Но вчера мне наконец удалось заставить его работать в своём приложении.


Для начала, его следует включить и настроить парой простых комманд:
dev->SetRenderState(D3DRS_POINTSIZE, 0x7FA03001); //включаем
dev->SetRenderState(D3DRS_MAXTESSELLATIONLEVEL, *(DWORD*)(&floatTesselationFactor)); //настраиваем. Значения от 1.0f до 15.0f

Есть одна небольшая проблема. Если у вас меняется тип выводимой геометрии (например, выводили треугольники, а дальше пойдут стрипы), то необходимо "перезагрузить" тесселятор. Для этого, отключаем его:
dev->SetRenderState(D3DRS_POINTSIZE, 0x7FA03000); //другие значения могут сделать тоже самое
dev->SetRenderState(D3DRS_ENABLEADAPTIVETESSELLATION, 0); //никогда, никогда не ставьте тут 1 при включенном тесселяторе!
После этого, сразу включаем и настраиваем кодом выше.

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

Поэтому, если у вас на входе например, вот такая структура:
struct VS_INPUT
{
float4 position: POSITION0,
float2 texcoord: TEXCOORD0
};

То её следует поменять на такую:
struct VS_INPUT
{
float3 barycentric: BLENDWEIGHT0,

//First vertex
float4 position1: POSITION0,
float2 texcoord1: TEXCOORD0,

//Second vertex
float4 position2: POSITION4,
float2 texcoord2: TEXCOORD4,

//Third vertex
float4 position3: POSITION8,
float2 texcoord3: TEXCOORD8
};

Теперь, чтобы найти параметры вершины для текущего положения следует использовать такой код:
float4 position = position1 * barycentric.x + position2 * barycentric.y + position3 * barycentric.z;
float2 texcoord = texcoord1 * barycentric.x + texcoord2 * barycentric.y + texcoord3 * barycentric.z;

Удачи в экспериментах!
Previous post Next post
Up