PDA

View Full Version : Drawing a billboard sprite from a single point- need geometry shader?



PrestoChung
06-23-2013, 08:27 PM
Essentially each point in the buffer will be the center of a new billboard sprite (two triangles). Does this mean I need to use a geometry shader? (never used one before).

mhagain
06-24-2013, 02:22 AM
You can also do it with instancing (and it may even be faster than using a GS).

Dark Photon
06-24-2013, 04:57 AM
Essentially each point in the buffer will be the center of a new billboard sprite (two triangles). Does this mean I need to use a geometry shader? (never used one before).

You can but you don't have to. In addition to sending down a POINT for each sprite and using geom shader to do POINT-to-QUAD, you can send down a QUAD where all of the verts are at the same point, and then just use the vtx shader to displace the vertices to the appropriate size.

And then (as mhagain mentioned) -- in either case -- you can choose whether to use geometry instanced draw calls or normal non-instanced draw calls.

mhagain
06-24-2013, 06:06 AM
There's an obvious tradeoff in all of this of course. With the instancing (or 4 vertex) approach there are certain calculations that you'll need to do 4 times per-sprite instead of just once; however having the GS stage active will impose some extra overhead of it's own (and this is true even if the GS is just pass-through) - using a geometry shader can therefore be actually slower, despite the appeal of having less data. Unfortunately there is no single answer to "which is the best" that applies in all cases, so you really need to profile and consider your hardware requirements: using a GS requires DX10 level hardware, instancing requires SM3 level (and some SM2 supports it), just sending all 4 verts should work on anything.

PrestoChung
06-24-2013, 06:55 PM
Thanks for the replies.

So I went ahead with the geometry shader. I found an example here that is similar and made more sense to me than the other examples I had found:
https://raw.github.com/progschj/OpenGL-Examples/master/07geometry_shader_blending.cpp

Edit: Figured it out, wasn't attaching the geometry shader.

So far, though, I haven't gotten any rendering. One difference from the code above is that I am using a texture. Is there any problem to using GL_TEXTURE_RECTANGLE for the texture in this case? So far the only other textures in my code are ortho-rendered quads, so I have been using this texture type and all my other texture loading code uses it.

Here are my shaders, if there is anything obviously wrong with them:

Vertex: (Simple pass-through)

#version 330

layout(location = 0) in vec3 inCoord;

void main()
{
gl_Position = vec4(inCoord, 1);
}

Geometry: (Image size is 599x590 pixels. This will be changed later to fit image size or normalized coordinates. Arbitrary size of -10 to +10 in the billboard size)

#version 330

uniform mat4 uProjectionMatrix;
uniform mat4 uModelviewMatrix;

layout(points) in;
layout(triangle_strip, max_vertices = 4) out;

out vec2 varTex;

void main()
{
vec4 center = uModelviewMatrix * gl_in[0].gl_Position;

varTex = vec2( 0, 0 );
gl_Position = uProjectionMatrix * (center + vec4(10, 10, 0, 0));
EmitVertex();

varTex = vec2( 599, 0 );
gl_Position = uProjectionMatrix * (center + vec4(10, -10, 0, 0));
EmitVertex();

varTex = vec2( 0, 590 );
gl_Position = uProjectionMatrix * (center + vec4(-10, 10, 0, 0));
EmitVertex();

varTex = vec2( 599, 590 );
gl_Position = uProjectionMatrix * (center + vec4(-10, -10, 0, 0));
EmitVertex();
}

Fragment:

#version 330

uniform sampler2DRect uTex;

in vec2 varTex;

layout(location = 0) out vec4 outFragColor;

void main()
{
vec4 tex_color;
tex_color = texture( uTex, varTex );

outFragColor = tex_color;
}