graphics - Why is the transitive closure of matrix multiplication not working in this vertex shader? -
this can filed under premature optimization, since vertex shader executes on each vertex each frame, seems worth doing (i have lot of vars need multiply before going pixel shader).
essentially, vertex shader performs operation convert vector projected space, so:
// transform vertex position projected space. pos = mul(pos, model); pos = mul(pos, view); pos = mul(pos, projection); output.pos = pos;
since i'm doing operation multiple vectors in shader, made sense combine matrices cumulative matrix on cpu , flush gpu calculation, so:
// vertexshader.hlsl cbuffer modelviewprojectionconstantbuffer : register (b0) { matrix model; matrix view; matrix projection; matrix cummulative; float3 eyeposition; }; ... // transform vertex position projected space. pos = mul(pos, cummulative); output.pos = pos;
and on cpu:
// renderer.cpp // time update cummulative matrix m_constantmatrixbufferdata->cummulative = m_constantmatrixbufferdata->model * m_constantmatrixbufferdata->view * m_constantmatrixbufferdata->projection; // note: each of above vars xmmatrix
my intuition there mismatch of row-major/column-major, xmmatrix row-major struct (and of operators treat such) , mul(...) interprets matrix parameter row-major. doesn't seem problem perhaps still in way don't understand.
i've checked contents of cumulative matrix , appear correct, further adding confusion.
thanks reading, i'll appreciate hints can give me.
edit (additional information requested in comments): struct using matrix constant buffer:
// constant buffer contains 3 matrices needed // transform points they're rendered correctly struct modelviewprojectionconstantbuffer { directx::xmmatrix model; directx::xmmatrix view; directx::xmmatrix projection; directx::xmmatrix cummulative; directx::xmfloat3 eyeposition; // , padding make size divisible 16 float padding; };
i create matrix stack in createdeviceresources (along other constant buffers), so:
void modelrenderer::createdeviceresources() { direct3dbase::createdeviceresources(); // let's take moment create constant buffers ... // creation of other constant buffers // , lastly, mighty matrix buffer cd3d11_buffer_desc constantmatrixbufferdesc(sizeof(modelviewprojectionconstantbuffer), d3d11_bind_constant_buffer); dx::throwiffailed( m_d3ddevice->createbuffer( &constantmatrixbufferdesc, nullptr, &m_constantmatrixbuffer ) ); ... // , rest of initialization (reading in shaders, loading assets, etc) }
i write matrix buffer inside matrix stack class created. client of class calls update() once done modifying matrices:
void matrixstack::update() { // update buffers m_constantmatrixbufferdata->model = model.front(); m_constantmatrixbufferdata->view = view.front(); m_constantmatrixbufferdata->projection = projection.front(); // note: eye position has no stack, it's kept updated trackball // time update cummulative matrix m_constantmatrixbufferdata->cummulative = m_constantmatrixbufferdata->model * m_constantmatrixbufferdata->view * m_constantmatrixbufferdata->projection; // , flush m_d3dcontext->updatesubresource( m_constantmatrixbuffer.get(), 0, null, m_constantmatrixbufferdata, 0, 0 ); }
given code snippets, should work.
possible causes of problem:
- have tried inverted multiplication:
projection * view * model
? - are sure set correctly
cummulative
(register index = 12, offset = 192) in constant buffer - same
eyeposition
(register index = 12, offset = 256)?
Comments
Post a Comment