Need Help With Water

BlitzMax Forums/MiniB3D Module/Need Help With Water

FBEpyon(Posted 2015) [#1]
Hello,

I was hoping someone can help me with getting a water shader..

Here is a picture of my project so far using perlin noise to create random island terrains, and was looking online for information on water shaders and I couldn't find anything.



Any help would be great!!


markcw(Posted 2015) [#2]
I have just added a water shader to Openb3d examples, sorry no picture.

It's pretty simple, no clever stuff like caustics, just a specular cubemap and water texture with uv scrolling and mesh wave deformation.

One issue is reflections, they are really big for anything in the water so those need hidden and anything directly above the surface needs moved up a bit before rendering. Also, I tried diffuse cubemap but it doesn't seem to work at all on flat surfaces.


markcw(Posted 2015) [#3]
Just updated this with a second version with pixel lighting. The first one just ignores lighting, just in case someone wants that.


FBEpyon(Posted 2015) [#4]
Thanks,

I will look at I as soon as I get a chance to get back on to my computer. I was having problems with MinGW so I'm in the process of fixing that now.


markcw(Posted 2015) [#5]
I've updated my sl_water.bmx example again with stencil reflections which looks much better. Now cubemapping is just used for the sky reflection.


FBEpyon(Posted 2015) [#6]
I worked with the sl_water, and it ended up be to much for trying to keep this working on low end hardware.

Soooo I came up with this instead :



Thanks for all the help, and let me know what you think...

BTW this is all done in OpenB3d using shaders for all the texturing and water movement (which you can't see..)


Hezkore(Posted 2015) [#7]
I was experimenting with water and an isometric heightmap a little while ago and came up with something I was almost happy with heh.
I've not used any shaders for this and it runs quite well on lower end machines.





It sparkles a bit as it moves heh.


markcw(Posted 2015) [#8]
FBEpyon, looks nice, not top quality but quite passable if it matches the graphical style of your game.

It looks like you may be doing a caustic effect, are you? The simplest way is probably an animated texture, but a bit harder and probably better is to multitexture with two similar water textures and then fade in from one to the other, which could be done by a shader. I'll see if I can add that to sl_water.bmx.

Hezkore, looks really good. It looks almost bumpmapped, which is another good idea for a nice water shader. Are you using an animated texture? Can you explain how you achieved that?


Hezkore(Posted 2015) [#9]
It was meant to used as ponds and small water holes in the terrain.
So I wanted very calm and still water, which means it's got no waves or anything like that.
It's also made to be used with an orthographic projection, so this might not be the perfect water for every situation.
I'm also drawing some "fake" sun to the screen to lighten it all up a bit.

It feels like I'm giving away trade secrets here hehe, but it's just water and it's not that special.
So here's the source code to a quickly thrown together demo of it - water_example.zip
It's pretty messy and has a lot of stuff it doesn't need in this situation, but you get the basic idea.
Just some texture blending and a few planes layered above each other.


markcw(Posted 2015) [#10]
Thanks Hezkore! Very kind of you to share your textures and source. I'm still trying to work out what is going on, it seems quite complex. Shows you don't always need shaders though.

Also, I noticed your comment about jpg/png loader so I double checked this and Openb3d doesn't import either jpg, png or even bmp loaders whereas Minib3d does. I think I should add them though as the wrapper is meant to behave as much like Minib3d as it can.


angros47(Posted 2015) [#11]
@munch
What do you mean? OpenB3D can open jpg/png/bmp.

@Hezkore: if you are going to create ponds, you could use a stencil mesh for thems: you can scale the camera with a factor of -1, and it will render a mirror image; by combining the two effects, you could have reflections on water (It's a way to replicate the "CreateMirror" command of Blitz3D, that is not available in MiniB3D or OpenB3D)


markcw(Posted 2015) [#12]
What I meant was, as in Hezkore's demo, when using the Max2d commands you need to import the image loaders or it will error out.

So I guess there's no CreateMirror in Minib3d because you can't really automate that but Blitz3d could as it used a built-in Dx7 render function.


angros47(Posted 2015) [#13]
What I meant was, as in Hezkore's demo, when using the Max2d commands you need to import the image loaders or it will error out.


Uh, ok. That's because OpenB3D has its own internal loader (stbi image loader), to be able to work with other languages, too, while MiniB3D uses the loader provided with BlitzMax. If you use Max2D with MiniB3D, the loader code is already imported, if you use OpenB3D, it is not (and Max2D cannot access the loader included in OpenB3D)


So I guess there's no CreateMirror in Minib3d because you can't really automate that but Blitz3d could as it used a built-in Dx7 render function.



Actually, it could be automated: you just need to reverse camera view matrix and perform another render; but it could be easily done with current version (to reverse camera matrix, just use ScaleEntity: Blitz3D ignores scaling operations on cameras, while MiniB3D and OpenB3D allow that).

So, simulating a Blitz3D mirror is not difficult, and can be done with two or three commands (two "ScaleEntity" and one extra "RenderWorld")... it's not even worth adding a new command just for that.

Also, CreateMirror has too many limitations:

- it works only for horizontal mirrors (it's ok for water and ice, not for wall mirrors), while most mirrors are vertical
- the mirror size is infinite (you'd need stencils to restrict it, and in Blitz3D stencils are not available): it's ok for sea, or for a lake that is in the lowest place of a scene (the terrain will hide the rest of the mirror) but it's bad if I just want a puddle, or a sheet of ice, or a pool that are above the ground level
- the mirror works on both sides, and there is no clipping: everything that is above the mirror is reflected below it, but everything is below is also reflected above, so it's not possible to have fishes, or a sea bed, because you'd see it reversed in the air (imagine: you are on a boat, and you see a shoal of fishes flying upside down in the air)

These limits restricts the use of CreateMirror to iced landscapes, and not much more (in fact, even in Blitz3D, reflections were usually achieved with cube mapping, not with CreateMirror); with a wise use of stencils, in OpenB3D a better mirror could be achieved


Hezkore(Posted 2015) [#14]
I tried all the tricks to make water reflections, but in the end I found none that worked well in all situations.
One problem was that the world/heightmap was very optimized for the ortho projection, it had no surfaces at the back or bottom, so rendering it from any other point of view would make it invisible (and flip mesh would't help).
At one point I even generated a custom reflections mesh that would only be seen in the stencil, but it took a lot of extra time to generate and since the heightmap would change ingame it needed to be fast.

In a different situation I could have used reflections (and I'd love to see that), but for the isometric heightmap demo shown above I decided that it was best to leave them out.


angros47(Posted 2015) [#15]
Is the world a terrain entity (made with CreateTerrain, or LoadTerrain)? If so, you can't use FlipMesh because it's not a mesh, but you can still disable backface culling using EntityFX ent, 16.


Hezkore(Posted 2015) [#16]
Neither, it's created with my own CreateIsoTerrian(), returned as a mesh.
I can flip it (disabling backface culling works too) but it doesn't look correct in the end.

It doesn't really matter anymore though as I've changed the entire thing and started a new project.


markcw(Posted 2015) [#17]
(and Max2D cannot access the loader included in OpenB3D)

Yes, but we can use Pixmap with TexToBuffer/BufferToTex commands which is enough.

I tried the ScaleEntity trick to simulate CreateMirror and got it working, then I realized doing that makes it more complex than it needs to be. I had to render twice, use a second camera, hide/show the mesh and their copies (I had to use copies or else use ScaleEntity on each mesh because camera rotation caused meshes to move) all to achieve an effect that can be done just by positioning inverted copies below the ground/plane. So I can see why CreateMirror was never added to Minib3d! I have uploaded a mirror example for anyone who is looking for a simple and fast alternative to the stencil example (my framerate was twice as fast).


markcw(Posted 2015) [#18]
Ok, I've deleted the mirror example and just added the ability to enable/disable stenciling in the stencil example.