Page 1 of 1

Another Water Simulation

Posted: Mon Sep 21, 2009 4:37 pm
by andres
hi guys.
This is the ocean shader i've made to my project named Tikal, an RTS based in the Mayan civilization


UPDATED: Sample Code and Windows/Linux Binaries available at
http://www.andresjesse.com

Direct Links:
http://andresjesse.com/files/Water_Sample.tar.gz
http://andresjesse.com/files/Water_Sample.zip




Image

Image

more details : andresjesse.spaces.live.com/blog/cns!8F7523C41063CBC6!242.entry
or
http://www.andresjesse.com


There is an texture layer equals to the terrain heightmal, then the shader sets the transparency according the height of the land, then the border of the ocean makes transparent.

Edit: I'm working on my website, for now i've uploaded images in imageshark. :wink:

Posted: Mon Sep 21, 2009 6:40 pm
by Lil Margin
all your links seems down :S ?

Posted: Mon Sep 21, 2009 9:13 pm
by andrei25ni
Lil Margin wrote:all your links seems down :S ?
You need to have a Windows Live account to see them.

@andres, maybe you can upload them someplace else (imageshack etc.)

on-topic: the ocean shader looks great :)

Posted: Tue Sep 22, 2009 8:18 am
by JP
Nice water, not very ocean looking though!

Posted: Tue Sep 22, 2009 9:13 am
by m_krzywy
Looking nice. Wish to use it in my project :D

Posted: Wed Sep 23, 2009 10:54 pm
by andres
m_krzywy wrote:Looking nice. Wish to use it in my project :D
yeah, of course, here are the GLSL programs:

Code: Select all

//=========================================================================//
// Ocean.frag                                                              //
// Project Tikal                                                           //
// Ocean Fragment Shader v1.0, september 2009                              //
// reflection funcion is based in the SIO2 demo from sio2.g0dsoft.com      //
// everything else by Andres J. Porfirio ... andresjesse.spaces.live.com   //
//=========================================================================//

//!alphaMap for the ocean (terrain heighmap)
uniform sampler2D t0;
//!reflection texture
uniform sampler2D t1;
//!water normalmap

uniform sampler2D NormalMap;

varying vec4 waterpos;

varying vec2 bumpCoord0;

varying vec2 originalCoord;



vec4 reflection()

{

	vec4 projCoord = waterpos / waterpos.w;

	projCoord += vec4(1.0);

	projCoord *= 0.5;

	projCoord = clamp(projCoord, 0.001, 0.999);
	
	projCoord.y = 1.0 - projCoord.y;
	
	vec4 tnmap = texture2D(NormalMap, bumpCoord0);

	return texture2D(t1, vec2(projCoord) + tnmap.xz*0.15 - vec2(0.08,0.15));
}

void main(void)

{

    vec4 alphaMap = texture2D(t0, originalCoord);

    vec4 ref=reflection()+vec4(0,0,0,1);
    

    gl_FragColor = ref * vec4(1,1,1,(0.12-alphaMap.b)*6);

}

Code: Select all

//=========================================================//
// Ocean.vert                                              //
// Project Tikal                                           //
// Ocean Vertex Shader v1.0, september 2009                //
// by Andres J. Porfirio ... andresjesse.spaces.live.com   //
//=========================================================//


//!device->getTimer()->getTime()/1000.0f;
uniform float waterTime;


varying vec4 waterpos;

varying vec2 bumpCoord0;

varying vec2 originalCoord;

void main(void)

{
	waterpos = ftransform();


	originalCoord = gl_MultiTexCoord0;

	bumpCoord0.xy = gl_MultiTexCoord0.xy * 10 + waterTime * vec2(-0.01,-0.05);
	
	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}

Posted: Sun Oct 04, 2009 3:25 pm
by EvilAlex
Hi, andres!
Thanks very much for your code!
It's the first water shader I found to actually work with IrrLicht without having to... well... you know, rewrite the whole shader!

However I've got a problem. It's a rather theoretical problem, and not specifically a problem with your shader:
I don't know how to get a proper reflection map (texture).
Basically, as I understand it, it just a scene rendered upside-down into an RTT-texture.
But then, how do I deal out all those areas that shouldn't be on the reflection, like things below the water surface? I tried to use "setClipplane" and stuff, but I guess I've got issues in understanding how to set it up, or there is a bug somewhere, e.t.c it just doesn't work for me. Well, in fact it does, but it only clips skybox to a certain amount, and not anything else, it doesn't matter what I try.

