Поделиться через


Использование геометрического смешивания (Direct3D 9)

Для вершин, которые будут смешиваться между двумя матрицами, можно использовать следующую определяемую пользователем структуру.

// The flexible vertex format (FVF) descriptor for this vertex would be:
//   FVF = D3DFVF_XYZB1 | D3DFVF_NORMAL | D3DFVF_TEX1; 

struct D3DBLENDVERTEX {
    D3DVECTOR v;
    FLOAT     blend; 
    D3DVECTOR n;
    FLOAT     tu, tv;
};

Вес смешения должен отображаться после положения и данных RHW в FVF, а также до нормальной вершины.

Обратите внимание, что предыдущий формат вершины содержит только одно значение веса смешения. Это связано с тем, что в состояниях преобразования D3DTS_WORLDMATRIX(0) и D3DTS_WORLDMATRIX(1) будут определены две мировые матрицы. Система объединяет каждую вершину между этими двумя матрицами, используя одно весовое значение. Для трех матриц требуются только два веса и т. д.

Примечание

Определение веса кожи легко. Использование линейной функции расстояния между суставами является хорошим началом, но более гладкая сигмоидная функция выглядит лучше. Выбор функции распределения веса кожи может привести к резким складкам в суставах, если это необходимо, используя большой разброс веса кожи на небольшом расстоянии.

 

Настройка матриц смешения

Матрицы преобразования, между которыми система смешивается, задается путем вызова метода IDirect3DDevice9::SetTransform . Присвойте первому параметру значение, определенное макросом D3DTS_WORLDMATRIX , а для второго параметра — адрес матрицы.

В следующем примере кода C++ задаются две матрицы мира, между которыми смешивается геометрия, чтобы создать иллюзию соединения руки.

// For this example, the d3dDevice variable is assumed to be a valid pointer
//   to an IDirect3DDevice9 interface for an initialized 3D scene.

float     BendAngle = 3.1415926f / 4.0f; // 45 degrees
D3DMATRIX matUpperArm, matLowerArm;

// The upper arm is immobile. Use the identity matrix.
D3DXMatrixIdentity( matUpperArm );
d3dDevice->SetTransform( D3DTS_WORLDMATRIX(0), &matUpperArm );

// The lower arm rotates about the x-axis, attached to the upper arm.
D3DXMatrixRotationX( matLowerArm, -BendAngle ); 
d3dDevice->SetTransform( D3DTS_WORLDMATRIX(1), &matLowerArm );

Установка матрицы смешения просто приводит к тому, что система кэширует матрицу для последующего использования; он не предписывает системе начать смешивание вершин.

Включение смешивания геометрии

Смешивание геометрии отключено по умолчанию. Чтобы включить смешивание геометрии, вызовите метод IDirect3Device9::SetRenderState , чтобы задать для состояния D3DRS_VERTEXBLEND отрисовки значение из перечисленного типа D3DVERTEXBLENDFLAGS . В следующем примере кода показано, как может выглядеть этот вызов при задании состояния отрисовки для смешения между двумя матрицами мира.

d3dDevice->SetRenderState( D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS );

Если D3DRS_VERTEXBLEND задано любое значение, отличное от D3DVBF_DISABLE, система предполагает, что в формат вершин будет включено соответствующее количество весовых коэффициентов смешения. Вы несете ответственность за предоставление соответствующего формата вершины и правильное описание этого формата для методов отрисовки Direct3D.

Если этот параметр включен, система выполняет смешивание геометрии для всех объектов, отображаемых методами отрисовки DrawPrimitive.

См. также:

Исправлены коды FVF функции (Direct3D 9)

Наложение геометрии