[rmodels] "matModel" shader uniform is not multiplied with the push/pop matrix stack
denovodavid opened this issue · comments
Issue description
While making a transform hierarchy, I noticed that rmodels.c
DrawMesh function does not set the "matModel" matrix shader uniform relative to the push/pop matrix stack. See here:
Lines 1392 to 1398 in 9d67f47
"matModel" uniform is set to the model's local transform, then right after, a matModel variable is created, accumulated with push/pop matrix stack, and used for "matNormal" and "mvp" uniforms
This seems unintuitive, I expect "matModel" uniform to be the model space to world space transform, the same used calculate the "mvp" uniform, the same as the matModel variable.
However, I can work around this by getting the correct matModel in the shader by way of mat4 matModel = inverse(transpose(matNormal));
Issue Screenshot
Based on the Basic Lighting example, I have a player model that gets drawn after using rlPushMatrix()
and rlTranslatef(player_position)
, it is incorrectly lit, as if it was positioned at {0, 0, 0}
.
It should look like this:
@denovodavid Actually, the push/pop functionality was mostly intended the immediate-mode-style batching system, not for the modern VBO-based models drawing system. model.transform
is actually intended for that.
Not sure if applying matModel
to the model.transform
could derive in some issue. If you do some testing in that regards and nothing is broken, I can consider applying that additional transformation...
@denovodavid Actually, the push/pop functionality was mostly intended the immediate-mode-style batching system, not for the modern VBO-based models drawing system.
model.transform
is actually intended for that.
I see, though I think I can state my issue more clearly. The matrix stack is already used when calculating the model matrix used in mvp
sent to the shader, matProjection
and matView
also come from the matrix stack. matModel
(shader uniform) is just the local model.transform
matrix, which means you cannot necessarily reconstruct the mvp
in the shader from what should be its component parts.
// vertex shader
mvp != matProjection*matView*matModel;
This is what causes the incorrect lighting from my previous screenshots.
Not sure if applying
matModel
to themodel.transform
could derive in some issue. If you do some testing in that regards and nothing is broken, I can consider applying that additional transformation...
All I propose is to set (what I believe to be) the correct matModel
value of the model matrix shader uniform.
// Accumulate several model transformations:
// transform: model transformation provided (includes DrawModel() params combined with model.transform)
// rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
matModel = MatrixMultiply(transform, rlGetMatrixTransform());
// Model transformation matrix is sent to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], matModel);
I'll make a PR to show specifically.
@denovodavid thanks for the detailed explanation! I missunderstood it on my first read. And thanks for the fix!