Why is my Geometry Shader meshes moving when I move my camera?

Hello, I have a basic geometry shader that I use to generate quads and texture them. Every time I move my camera, the quads also seem to rotate in the direction of my camera (they are always perpendicular to my camera), I don’t know why that is happening.

Vertex Shader:


#version 330 core

layout (location = 0) in vec3 vposition;
layout (location = 1) in vec2 vtexture;
out vec2 Texture;

void main()
{
	gl_Position = vec4(vposition, 1.0f);
	Texture = vtexture;
}

Geometry Shader:


#version 330 core

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

out vec2 Texture;

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

void main()
{
	gl_Position = Projection * View * Model * gl_in[0].gl_Position; 
	Texture = vec2(0.0f, 1.0f);
	EmitVertex();

	gl_Position = Projection * View * Model * gl_in[0].gl_Position;  
	Texture = vec2(0.0f, 0.0f);
	EmitVertex();
	
	gl_Position = Projection * View * Model * gl_in[0].gl_Position;
	Texture = vec2(1.0f, 0.0f);
	EmitVertex();
	
	gl_Position = Projection * View * Model * gl_in[0].gl_Position
	Texture = vec2(1.0f, 1.0f);
	EmitVertex();

    EndPrimitive();
}

Your geometry shader is emitting four identical points, so you shouldn’t be seeing anything.

To get quads which are aligned in model space, you should be adding offsets after transformation by the model matrix but before transformation by the view and projection matrices.

Thank you for your reply, I added the offsets and I can see the quads, but they are still moving with the camera :tired:


void DrawSmallTrees(vec4 Pos)
{
	gl_Position = Projection * View * Model * Pos + vec4(-0.3f, -0.3f, 0.0f, 0.0f); // Bottom Left
	Texture = vec2(0.0f, 1.0f);
	EmitVertex();

	gl_Position = Projection * View * Model * Pos + vec4(0.3f, -0.3f, 0.0f, 0.0f); // Bottom Right
	Texture = vec2(1.0f, 1.0f);
	EmitVertex();
	
	gl_Position = Projection * View * Model * Pos + vec4(-0.3f, 0.7f, 0.0f, 0.0f); // Top Left
	Texture = vec2(0.0f, 0.0f);
	EmitVertex();
	
	gl_Position = Projection * View * Model * Pos + vec4(0.3f, 0.7f, 0.0f, 0.0f); // Top Right
	Texture = vec2(1.0f, 0.0f);
	EmitVertex();

    EndPrimitive();
}

void main() 
{
	DrawSmallTrees(gl_in[0].gl_Position);
}

This:


Projection * View * Model * Pos

transforms an object-space position “Pos” to clip space. This:


Model * Pos

transforms an object-space position “Pos” to world space.

So which space are you applying your offset in?

I’m guessing I’m applying offset in clip space. If I remove Projection * View then the grass wouldn’t be visible to the camera anymore.

Right.

If I remove Projection * View then the grass wouldn’t be visible to the camera anymore.

It’s very possible, because the displacement would be happening in object-space, which may have any orientation w.r.t. the camera (eye-space and clip-space). It could even be edge-on, so nothing would be rendered (i.e. no pixels would be rasterized).

This is why billboards are typically positioned orthogonal to the camera in screen-space or eye-space. Their purpose not to define the boundary of a physical object, but rather to just trigger rasterization and shading for these pixels so you can render something that looks reasonable for an object that’s not so easily defined (e.g. fuzzy smoke cloud, blades of grass, fire, cumulus cloud, font character, etc.)

[QUOTE=MysticWizard;1288798]Thank you for your reply, I added the offsets and I can see the quads, but they are still moving with the camera


void DrawSmallTrees(vec4 Pos)
{
	gl_Position = Projection * View * Model * Pos + vec4(-0.3f, -0.3f, 0.0f, 0.0f); // Bottom Left

[/QUOTE]
That’s because you’re applying the offset after the coordinates have been transformed to clip space. If you want the offset to be applied in object space:


	gl_Position = Projection * View * Model * (Pos + vec4(-0.3f, -0.3f, 0.0f, 0.0f));

Or in world space:


	gl_Position = Projection * View * (Model * Pos + vec4(-0.3f, -0.3f, 0.0f, 0.0f));

Okay, I understand how it all works now, thank you both!