Skip to content

Commit

Permalink
Geometry shader: generate tris facing the camera
Browse files Browse the repository at this point in the history
 - Modified the geometry shader to generate triangles that are oriented
   to sit on the camera plane.

 - Made the geometry shader actually use the "geometry_thickness"
   uniform value.
  • Loading branch information
yalue committed Mar 4, 2022
1 parent ef54851 commit 2b4870e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
7 changes: 3 additions & 4 deletions l_system_3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#define DEFAULT_WINDOW_WIDTH (800)
#define DEFAULT_WINDOW_HEIGHT (600)
#define DEFAULT_FPS (60.0)
#define DEFAULT_GEOMETRY_THICKNESS (0.5)
#define DEFAULT_GEOMETRY_THICKNESS (0.125)

static ApplicationState* AllocateApplicationState(void) {
ApplicationState *to_return = NULL;
Expand Down Expand Up @@ -325,9 +325,8 @@ static int WaitNextFrame(ApplicationState *s) {

static int RunMainLoop(ApplicationState *s) {
glEnable(GL_DEPTH_TEST);
// TODO: Re-enable face culling after getting the geometry shader working.
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glClearColor(0, 0, 0, 1.0);
while (!glfwWindowShouldClose(s->window)) {
s->frame_start = glfwGetTime();
Expand Down
41 changes: 25 additions & 16 deletions pipes_shader.geom
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#version 330 core
layout (lines) in;
layout (line_strip, max_vertices = 4) out;
layout (triangle_strip, max_vertices = 3) out;

in VS_OUT {
vec3 position;
Expand Down Expand Up @@ -28,35 +28,44 @@ float timeOffset() {
return (sin(shared_uniforms.current_time * 3) + 1.0) * 0.5;
}

// Takes a forward-facing vector and returns a vector that points to its right,
// along the camera plane.
vec3 cameraRight(vec3 position, vec3 forward) {
vec3 to_camera = shared_uniforms.camera_position.xyz - position;
return normalize(cross(forward, to_camera));
}

void main() {
gs_out.forward = normal * gs_in[0].forward;
gs_out.up = normal * gs_in[0].up;
gs_out.right = normal * gs_in[0].right;
gs_out.forward = normalize(normal * gs_in[0].forward);
gs_out.up = normalize(normal * gs_in[0].up);
gs_out.right = normalize(normal * gs_in[0].right);
gs_out.color = gs_in[1].color;

mat4 projView = shared_uniforms.projection * shared_uniforms.view;
vec4 pos_tmp = model * vec4(gs_in[0].position, 1);
pos_tmp += normalize(vec4(gs_out.forward, 1.0)) * timeOffset();
gs_out.frag_position = pos_tmp.xyz;
vec3 frag_pos_start = pos_tmp.xyz;
gs_out.frag_position = frag_pos_start;;
gl_Position = projView * pos_tmp;
EmitVertex();

pos_tmp = model * vec4(gs_in[1].position, 1);
pos_tmp += normalize(vec4(gs_out.forward, 1.0)) * timeOffset();
gs_out.frag_position = pos_tmp.xyz;
vec3 frag_pos_end = pos_tmp.xyz;
gs_out.frag_position = frag_pos_end;
gl_Position = projView * pos_tmp;
EmitVertex();
EndPrimitive();

// Add a second primitive: a line starting at each midpoint and pointing in
// the "up" direction.
// TODO (next): Continue the same thing, except put points to the left and
// right of both endpoints rather than a single triangle point to the left of
// the midpoint.

// The third vertex is in the "up" direction from the midpoint of the
// original segment.
vec3 dir = gs_in[1].position - gs_in[0].position;
vec3 midpoint = gs_in[0].position + dir * 0.5;
pos_tmp = model * vec4(midpoint, 1.0);
gs_out.frag_position = pos_tmp.xyz;
gl_Position = projView * pos_tmp;
EmitVertex();
pos_tmp = model * vec4(midpoint + gs_out.up * (length(dir) * 0.5), 1);
pos_tmp = model * vec4(midpoint, 1);
vec3 plane_right = cameraRight(pos_tmp.xyz, gs_out.forward);
pos_tmp.xyz = pos_tmp.xyz - plane_right * (length(frag_pos_end -
frag_pos_start) * shared_uniforms.geometry_thickness);
gs_out.frag_position = pos_tmp.xyz;
gl_Position = projView * pos_tmp;
EmitVertex();
Expand Down

0 comments on commit 2b4870e

Please sign in to comment.