Flowing Rivers
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
Friday or saturday, the code should be ready (together with a new movie)
- umpf
- umpf
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
new video is ready!
watch it at http://www.youtube.com/watch?v=TeSuNYvXAiA&hd=1
(sorry for the Germans, it uses the same music, which is blocked in Germany)
watch it at http://www.youtube.com/watch?v=TeSuNYvXAiA&hd=1
(sorry for the Germans, it uses the same music, which is blocked in Germany)
Last edited by umpf on Fri Oct 22, 2010 9:03 pm, edited 1 time in total.
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
Code: Select all
the boring part... the vertex shader (in this case for osgviewer)
//
// Vertex shader
varying vec3 Normal;
varying vec3 EyeDir;
varying vec2 texNormal0Coord;
varying vec2 texColorCoord;
varying vec2 texFlowCoord;
uniform float osg_FrameTime;
varying float myTime;
void main(void)
{
gl_Position = ftransform();
Normal = normalize(gl_NormalMatrix * gl_Normal);
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
EyeDir = pos.xyz;
texNormal0Coord = gl_MultiTexCoord1.xy;
texColorCoord = gl_MultiTexCoord3.xy;
texFlowCoord = gl_MultiTexCoord2.xy;
myTime = 0.01 * osg_FrameTime;
}
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
and the interesting part... the fragment shader
I will pack everything (including osg example) into a zip file and make it available for download from somewhere.
I'll post the link here. But for now, get inspired by the source below
advantages of this shader:
- flow in any direction
- waves can rotate with the flow direction
- waves can be scaled (in this demo the waves are smaller on the inside)
- no visible tiling (even for very large surfaces like open sea)
- no pulsing effect
This shader creates animated water by transforming normalmaps.
The scaling and rotation of the normalmaps is done per tile
and is constant per tile. Each tile can have its own parameters
for rotation, scaling, and speed of translation
To hide the seams between the tiles, all seams have another tile
centered on top of the seam. The opacity of the tiles decreases towards the
edge of the tiles, so the edge isn't visible at all.
Basically, all points have four tiles (A,B,C and D), mixed together
(although at the edges the contribution of a tile to this mix is
reduced to zero).
The mixing of the tiles each with different parameters gives a nice
animated look to the water. It is no longer just sliding in one direction, but
appears to move more like real water.
The resulting sum of normalmaps, is used to calculate the refraction of the clouds
in a cube map and can also be used for other nice effects. In this example the
colormap of the material under water is distorted to fake some kind of refraction
(for this example the water is a bit too transparent, but it shows this refraction
better)
A flowmap determines in the red and green channel the normalized direction of the
flow and in the blue channel wavelength.
The alpha channel is used for the transparency of the water. Near the edge, the
water becomes less deep and more transparent. Also near the edge, the waves tend
to be smaller, so the same alpha channel also scales the height of the waves.
Currently the wavelength is in its own channel (blue), but could be pre-multiplied
to the red and green channels. This makes this channel available for changing the
speed of the waves per tile.
you can do whatever you want with this shader except claiming rights
you may sell it, but you cannot prevent others from selling it, giving it away
or use it as they please.
Having said that, it would be nice if you gave me some credit for it, when you use
it.
movie at youtube: http://www.youtube.com/watch?v=TeSuNYvXAiA
Thanks to Bart Campman, Pjotr Svetachov and Martijn Kragtwijk for their help.
I will pack everything (including osg example) into a zip file and make it available for download from somewhere.
I'll post the link here. But for now, get inspired by the source below
advantages of this shader:
- flow in any direction
- waves can rotate with the flow direction
- waves can be scaled (in this demo the waves are smaller on the inside)
- no visible tiling (even for very large surfaces like open sea)
- no pulsing effect
This shader creates animated water by transforming normalmaps.
The scaling and rotation of the normalmaps is done per tile
and is constant per tile. Each tile can have its own parameters
for rotation, scaling, and speed of translation
To hide the seams between the tiles, all seams have another tile
centered on top of the seam. The opacity of the tiles decreases towards the
edge of the tiles, so the edge isn't visible at all.
Basically, all points have four tiles (A,B,C and D), mixed together
(although at the edges the contribution of a tile to this mix is
reduced to zero).
The mixing of the tiles each with different parameters gives a nice
animated look to the water. It is no longer just sliding in one direction, but
appears to move more like real water.
The resulting sum of normalmaps, is used to calculate the refraction of the clouds
in a cube map and can also be used for other nice effects. In this example the
colormap of the material under water is distorted to fake some kind of refraction
(for this example the water is a bit too transparent, but it shows this refraction
better)
A flowmap determines in the red and green channel the normalized direction of the
flow and in the blue channel wavelength.
The alpha channel is used for the transparency of the water. Near the edge, the
water becomes less deep and more transparent. Also near the edge, the waves tend
to be smaller, so the same alpha channel also scales the height of the waves.
Currently the wavelength is in its own channel (blue), but could be pre-multiplied
to the red and green channels. This makes this channel available for changing the
speed of the waves per tile.
you can do whatever you want with this shader except claiming rights
you may sell it, but you cannot prevent others from selling it, giving it away
or use it as they please.
Having said that, it would be nice if you gave me some credit for it, when you use
it.
movie at youtube: http://www.youtube.com/watch?v=TeSuNYvXAiA
Thanks to Bart Campman, Pjotr Svetachov and Martijn Kragtwijk for their help.
Code: Select all
//
// Fragment shader, Tiled Directional Flow
//
// (c) 2010 frans van hoesel, university of groningen
//
uniform sampler2D normalMap;
uniform sampler2D colorMap;
uniform sampler2D flowMap;
uniform samplerCube cubeMap;
uniform float osg_FrameTime;
uniform mat4 osg_ViewMatrixInverse;
varying vec3 Normal;
varying vec3 EyeDir;
varying vec2 texNormal0Coord;
varying vec2 texColorCoord;
varying vec2 texFlowCoord;
varying float myTime;
void main (void)
{
float texScale = 35.0;
float texScale2 = 10.0;
float myangle;
float transp;
vec3 myNormal;
vec2 mytexFlowCoord = texFlowCoord * texScale;
// ff is the factor that blends the tiles.
vec2 ff = abs(2*(frac(mytexFlowCoord)) - 1) -0.5;
// take a third power, to make the area with more or less equal contribution
// of more tile bigger
ff = 0.5-4*ff*ff*ff;
// ffscale is a scaling factor that compensates for the effect that
// adding normal vectors together tends to get them closer to the average normal
// which is a visible effect. For more or less random waves, this factor
// compensates for it
vec2 ffscale = sqrt(ff*ff + (1-ff)*(1-ff));
vec2 Tcoord = texNormal0Coord * texScale2;
// offset makes the water move
vec2 offset = vec2(myTime,0);
// I scale the texFlowCoord and floor the value to create the tiling
// This could have be replace by an extremely lo-res texture lookup
// using NEAREST pixel.
vec4 sample = texture2D( flowMap, floor(mytexFlowCoord)/ texScale);
// flowdir is supposed to go from -1 to 1 and the line below
// used to be sample.xy * 2.0 - 1.0, but saves a multiply by
// moving this factor two to the sample.b
vec2 flowdir = sample.xy -0.5;
// sample.b is used for the inverse length of the wave
// could be pre-multiplied in sample.xy, but this is easier for editing flowtexture
flowdir *= sample.b;
// build the rotation matrix that scales and rotates the complete tile
mat2 rotmat = mat2(flowdir.x, -flowdir.y, flowdir.y ,flowdir.x);
// this is the normal for tile A
vec2 NormalT0 = texture2D(normalMap, rotmat * Tcoord - offset).rg;
// for the next tile (B) I shift by half the tile size in the x-direction
sample = texture2D( flowMap, floor((mytexFlowCoord + vec2(0.5,0)))/ texScale );
flowdir = sample.b * (sample.xy - 0.5);
rotmat = mat2(flowdir.x, -flowdir.y, flowdir.y ,flowdir.x);
// and the normal for tile B...
// multiply the offset by some number close to 1 to give it a different speed
// The result is that after blending the water starts to animate and look
// realistic, instead of just sliding in some direction.
// This is also why I took the third power of ff above, so the area where the
// water animates is as big as possible
// adding a small arbitrary constant isn't really needed, but helps to show
// a bit less tiling in the beginning of the program. After a few seconds, the
// tiling cannot be seen anymore so this constant could be removed.
// For the quick demo I leave them in. In a simulation that keeps running for
// some time, you could just as well remove these small constant offsets
vec2 NormalT1 = texture2D(normalMap, rotmat * Tcoord - offset*1.06+0.62).rg ;
// blend them together using the ff factor
// use ff.x because this tile is shifted in the x-direction
vec2 NormalTAB = ff.x * NormalT0 + (1-ff.x) * NormalT1;
// the scaling of NormalTab and NormalTCD is moved to a single scale of
// NormalT later in the program, which is mathematically identical to
// NormalTAB = (NormalTAB - 0.5) / ffscale.x + 0.5;
// tile C is shifted in the y-direction
sample = texture2D( flowMap, floor((mytexFlowCoord + vec2(0.0,0.5)))/ texScale );
flowdir = sample.b * (sample.xy - 0.5);
rotmat = mat2(flowdir.x, -flowdir.y, flowdir.y ,flowdir.x);
NormalT0 = texture2D(normalMap, rotmat * Tcoord - offset*1.33+0.27).rg;
// tile D is shifted in both x- and y-direction
sample = texture2D( flowMap, floor((mytexFlowCoord + vec2(0.5,0.5)))/ texScale );
flowdir = sample.b * (sample.xy - 0.5);
rotmat = mat2(flowdir.x, -flowdir.y, flowdir.y ,flowdir.x);
NormalT1 = texture2D(normalMap, rotmat * Tcoord - offset*1.24).rg ;
vec2 NormalTCD = ff.x * NormalT0 + (1-ff.x) * NormalT1;
// NormalTCD = (NormalTCD - 0.5) / ffscale.x + 0.5;
// now blend the two values together
vec2 NormalT = ff.y * NormalTAB + (1-ff.y) * NormalTCD;
// this line below used to be here for scaling the result
//NormalT = (NormalT - 0.5) / ffscale.y + 0.5;
// below the new, direct scaling of NormalT
NormalT = (NormalT - 0.5) / (ffscale.y * ffscale.x);
// scaling by 0.3 is arbritrary, and could be done by just
// changing the values in the normal map
// without this factor, the waves look very strong
NormalT *= 0.3;
// to make the water more transparent
transp = texture2D( flowMap, texFlowCoord ).a;
// and scale the normals with the transparency
NormalT *= transp*transp;
// assume normal of plane is 0,0,1 and produce the normalized sum of adding NormalT to it
myNormal = vec3(NormalT,sqrt(1-NormalT.x*NormalT.x - NormalT.y*NormalT.y));
vec3 myEye = vec3(osg_ViewMatrixInverse*vec4(EyeDir,0));
vec3 reflectDir = reflect(myEye, myNormal);
vec3 envColor = vec3 (textureCube(cubeMap, -reflectDir));
// very ugly version of fresnel effect
// but it gives a nice transparent water, but not too transparent
myangle = dot(myNormal,normalize(myEye));
myangle = 0.95-0.6*myangle*myangle;
// blend in the color of the plane below the water
// add in a little distortion of the colormap for the effect of a refracted
// view of the image below the surface.
// (this isn't really tested, just a last minute addition
// and perhaps should be coded differently
vec3 base = vec3 (texture2D(colorMap,texColorCoord + myNormal/texScale2*0.07*transp));
gl_FragColor = vec4 (mix(base,envColor,myangle*transp),1.0 );
// note that smaller waves appear to move slower than bigger waves
// one could use the tiles and give each tile a different speed if that
// is what you want
}
- bernie
- Gnoblar
- Posts: 3
- Joined: Sun Oct 03, 2010 2:38 pm
Re: Flowing Rivers
Thanks,that is just fantastic.
Last edited by bernie on Fri Oct 22, 2010 3:28 pm, edited 1 time in total.
- jacmoe
- OGRE Retired Moderator
- Posts: 20570
- Joined: Thu Jan 22, 2004 10:13 am
- Location: Denmark
- x 179
- Contact:
Re: Flowing Rivers
Let's hand the torch to the OP, shall we?
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
-
- Google Summer of Code Student
- Posts: 1005
- Joined: Wed Jan 08, 2003 9:15 pm
- Location: Lyon, France
- x 49
- Contact:
Re: Flowing Rivers
That's great!
It's a bit different from my technique because you use flowmap, but it's a cool and good looking implementation! Especially the fact that you have no pulse effect and the seamless normal mapping
It's a bit different from my technique because you use flowmap, but it's a cool and good looking implementation! Especially the fact that you have no pulse effect and the seamless normal mapping
What do you mean? (if the "OP" is myself )Let's hand the torch to the OP, shall we?
- jacmoe
- OGRE Retired Moderator
- Posts: 20570
- Joined: Thu Jan 22, 2004 10:13 am
- Location: Denmark
- x 179
- Contact:
Re: Flowing Rivers
Umpf stole your thunder - now you take it back.
Two really cool implementations in one topic - that's awesome!
Two really cool implementations in one topic - that's awesome!
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
I do use a flowmap, because I need it in a harbor, with open sea. In the harbor the waves can have very different directions.Crashy wrote:That's great!
It's a bit different from my technique because you use flowmap, but it's a cool and good looking implementation! Especially the fact that you have no pulse effect and the seamless normal mapping
But if you have a landscape, and the water flows simply downhill, you could easily calculate the flow from the normal vectors of the landscape. Once you have the flow, you can use this technique to make it look really good
Last edited by umpf on Fri Oct 22, 2010 5:51 pm, edited 2 times in total.
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
a visual version of 'how to go with the flow' is at http://www.youtube.com/watch?v=wdcvPegJ1lw&hd=1
(no sound, so the Germans are not blocked by MGM)
(no sound, so the Germans are not blocked by MGM)
Last edited by umpf on Fri Oct 22, 2010 9:02 pm, edited 1 time in total.
- jacmoe
- OGRE Retired Moderator
- Posts: 20570
- Joined: Thu Jan 22, 2004 10:13 am
- Location: Denmark
- x 179
- Contact:
Re: Flowing Rivers
That video is just too awesome not to be inlined!
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
- aguru
- Goblin
- Posts: 236
- Joined: Tue Feb 26, 2008 5:48 pm
- x 3
Re: Flowing Rivers
aaah, this is nice!
-
- Halfling
- Posts: 77
- Joined: Thu Jan 08, 2009 2:03 am
- x 1
Re: Flowing Rivers
This is truly amazing!
If I understand correctly, the riverbed is not modeled but rather a texture on a plane?
If I understand correctly, the riverbed is not modeled but rather a texture on a plane?
The Key to Magic -- Book One: ORPHAN
An epic fantasy by H. Jonas Rhynedahll available on Kindle.
The Key to Magic
An epic fantasy by H. Jonas Rhynedahll available on Kindle.
The Key to Magic
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
yes that is true. The whole scene is just one square. Not that it needs to be, it is just me being lazy and not modeling any mountains, riverbed or whatever. The whole thing is a bit artificial, but made this way to show the possibilities of the algorithm.Rhynedahll wrote:This is truly amazing!
If I understand correctly, the riverbed is not modeled but rather a texture on a plane?
-
- Halfling
- Posts: 77
- Joined: Thu Jan 08, 2009 2:03 am
- x 1
Re: Flowing Rivers
Another question:
How does it look up close? Would it be suitable, for instance, for a 3d game where characters are close to the ground?
Or is it best suited to flight sims and the like?
How does it look up close? Would it be suitable, for instance, for a 3d game where characters are close to the ground?
Or is it best suited to flight sims and the like?
The Key to Magic -- Book One: ORPHAN
An epic fantasy by H. Jonas Rhynedahll available on Kindle.
The Key to Magic
An epic fantasy by H. Jonas Rhynedahll available on Kindle.
The Key to Magic
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
I think it looks great up close. It is still flat of course. Tomorrow or the day after tomorrow I will release the complete data. I'll try to include a tiny bit of osg, but if you want to be sure you can see it immediately, make sure you have installed the osg binaries http://www.openscenegraph.org/projects/ ... /Downloads. With that comes a bin directory with a demo called osgviewer. I if you can run that, you should be able to zoom in as much as you likeRhynedahll wrote:Another question:
How does it look up close? Would it be suitable, for instance, for a 3d game where characters are close to the ground?
Or is it best suited to flight sims and the like?
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
I know I'm going to disappoint you, but I'm not using ogre at all. Just osg. So if anyone wants to make a nice river in Ogre, feel free to adapt the shader so it works with ogre. That should be easy enough, I asume.JustBoo wrote: I'm curios. I'm familiar with OSG. Are you saying that you are rendering with Ogre, but you are using OSG as the underlying scenegraph that drives the rendering? If so, could you explain that? If not, then I don't understand how you would be using OSG. Could you explain that?
-
- Halfling
- Posts: 77
- Joined: Thu Jan 08, 2009 2:03 am
- x 1
Re: Flowing Rivers
Lol!umpf wrote: I'm I know I'm going to disappoint you, but I'm not using ogre at all. Just osg. So if anyone wants to make a nice river in Ogre, feel free to adapt the shader so it works with ogre. That should be easy enough, I asume.
It's still nice work, but certainly dissapointing. But, no worries from me!
The Key to Magic -- Book One: ORPHAN
An epic fantasy by H. Jonas Rhynedahll available on Kindle.
The Key to Magic
An epic fantasy by H. Jonas Rhynedahll available on Kindle.
The Key to Magic
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
Finally , the complete source including images can be downloaded from our website http://www.rug.nl/cit/hpcv, but more directly from http://www.rug.nl/cit/hpcv/publications/watershader. This should get you going and enable you to write your own shader for use with Ogre.
Instructions are in the readme file.
Instructions are in the readme file.
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
now lets wait and see if Crashy likes it too and tries to build his river using my shader. I would love to see it. He never said he would do so, but anyway it would be cool to see the shader being used outside the purpose I wrote it for.
-
- Google Summer of Code Student
- Posts: 1005
- Joined: Wed Jan 08, 2003 9:15 pm
- Location: Lyon, France
- x 49
- Contact:
Re: Flowing Rivers
Your shader is really nice, I think I may grab some little things to improve mine. But reminds that rivers in my game are made in the terrain shader, so there are a lot of instructions for the texture splatting and I cannot add a complex implementation for the river stuff. As it is for an aircraft-shooting game I do not need a top notch quality because most of time the player will be far from rivers. But I'm really interested in the normal mapping without tiling you've done
I'm going to investigate this in the next days, stay tuned
I'm going to investigate this in the next days, stay tuned
-
- Gnoblar
- Posts: 17
- Joined: Tue Oct 12, 2010 7:08 pm
Re: Flowing Rivers
if you are going to borrow little things, I suggest you look at my scaling (ffscale in the sourcecode) as this prevents the pulsing effect... at least I assume it will in you case as well.Crashy wrote:Your shader is really nice, I think I may grab some little things to improve mine.
- tuan kuranes
- OGRE Retired Moderator
- Posts: 2653
- Joined: Wed Sep 24, 2003 8:07 am
- Location: Haute Garonne, France
- x 4
- Contact:
Re: Flowing Rivers
You might be interested in GPU-based water flow simulator (binary+source+Dx9)
- mikeInside
- Kobold
- Posts: 37
- Joined: Thu Apr 26, 2007 5:46 pm
- Location: Sydney, Australia
- Contact:
Re: Flowing Rivers
tuan kuranes wrote:You might be interested in GPU-based water flow simulator (binary+source+Dx9)
Oh wow I've been periodically checking in on that topic for years waiting for him to post the explanation, great find Tuan!
It's fantastic that we now have two really interesting solutions to the problem. I think DavlexDesign has also been working on flowing rivers, so the count may increase once again real soon.
Big thanks Umpf for your hard work And looking forward to seeing the results of your experimentation Crashy.
-
- Gnoblar
- Posts: 2
- Joined: Sun Jul 04, 2010 1:53 pm
Re: Flowing Rivers
Thank you for you code. But I want to know only the .osg and shader is enough? You code contain two .osg, what is another?umpf wrote:Friday or saturday, the code should be ready (together with a new movie)
- umpf
I want to do it in ogre, How to do just like you said it's easy? The terrain is from ?What is the .osg file corresponding to in OGRE? Please give an hint,thanks!