This topic is 2952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm writing my first geometry shader in glsl. I want to extrude points uploaded to the gpu to two triangles facing the camera (spherical billboards). The idea is to calculate the three axes of the billboard (typical lookat() function) and then position the vertices along these axes. What i've got somehow works but the billboards start rotating in the wrong direction when the camera moves close and/or spin around their z axis. Any ideas what i'm missing? What bothers me is that the camera's rotation is not considered; shouldn't the billboards' rotation have to be influenced by that?

Thanks!

#version 330 core layout (points) in; layout (triangle_strip) out; layout (max_vertices = 4) out; layout(std140) uniform; uniform Transform { mat4 view; mat4 model; vec4 animate; mat4 bones[64]; } transform; uniform Projection { mat4 perspective; mat4 orthographic; } projection; uniform vec3 cameraPosition; out vec2 textureCoords; void main() { mat4 mvp = projection.perspective*transform.view*transform.model; vec3 center = gl_in[0].gl_Position.xyz; vec3 zAxis = normalize( cameraPosition-center ); vec3 yAxis = vec3( 0.0, 1.0, 0.0 ); vec3 xAxis = normalize( cross(zAxis, yAxis) ); yAxis = normalize( cross(xAxis, zAxis) ); vec3 x = xAxis*0.5; vec3 y = yAxis*0.5; gl_Position = mvp*vec4( center-x-y, 1.0 ); textureCoords = vec2( 0.0, 0.0 ); EmitVertex(); gl_Position = mvp*vec4( center-x+y, 1.0 ); textureCoords = vec2( 0.0, 1.0 ); EmitVertex(); gl_Position = mvp*vec4( center+x-y, 1.0 ); textureCoords = vec2( 1.0, 0.0 ); EmitVertex(); gl_Position = mvp*vec4( center+x+y, 1.0 ); textureCoords = vec2( 1.0, 1.0 ); EmitVertex(); EndPrimitive(); } 

This is what it looks like atm:

##### Share on other sites
I think the difference in what you are getting and what you want is that you are doing the expansion in world space instead of in view space. Your input point should already be in view space (from a previous pipeline stage), then you create your new vertices and offset them (in view space), and finally transform them only with the projection matrix. Then they will appear to be aligned with the viewing plane, which I think is what you are after.

##### Share on other sites
Thanks for the input! What you're saying makes perfect sense. I've changed my shaders (see below) but the billboards are still not always facing the camera.. rather, they seem to be rotated in the wrong direction along the y-axis, and I'm not sure why.

#version 330 core layout(location = 0) in vec4 in_vertexPos; uniform Transform { mat4 view; mat4 model; vec4 animate; mat4 bones[64]; } transform; void main() { mat4 modelViewMatrix = transform.view*transform.model; gl_Position = modelViewMatrix*vec4( in_vertexPos.xyz, 1.0 ); }

#version 330 core layout (points) in; layout (triangle_strip) out; layout (max_vertices = 4) out; layout(std140) uniform; uniform Projection { mat4 perspective; mat4 orthographic; } projection; uniform vec3 cameraPosition; out vec2 textureCoords; void main() { mat4 p = projection.perspective; vec3 center = gl_in[0].gl_Position.xyz; vec3 zAxis = normalize( cameraPosition-center ); vec3 yAxis = vec3( 0.0, 1.0, 0.0 ); vec3 xAxis = normalize( cross(zAxis, yAxis) ); yAxis = normalize( cross(xAxis, zAxis) ); vec3 x = xAxis*0.5; vec3 y = yAxis*0.5; gl_Position = p*vec4( center-x-y, 1.0 ); textureCoords = vec2( 0.0, 0.0 ); EmitVertex(); gl_Position = p*vec4( center-x+y, 1.0 ); textureCoords = vec2( 0.0, 1.0 ); EmitVertex(); gl_Position = p*vec4( center+x-y, 1.0 ); textureCoords = vec2( 1.0, 0.0 ); EmitVertex(); gl_Position = p*vec4( center+x+y, 1.0 ); textureCoords = vec2( 1.0, 1.0 ); EmitVertex(); EndPrimitive(); } 

##### Share on other sites
Can you post a screen shot of the way it looks now?

##### Share on other sites
I used a very different approach in the end; someone gave me a good tip on the OpenGL forums:

#version 330 core layout (points) in; layout (triangle_strip) out; layout (max_vertices = 4) out; layout(std140) uniform; uniform Display { vec2 area; vec2 oneOverArea; } display; uniform Projection { mat4 perspective; mat4 orthographic; } projection; uniform Transform { mat4 view; mat4 model; vec4 animate; mat4 bones[64]; } transform; uniform bool forceSize = false; uniform ivec2 spriteSize = ivec2( 128, 128 ); out Vertex { vec2 textureCoords; } vertex; void main() { vec3 pos = gl_in[0].gl_Position.xyz; mat4 modelView = transform.view*transform.model; mat4 modelViewProjection = projection.perspective*modelView; vec4 clip = modelViewProjection*vec4( pos, 1.0 ); float dx = spriteSize.x*display.oneOverArea.x; float dy = spriteSize.y*display.oneOverArea.y; if( forceSize ) { dx *= 0.5*clip.w; dy *= 0.5*clip.w; } gl_Position = vec4( clip.x-dx, clip.y-dy, clip.z, clip.w ); vertex.textureCoords = vec2( 0.0, 0.0 ); EmitVertex(); gl_Position = vec4( clip.x-dx, clip.y+dy, clip.z, clip.w ); vertex.textureCoords = vec2( 0.0, 1.0 ); EmitVertex(); gl_Position = vec4( clip.x+dx, clip.y-dy, clip.z, clip.w ); vertex.textureCoords = vec2( 1.0, 0.0 ); EmitVertex(); gl_Position = vec4( clip.x+dx, clip.y+dy, clip.z, clip.w ); vertex.textureCoords = vec2( 1.0, 1.0 ); EmitVertex(); EndPrimitive(); }

##### Share on other sites
glad to see you got there in the end, its actually quite simple, as is good as a first algorythm with the geometry shader. :-)

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 15
• 21
• 21
• 11
• 25