May 8, 2012

projected grid in vertex shader

I am in the middle of making a complete water/underwater shading system in GLSL. Water surface wave displacement is now the last thing to deal with and "projected grid" concept is something I wanted to try. You can read about it in this cool article HERE. But one thing I did not found is an approach to do it completely in a vertex shader, which might speed and simplify things a lot.

As an exercise I reinvented one myself.

What it does is scales the our grid to view frustum space coordinates and projects it to specified plane in the world.
The easy thing is that frustum-space (untransformed) coordinates for our water plane is already provided as gl_Vertex. The value range is between -1.0 to 1.0 and values outside of this range correspond to points which are not in viewing frustum.
So in X axis -1.0 is left and 1.0 is right edge of the screen, Y - upper and lower edge, but for Z -1.0 is near plane and 1.0 is far plane. The tricky part is that while X and Y values are linear, Z values are exponential - more densely packed at near plane.
Next part is to create a virtual plane to project our grid to. We only need the grid Z axis to be projected as X and Y are already at needed position - at screen edges. To do so, we need to create world position. I transformed texture coordinates of grid with camera transformation matrices and then with line-plane intersection I got the coordinates of ground plane. And finally we create a depth from ground position to apply to Z coordinate of the grid. As Z is exponential, I found THIS very useful to convert linear depth to exponential.

screenshots (not an eye candy yet):



clamped size:

with a displacement map:

There is yet a lot of work ahead, but I felt I should share this. Maybe someone finds this useful.

get the vertex shader HERE

edit: I found a technique by Eric Bruneton, which is much more useful easier and faster than mine, hehe. Still it was a nice exercise and I found out bunch of new stuff while doing this.