ModelViewProjection

Just a simple question, but confusing to ke anyway… I have this:

Lua

self.mesh.shader.mModel = modelMatrix()
self.mesh.shader.mView = viewMatrix()
self.mesh.shader.mProjection = projectionMatrix()

Vertexshader

uniform mat4 mModel;
uniform mat4 mView;
uniform mat4 mProjection;
...
void main()
{
    ...
    mat4 mvp = mProjection * mView * mModel;
    gl_Position = mvp * position;
    // gl_Position = modelViewProjection * position;
}

I’m confused, because I thought my expression for mvp should be identical to the predefined modelViewProjection, but it isn’t working; my mesh isn’t showing at all.

Anyone knows how to accomplish this? Eventually I wanna scale the mModel*position coordinates.

You wrote:

Eventually I wanna scale the mModel*position coordinates.

So, presumably what you eventually want then is a viewProjectionMatrix.

Here’s the easiest way to do this:


function Entity:draw()
    -- grab the modelMatrix
    pushMatrix()
    translate(self.pos.x, self.pos.y, self.pos.z)
    rotate(self.euler.x, 1,0,0)
    -- rest of rotations
    self.mesh.shader.mModel = modelMatrix()

   -- now for the clever part: reset to the identity matrix before you draw
   resetMatrix()
   self.mesh:draw()
   popMatrix()
end

If you reset the model matrix before you draw, then it means the model matrix passed into the shaders MVPM is an identity matrix:

1,0,0,0
0,1,0,0
0,0,1,0
0,0,0,1

And this means that the shaders modelViewProjectionMatrix is in fact just a viewProjectionMatrix. You’ve effectively removed the modelMatrix out of the equation by resetting it to the identity.

The model’s position then comes not from the automatic MVPM, but from the mMatrix you passed in.

So in the shader, this will be correct:

  gl_Position = modelViewProjection * mModel * position;

This will also be much more perfomant than recalculating the MVP in each run through the vertex shader.

Sometimes I wish the Codea forum would allow answers to be up/ down-voted :stuck_out_tongue: B)

Turned out the problem was that the shader variables for each matrix weren’t updated every step.

Only problem now is that the rendering order is reversed somehow. Everything in the back is rendered in in front and vice versa. So I’m still a little bit confused…

@yojimbo2000 Your solution worked well! Thank you so much.

I didn’t come up with this method btw. I think it might’ve been one of @Ignatz 's?

Ok, I found the thread where we discussed this before, it was @Ignatz who came up with this technique:

https://codea.io/talk/discussion/comment/62198/#Comment_62198

I know this is an old thread but I’ve come across the same issue Kjell mentioned above:

Only problem now is that the rendering order is reversed somehow. Everything in the back is rendered in in front and vice versa.

If I set the projection matrix with perspective(60), read it with projectionMatrix() and use the value with similarly split model & view matrices in the shader the Z ordering seems inverted for some reason. I’m having to add gl_Position.z = 1.0 - gl_Position.z; at the end of my vertex shader just to correct for it.

@Simeon is there something going on that avoids this issue when Codea generates the modelViewProjection matrix?

@Steppers I haven’t had a lot of time to look into this, but this is how Codea generates its model view projection matrix which is delivered to shaders:

modelViewMatrix = fixMatrix * projectionMatrix * (viewMatrix * modelMatrixStack.back());

Where fixMatrix is an ortho matrix with the following parameters:

ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f) //left, right, top, bottom, near, far

The fix matrix used to be used when recording video (as the video would record upside-down, so the fix matrix would invert the screen during recording). I don’t think we need this since the move to ReplayKit for video recording and so will remove this

Thanks @Simeon !

This should be plenty of info for me to try to figure out what’s going on here. I’ll keep you posted if I find anything.

Ok so it seems fixMatrix is (inadvertently?) flipping z values too.

As you have it above:
ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f) //left, right, top, bottom, near, far
If this is the same form of the ortho function available in Lua then the top & bottom values seem to be the wrong way around and this only appears to be flipping the z axis and not y at all.

I suspect you may have a call to glDepthFunc(GL_GREATER) somewhere too to account for this z axis flip?

@Steppers I don’t think the fix matrix is used any longer so I’ll remove it. Sorry about the issues it was causing

Edit: Yes, we were using glDepthFunc(GL_GEQUAL)

@Steppers are you on the beta? If so the next build will have the fixMatrix removed

Thanks! No I’m not currently. Do I need a TestFlight code?

@Simeon this was not a good change, previously my lights demo worked as expected, now the meshes are reversed and drawing them in the opposite order creates an alpha transparency issue, see attached

It could well be that we just have to deal with it then for the sake of backward compatibility.

@skar thanks for the report! Sorry about the regression I’ll be looking into the cause of this tonight

@Steppers I’ve added you to the latest beta so you can try it out

@Simeon Yep, that behaves more as I expect now but I think you’ll either have to revert the change or add a binding to disable it. Many people’s custom shaders will be relying on the old logic.

Yeah I might revert the behaviour considering we have a new renderer coming anyway