Sunday, 27 January 2013

Procedural cube in a vertex shader

With OpenGL3+ and shader tricks, one can procedurally generate fullscreen quads or implicit surfaces. Here's another little trick I found to draw a unit sized cube with a single draw call (a triangle strip with 14 vertices) without any vertex or index buffers. The idea is to use the gl_VertexID variable to extract the positions of the vertices.

Here are the shaders (which I now use to render my skyboxes)
Vertex Shader:
#version 330

uniform mat4 uModelViewProjection;

out vec3 vsTexCoord;
#define oTexCoord vsTexCoord

void main() {
 // extract vertices
 int r = int(gl_VertexID > 6);
 int i = r==1 ? 13-gl_VertexID : gl_VertexID;
 int x = int(i<3 || i==4);
 int y = r ^ int(i>0 && i<4);
 int z = r ^ int(i<2 || i>5);

 // compute world pos and project
 const float SKY_SIZE = 100.0;
 oTexCoord = vec3(x,y,z)*2.0-1.0;
 gl_Position = uModelViewProjection *

Fragment shader (which is pretty standard):
#version 330

uniform samplerCube sSky;

in vec3 vsTexCoord;
#define iTexCoord vsTexCoord
layout(location=0) out vec4 oColour;

void main() {
 oColour = texture(sSky, normalize(iTexCoord));

And the client code:
// init

// render
glDrawArrays(GL_TRIANGLE_STRIP, 0, 14);

Real-time whitecaps !

   During my master thesis I had the great opportunity to work with Eric Bruneton on a fast method to render whitecaps on ocean scenes. We came up with a scalable solution (e.g. performance is independent from the viewing resolution) which runs in real time on current GPUs, and was presented at SIGGRAPH Asia's 2012 edition. Here's a video showing some results and a link to the paper and source code:

link to the paper:
source code: which should build and run on windows and linux (a warning though, the code is pretty messy and there's room for optimisation).

Enjoy !