У меня есть простой пиксельный шейдер DirectX9 HLSL, который я перенес из GLSL, я прочитал, что мне нужно будет изменить правую систему координат на левую систему координат Direct3D по умолчанию. В результате мои результаты перевернуты, а математика неверна.
Команды пиксельного шейдера были правильно переведены из GLSL в HLSL.
MSDN также предоставляет руководство по портированию для буферов вершин Directx11.
Кто-нибудь знает, как приведенный ниже код следует правилам MSDN для DFirectX9:
MSDN заявляет:
Отразите порядок вершин треугольника, чтобы Direct3D проходил их по часовой стрелке спереди. Например, если ваши вершины проиндексированы как 0, 1 и 2 в вашем конвейере OpenGL, вместо этого передайте их Direct3D как 0, 2, 1.
Используйте матрицу вида, чтобы масштабировать мировое пространство на -1.0f в направлении z, эффективно изменяя координаты оси z. Чтобы сделать это, переверните знак значений в позициях M31, M32 и M33 в матрице вида (при переносе на тип Matrix). Если M34 не равно 0, переверните его знак.
Вопрос:
Нужно ли вводить вершинный шейдер HLSL?
Следующий код передает данные в пиксельный шейдер без использования вершинного шейдера.
struct Vertex { FLOAT x, y, z, rhw;
DWORD diffuse_color;
FLOAT u, v; };
#define MY_VERTEX_FORMAT (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
const int num_vertices = 4;
Vertex vertices[num_vertices] = {
0, 0, 0, 1, 0xFFFF0000, 0.0f, 0.0f, // left top
w, 0, 0, 1, 0xFFFF0000, 1.0f, 0.0f, // right top
w, h, 0, 1, 0xFFFF0000, 1.0f, 1.0f, // right bottom
0, h, 0, 1, 0xFFFF0000, 0.0f, 1.0f // left bottom };
.....
m_pD3DD9->SetPixelShader(pShader);
m_pD3DD9->BeginScene();
hr = m_pD3DD9->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
m_pD3DD9->EndScene();
... ..
Shader:
sampler2D rgbaTexture : register(S0);
float4 main(float2 in_Point : TEXCOORD) : COLOR
{
…..
}
Любое руководство будет с благодарностью!
ОБНОВЛЕНИЕ 1
Хорошо, поэтому мне нужно указать правостороннее представление и матрицу проекции:
struct Vertex
{
FLOAT x, y, z;
FLOAT u, v;
};
...
->BeginScene()
D3DXMATRIX matView
D3DXVECTOR3 eye(2, 3, 3); //??
D3DXVECTOR3 Lat(0, 0, 0); //??
D3DXVECTOR3 up(0, 1, 0); //??
D3DXMatrixLookAtRH(&matView, &eye, &Lat, &up);
d3ddevice->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovRH(&matProjection, D3DXToRadian(45.0f), float(SrcW / SrcH), 0.1f, 100.0f);
m_pD3DD9->SetTransform(D3DTS_PROJECTION, &matProjection);
Какие числа нужно добавить в эти матрицы, чтобы это работало, я хотел бы, чтобы вся текстура через шейдер была, как и раньше, но с правой системой координат?
ОТВЕТ
XMFLOAT4X4 matView;
XMFLOAT4X4 matProjection;
FXMVECTOR mEye = XMVectorSet(0.0f, 15.0f, -30.0f, 0.0f);
FXMVECTOR mAt = XMVectorSet(0.0f, 8.0f, 0.0f, 0.0f);
FXMVECTOR mUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
float fovInDegrees = 45.0f;
float aspectRatio = (float)m_SrcW / (float)m_SrcH;
float fovAngleY = fovInDegrees * XM_PI / 180.0f;
if (aspectRatio < 1.0f)
fovAngleY /= aspectRatio;
XMStoreFloat4x4(&matView, XMMatrixTranspose(XMMatrixLookAtRH(mEye, mAt, mUp)));
XMStoreFloat4x4(&matProjection, XMMatrixTranspose(XMMatrixPerspectiveFovRH(fovAngleY, aspectRatio, 0.01f, 125.0f)));
hr = m_pD3DD9->SetTransform(D3DTS_VIEW, reinterpret_cast<D3DXMATRIX*>(&matView));
hr = m_pD3DD9->SetTransform(D3DTS_PROJECTION, reinterpret_cast<D3DXMATRIX*>(&matProjection));