PDA

View Full Version : Projection and Geometry shaders



joshuajnoble
10-25-2010, 07:34 PM
I'm trying to orient a triangle strip that I'm creating with a geometry shader to the projection (well, really to the eye coords of my camera). My shader looks like so:

#version 120
#extension GL_EXT_geometry_shader4 : enable

uniform float height;
uniform float width;

void main() {


gl_PositionIn[0];

gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_PositionIn[0].x, gl_PositionIn[0].y, gl_PositionIn[0].z, 1.0);
EmitVertex();

gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_PositionIn[0].x, gl_PositionIn[0].y-height, gl_PositionIn[0].z, 1.0);
EmitVertex();

gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_PositionIn[0].x-width, gl_PositionIn[0].y, gl_PositionIn[0].z, 1.0);
EmitVertex();

gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_PositionIn[0].x-width, gl_PositionIn[0].y-height, gl_PositionIn[0].z, 1.0);
EmitVertex();

// output
EndPrimitive();
}

(ps. no code formatting?) So, I'm just trying to figure out how I could transform the triangles to be oriented towards the camera, or whether it's better to calculate that on the CPU and then set a uniform vec3. Thanks!

david_f_knight
10-25-2010, 08:26 PM
If you want some triangles oriented towards the camera (by that, I assume you mean you want the triangles to be perpendicular to the camera), you should create your geometry after you have applied your modelview matrix. If you want your triangles to scale with distance, then you would apply the projection matrix after creating your geometry. If you do not want your triangles to scale with distance, i.e., to not have perspective, then you should apply your projection matrix before you create your geometry. You didn't state which you want, so I can't know. I've assumed you do want your triangles in perspective so they get smaller the further away they are.)

I'd do something like this (I only program in OpenGL 4.0 and GLSL syntax has changed since GLSL 1.2, so my GLSL syntax might not be quite right). First, I'm assuming that the W component of your input vertices is 1.0. I'd also most likely multiply the modelview matrix with the vertex in the vertex shader. If I didn't want the triangles created in the the geometry shader to have perspective, then I'd also multiply the projection matrix with the vertex in the vertex shader. Assuming I've only multiplied the modelview matrix in the vertex shader, I'd have:

#version 120
#extension GL_EXT_geometry_shader4 : enable

uniform float height;
uniform float width;

void main() {
gl_Position = gl_ProjectionMatrix * gl_PositionIn[0];
EmitVertex();

gl_Position = gl_ProjectionMatrix * vec4(gl_PositionIn[0].x, gl_PositionIn[0].y-height, gl_PositionIn[0].zw);
EmitVertex();

gl_Position = gl_ProjectionMatrix * vec4(gl_PositionIn[0].x-width, gl_PositionIn[0].yzw);
EmitVertex();

gl_Position = gl_ProjectionMatrix * vec4(gl_PositionIn[0].x-width, gl_PositionIn[0].y-height, gl_PositionIn[0].zw);
EmitVertex();

// output
EndPrimitive();
}

joshuajnoble
10-26-2010, 07:32 AM
Thanks so much and please excuse my sloppiness in describing what I want (long days render me less than eloquent sometimes). Yes, I did want the generated triangle strips to scale with persepctive and to be perpendicular to the camera. I'll give this a try as soon as I get home and see how it works out for me. Thanks!

joshuajnoble
10-26-2010, 09:26 PM
So, I tried this out and got somewhat strange results.
http://programminginteractivity.com/screen_shot.png

Maybe my vertex shader is off?



void main()
{

gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform() * gl_ModelViewMatrix;

}

skynet
10-27-2010, 01:49 AM
gl_Position = ftransform() * gl_ModelViewMatrix;

This is makes no sense. Usually, it is:

gl_Position = ftransform();

joshuajnoble
10-27-2010, 05:57 AM
Well, I was trying to follow Davids suggestion that to scale and position the generated geometry, I should
multiply the modelview matrix with the vertex in the vertex shader.

I'm wondering if my winding is somehow off now? That at least explains the odd generated shapes.

david_f_knight
10-27-2010, 11:28 PM
Well, I was trying to follow Davids suggestion that to scale and position the generated geometry, I should...But you didn't do what I suggested.

The ftransform() function performs the fixed function modelview and projection transforms, and then you multiplied that result by the modelview matrix, but in the wrong order. That's three mistakes.

Don't use ftransform().

In your vertex shader, your modelview multiplication should look like:
gl_Position = gl_ModelViewMatrix * your_vertex;

Matrix multiplication is not commutative, so the order matters. A lot.

Just to be clear, where I wrote "your_vertex" above, that would be declared as a vec4 with the "in" qualifier in OpenGL 4. Different versions of GLSL have different syntax for doing that, so I'm not sure what you need in your version.