PDA

View Full Version : Shader Trouble


leoaered
09-23-2012, 11:55 PM
I'm trying to send the model view projection matrix from the CPU side into my shader, but it's not working as expected. I have two objects loaded into my scene, without any transformations: 'box.wrl' and 'ground.osgb'.

1) Sending over the projection matrix seems to mess up the order of rendering.

uniform vec4 S1, S2, S3, S4;
void main()
{
gl_Position = mat4(S1, S2, S3, S4) * gl_ModelViewMatrix * gl_Vertex;
//gl_Position = ftransform();
}
When I pass in viz.MainWindow.getProjectionMatrix(), the scene looks OK, just the ground is rendered on top of the box. I don't really understand why, since if I use ftransform() or the inbuilt gl_ProjectionMatrix/gl_ModelViewProjectionMatrix the problem goes away. I also don't think there is a problem with the way I'm sending over the matrix, because I tried hardcoding the projection matrix into the vertex shader and had the same issue.

2) I can't get the view matrix to work, or I don't understand how to get it.

uniform vec4 S1, S2, S3, S4;
void main()
{
gl_Position = gl_ProjectionMatrix * mat4(S1, S2, S3, S4) * gl_Vertex;
//gl_Position = ftransform();
}

I tried passing viz.MainView.getMatrix() / viz.MainWindow.getMatrix() to no avail. The box doesn't show up properly. What am I missing? The model matrix should be identity because I didn't have any transforms on the objects.

*Sorry for the double post in Vizard 3.0 forum. I realized I posted on the wrong forum, and also have more useful information this time.

farshizzo
09-24-2012, 09:18 AM
By default, Vizard will automatically compute the near/far clipping planes based on what geometry is in view. The clip planes in the matrix returned by viz.MainWindow.getProjectionMatrix() won't match the clip planes that will be used to perform the rendering. This is why the ground shows up on top of the box.

You can use the viz.MainWindow.clip command to specify static clip planes. This will ensure the projection matrix is the same as the one being used to render the scene.

Here is an updated version of the script:
import viz, vizcam, vizshape, vizfx.postprocess, vizact

vizcam.PivotNavigate(center=[0, 0.1, 0], distance=5)
viz.go()

box = viz.addChild('box.wrl')
ground = viz.addChild('ground.osgb')

vertCode = """
uniform vec4 S1, S2, S3, S4;
void main()
{
gl_Position = mat4(S1, S2, S3, S4) * gl_ModelViewMatrix * gl_Vertex;
}
"""
fragCode = """
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
"""

shader = viz.addShader(vert=vertCode, frag=fragCode)
box.apply(shader)

# Use static clip plane so projection matrix doesn't change
viz.MainWindow.clip(0.1,100)
m = viz.MainWindow.getProjectionMatrix()

S1 = viz.addUniformFloat('S1', m[0:4])
S2 = viz.addUniformFloat('S2', m[4:8])
S3 = viz.addUniformFloat('S3', m[8:12])
S4 = viz.addUniformFloat('S4', m[12:16])
box.apply(S1)
box.apply(S2)
box.apply(S3)
box.apply(S4)

leoaered
09-24-2012, 01:29 PM
Thanks for the help!

Do you happen to know why viz.MainWindow.getMatrix() * box.getMatrix() is incorrect for the modelview matrix?

The box shows up but is moving incorrectly when I rotate the viewpoint.

farshizzo
09-24-2012, 01:39 PM
You need to pass the inverse of the view matrix:
m = viz.MainWindow.getMatrix().inverse()

leoaered
09-24-2012, 02:12 PM
Hi farshizzo,

That's what I thought at first when the box was moving the wrong direction. But I already tried passing the inverse and the box doesn't show up at all. Is there something else I'm doing wrong?

farshizzo
09-25-2012, 08:12 AM
Sorry, forgot to mention that you need to convert the matrix to the OpenGL reference frame:m = viz.MainView.getMatrix().inverse()
m[2] = -m[2];
m[6] = -m[6];
m[8] = -m[8];
m[9] = -m[9];
m[14] = -m[14];

leoaered
09-25-2012, 01:17 PM
Thanks for that, farshizzo. One last question:

How would I tie everything together and add the model matrix to the equation? Do I have to perform any operations/conversions on this matrix as well? Also, what is the multiplication order of model, view, and projection matrices?

<node3d>.getMatrix() on objects doesn't seem to work properly without either an inverse() or the same conversion you used for the view matrix. This seems really weird to me because I manually checked that the transformation matrix was correct as is.

I'm simply trying to send the MVP to the shader, but everything seems to be flipped from what I'm used to. For example, P * V * M seems to be the wrong multiplication order. I also don't understand why you needed to do the conversion on the view matrix.

Thanks again!

leoaered
10-01-2012, 02:30 AM
Yikes! I've been debugging for some time and it seems like there's still something wrong with the view matrix.

I made a simple plane and tried rendering it with:
m = viz.MainView.getMatrix().inverse()
m[2] = -m[2];
m[6] = -m[6];
m[8] = -m[8];
m[9] = -m[9];
m[14] = -m[14];

The plane is rotated! Everything goes back to normal with ftransform().

farshizzo
10-03-2012, 12:42 PM
Vizard will rotate certain model formats by 90 degrees along the X-axis in order to bring it into the Vizard coordinate frame. This is probably why you see a rotation.