So can you please, if it's not some kinda "trade secret", post a part of your code, which gets reflections? :oops:
So I can both get it all to work and finally understand something about how to get proper reflection-maps in IrrLicht. :oops:

Thanks in advance! :lol:

Posted: Sun Oct 04, 2009 3:31 pm
by devsh
reflect the camera position and target over the water plane

then make a camera from that

set it as active

set a user clipping plane which must be same as water plane

render scene into RTT

set back render target to 0

Posted: Sun Oct 04, 2009 4:11 pm
by EvilAlex
Thanks, devsh.

I did as you said, (except for the part about a clip-plane, since it only produces weird skybox clipping), and the reflection seems to work almost as it should. With a little synchronization bug, but I'll fix it, it's ok.

However, the problem with that clip plane... I reckon it has something to do with the devil! :twisted:
It seems so d*mn obvious: the vector, the normal, the enable\disable by index thing, but it doesn't do anything as intended -- for some h**lish reason!
Some guy with a Morpheus on his avatar (can't remember his nick) posted a thread on this forum a while ago, about a serious bug regrading clipping planes and OpenGL in IrrLicht. It was "when I set it up in D3d it clips things properly, but when I do the same in OGL it clips every single node at the same coords it should do world" kinda stuff.
It was so long ago, I thought the bug should've been fixed in 1.6, but either it haven't, or I don't get something obvious.

Code: Select all

driver->setClipPlane(0,plane3df(0,0,0,0,1,0),true); //This seems to clip at least the skybox thing.
...but...

Code: Select all

driver->setClipPlane(0,plane3df(0,60,0,0,1,0),true); //This does strange stuff. 0,60,0 is my water node position.
...and then even...

Code: Select all

driver->setClipPlane(0,plane3df(0,60,0,0,61,0),true); //This doesn't work... (Ooops, I said it does? Pardon me.)
I tried negative normals for both my previous code, and the method you said to use, it still does nothing as expected.

Posted: Mon Oct 05, 2009 1:57 pm
by andres
EvilAlex wrote: So can you please, if it's not some kinda "trade secret", post a part of your code, which gets reflections? :oops:
So I can both get it all to work and finally understand something about how to get proper reflection-maps in IrrLicht. :oops:
Thanks in advance! :lol:
The code to get reflection texture is same as the Sio2 sample. sorry about the miss of comments in the code, i have not had time to do that yet.

Code: Select all

    //First store the orginal camera...
    IVideoDriver* driver=device->getVideoDriver();
    scene::ICameraSceneNode *camera = smgr->getActiveCamera();
    
    RTTCamera->setFarValue(camera->getFarValue());

    core::vector3df Position=ocean->getPosition() + vector3df(0,1.8,0);

    core::vector3df campos = camera->getPosition();
    if (campos.Y >= Position.Y)
    {
        RTTCamera->setPosition(core::vector3df(campos.X, 2* Position.Y - campos.Y, campos.Z));
        core::vector3df target = camera->getTarget() - campos;
        target.normalize();
        target.Y *= -1;

        RTTCamera->setTarget(RTTCamera->getPosition() + target*20000);
        RTTCamera->setUpVector(camera->getUpVector());
    }
    else
    {
        RTTCamera->setPosition(camera->getPosition());

        core::vector3df target = camera->getTarget() - camera->getPosition();
        target.normalize();
        target *= 200000;
        RTTCamera->setTarget(RTTCamera->getPosition() + target);
        RTTCamera->setUpVector(camera->getUpVector());
    }

    sky->setPosition(RTTCamera->getPosition());

    driver->setRenderTarget(oceanReflectionTexture, true, true, video::SColor(255,255,255,255));
    smgr->setActiveCamera(RTTCamera);
    ocean->setVisible(false);
    terrain->setVisible(false);

    smgr->drawAll();

    driver->setRenderTarget(0,false,false);//sets the render to real screen

    terrain->setVisible(true);
    ocean->setVisible(true);
    smgr->setActiveCamera(camera);

    sky->setPosition(camera->getPosition());

Posted: Wed Oct 07, 2009 1:01 pm
by EvilAlex
Thanks!!! :D

Also no clipping planes, I see. I guess I can leave my own code in place, then.