A collection of tricks, thoughts, ideas and solutions from a graphics programmer. This blog contains my experiences, tips and tricks, everyday problems and their solutions. This blog serves not only as my reference but also for the whole world at large.
Sunday, April 12, 2009
Wednesday, April 8, 2009
Screen space water on GPU
The reference for this was this wonderful article. The snapshot from the application is on the top. Here is how I implemented this on OpenGL. I created 3 textures and attached them to the three color attachments using the FBO. The first color attachement was for the 3D scene (the teapot and the plane). The second and third color attachments were for the water simulation. Basically I have simply converted the main code given in the article. See it for details in this regard. In the display function, first the scene is rendered and then the water simulation is rendered by ping pongging btw color attachment 1 and 2. The complete fragment shader for water is given below
fragment_out fragment_water( frag_vertex IN,
uniform sampler2D currentMap,
uniform sampler2D prevMap)
{
fragment_out OUT;
float4 smoothed;
float4 prev = tex2D(prevMap, IN.UV);
smoothed = tex2D(currentMap, IN.UV + float2(s.x, 0));
smoothed += tex2D(currentMap, IN.UV + float2(-s.x,0));
smoothed += tex2D(currentMap, IN.UV + float2(0, s.y));
smoothed += tex2D(currentMap, IN.UV + float2(0,-s.y));
smoothed /= 4.0;
OUT.Color = (smoothed*2.0 - prev)*damping;
return OUT;
}
After this, we have three rendered outputs the first one containing the rendering result, the second and third contain the water buffer. These textures are then used in another fragment shader to show the final output. The fragment shader is given below.
fragment_out fragment_main( frag_vertex IN,
uniform sampler2D buffer,
uniform sampler2D textureMap)
{
fragment_out OUT;
float Xoffset = tex2D(buffer, IN.UV+half2(-s.x, 0)) -
tex2D(buffer, IN.UV+half2(s.x, 0));
float Yoffset = tex2D(buffer, IN.UV+half2(0, -s.y)) -
tex2D(buffer, IN.UV+half2(0, s.y));
half4 t = tex2D(textureMap, IN.UV+half2(Xoffset,Yoffset));
OUT.Color = t+half4(Xoffset);
return OUT;
}
This gives the result shown in the image below.
Rest is just openGL bits and pieces.
Popular Posts
-
In this tutorial, I will show you how to create a simple box at a specific position and let it bounce under influence of gravity. We will...
-
Recently, for one of my projects, I had to learn about skeletal animation and GPU skinning. As always, I first went to google which gave me...
-
There has been a major revamp of the PhysX API from version 3. I will try to convert all of the existing tutorials into PhysX3 so here I go ...
-
I went to see the power of the NVIDIA PhysX sdk. So I downloaded the sdk from the PhysX developer site. While the sdk contains a lot of de...
-
In this tutorial, I will show you how to create a simple box at a specific position and let it bounce under influence of gravity. We will be...