【发布时间】:2013-07-23 18:37:55
【问题描述】:
这可能会在过早优化下提交,但由于顶点着色器在每一帧的每个顶点上执行,这似乎是值得做的事情(在进入像素着色器之前我需要乘以很多变量)。
本质上,顶点着色器执行此操作以将向量转换为投影空间,如下所示:
// Transform the vertex position into projected space.
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
由于我在着色器中对多个向量执行此操作,因此将这些矩阵组合成 CPU 上的累积矩阵然后将其刷新到 GPU 进行计算是有意义的,如下所示:
// VertexShader.hlsl
cbuffer ModelViewProjectionConstantBuffer : register (b0)
{
matrix model;
matrix view;
matrix projection;
matrix cummulative;
float3 eyePosition;
};
...
// Transform the vertex position into projected space.
pos = mul(pos, cummulative);
output.pos = pos;
在 CPU 上:
// Renderer.cpp
// now is also the time to update the cummulative matrix
m_constantMatrixBufferData->cummulative =
m_constantMatrixBufferData->model *
m_constantMatrixBufferData->view *
m_constantMatrixBufferData->projection;
// NOTE: each of the above vars is an XMMATRIX
我的直觉是行主要/列主要不匹配,但 XMMATRIX 是row-major struct(并且它的所有运算符都这样对待它)并且 mul(...) 将其矩阵参数解释为行专业。所以这似乎不是问题,但也许它仍然是我不理解的方式。
我还检查了累积矩阵的内容,它们看起来是正确的,这进一步增加了混乱。
感谢您的阅读,如果您能给我任何提示,我将不胜感激。
编辑(在 cmets 中请求的附加信息): 这是我用作矩阵常量缓冲区的结构:
// a constant buffer that contains the 3 matrices needed to
// transform points so that they're rendered correctly
struct ModelViewProjectionConstantBuffer
{
DirectX::XMMATRIX model;
DirectX::XMMATRIX view;
DirectX::XMMATRIX projection;
DirectX::XMMATRIX cummulative;
DirectX::XMFLOAT3 eyePosition;
// and padding to make the size divisible by 16
float padding;
};
我在 CreateDeviceResources(连同我的其他常量缓冲区)中创建矩阵堆栈,如下所示:
void ModelRenderer::CreateDeviceResources()
{
Direct3DBase::CreateDeviceResources();
// Let's take this moment to create some constant buffers
... // creation of other constant buffers
// and lastly, the all mighty matrix buffer
CD3D11_BUFFER_DESC constantMatrixBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
DX::ThrowIfFailed(
m_d3dDevice->CreateBuffer(
&constantMatrixBufferDesc,
nullptr,
&m_constantMatrixBuffer
)
);
... // and the rest of the initialization (reading in the shaders, loading assets, etc)
}
我在我创建的矩阵堆栈类中写入矩阵缓冲区。类的客户端在修改完矩阵后调用 Update():
void MatrixStack::Update()
{
// then update the buffers
m_constantMatrixBufferData->model = model.front();
m_constantMatrixBufferData->view = view.front();
m_constantMatrixBufferData->projection = projection.front();
// NOTE: the eye position has no stack, as it's kept updated by the trackball
// now is also the time to update the cummulative matrix
m_constantMatrixBufferData->cummulative =
m_constantMatrixBufferData->model *
m_constantMatrixBufferData->view *
m_constantMatrixBufferData->projection;
// and flush
m_d3dContext->UpdateSubresource(
m_constantMatrixBuffer.Get(),
0,
NULL,
m_constantMatrixBufferData,
0,
0
);
}
【问题讨论】:
标签: graphics matrix windows-phone-8 directx hlsl