PDA

View Full Version : Why is my Geometry Shader meshes moving when I move my camera?



MysticWizard
10-05-2017, 01:50 AM
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();
}

GClements
10-05-2017, 04:21 PM
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.

MysticWizard
10-05-2017, 06:56 PM
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);
}

Dark Photon
10-05-2017, 07:18 PM
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?

MysticWizard
10-05-2017, 07:56 PM
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.

Dark Photon
10-06-2017, 06:31 AM
I'm guessing I'm applying offset in clip space.

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.)

GClements
10-06-2017, 06:40 AM
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


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));

MysticWizard
10-06-2017, 06:59 AM
Okay, I understand how it all works now, thank you both!