Rivers

Hi,

I want to add rivers to a scene, but I’m unsure abouth how to implement them correctly. I looked at the examples for simple and post-processor water, but they only seem to be suitable for lakes or seas.
I want to make a river that can flow around bends, witouth visible seams in the waves, and it should look like it’s flowing.

What would be the best way to do this?

many thanks in advance.

As far as I know, you can add any non-trivial mesh to simple water processor and it will work correctly. It just has to be on single level. Unfortunately, waves will no behave correctly near the shores, but it might be good first approximation.

If I would use the simple water processor, then all the waves would go in the same direction, so in bends, a part of the river would flow straight into the bank. And if I would use multiple meshes to give each part it’s own direction, then there would be seams visible in some waves.

@beniboy said: If I would use the simple water processor, then all the waves would go in the same direction, so in bends, a part of the river would flow straight into the bank. And if I would use multiple meshes to give each part it's own direction, then there would be seams visible in some waves.

I think he sort of said that.

@abies said:Unfortunately, waves will no behave correctly near the shores, but it might be good first approximation.

This is an extremely hard thing to do. There is no built in support for it. You will have to figure out a solution for yourself since it is basically an unsolved problem and/or will depend on how you are doing the rest of your engine.

Rivers is a big subject. Take a look at forester, it’s a now-abandoned plugin where a guy was working on flowing water, etc.

<cite>@beniboy said:</cite> If I would use the simple water processor, then all the waves would go in the same direction, so in bends, a part of the river would flow straight into the bank. And if I would use multiple meshes to give each part it's own direction, then there would be seams visible in some waves.

If it is just about the wave direction, without worrying about banks etc, I suppose it should be possible. As far as I understand, water mesh just has one big texture coords aligned to world space. By triangulating your river geometry properly and moving texture coords down the flow instead of just based on mesh coordinates, you should probably get reasonable waves without even modifying the shaders.

Applying the water material of the simple water processor worked, but it seems to be a full 100% reflective. It looks all right from a distance, but when you get close, it looks weird because it has absolutely no transparency. I tried changing the depth and the transparency, but it keeped looking exactely the same.

Does anyone know how I can make it a bit more realistic? I especially want to be able to see at least a part of the underwater ground. Otherwise, the water just looks like a waving mirror.

In case it might help: this is how I create the water (mostly copied from the tutorial)
[java]SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
waterProcessor.setReflectionScene(spat); //spat = the spatial which contains the world model, the skybox, etc.

    // we set the water plane
    Vector3f waterLocation=new Vector3f(0,-0.021226883f,0);
    waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
    Main.app.getViewPort().addProcessor(waterProcessor);

    // we set wave properties
    waterProcessor.setWaterDepth(400);         // transparency of water
    waterProcessor.setDistortionScale(0.1f); // strength of waves
    waterProcessor.setWaveSpeed(-0.1f);       // speed of waves
    waterProcessor.setWaterTransparency(0.5f);
    waterProcessor.setWaterColor(ColorRGBA.Blue);
    water.setMaterial(waterProcessor.getMaterial());
    water.setQueueBucket(Bucket.Translucent);
    rootNode.attachChild(water);[/java] <a href="http://s1.postimg.org/gnjc1a94v/Untitled.png"><img src="http://s1.postimg.org/gnjc1a94v/Untitled.png" alt="" /></a>

I think that you have to use different plane with setPlane. I’m using two-vector setter, with something like setPlane(new Vector3f(0,-0.02,0), Vector3f.UNIT_Y).
Also, not sure if you have to put it into translucent bucket - try without it.

I now use this to set the plane:
[java] Plane p = new Plane();
p.setOriginNormal(new Vector3f(0,-0.021226883f,0), Vector3f.UNIT_Y);
waterProcessor.setPlane§;[/java] and it still gives the same results, also when the bucket isn’t set to translucent.

Set waterProcessor.setDebug(true);
and check what the debug screen are showing.

This is what it’s showing:

It seems to be quite simular to what the debug view of TestSceneWater is giving, wile the water of that example has some transparacy.

Hmmm, hard to say… are normals for your water geometry proper? Alternatively, can you see if things will work properly with just sample Quad as water geometry and everything same as you have currently?

With the quad, it works better. But the normals of the water mesh should be correct, because if I apply a textured material to it, it shows up normally. Is there an other way to check the normals?

Textures don’t really show normals that well, they would show texcoords.
Regarding normals - there should be no magic about them, just slap 0,1,0 everywhere.

With the showNormals material, it shows up as green. Is that correct?

Appaerntely, I had to rotate it 90° around the x-axis before converting it to .j3o, then rotate it 90° again. That fixed the transparency.
But now I have an other problem with the transparency. The water is supposed to be transparent around the camera for a realistic water effect, but instead, it’s transparent around a certain point. I tried setting the X and Z coordinates of the orgin of the water plane to the X and Z coordinates of the player, but it didn’t work.
This is a screenshot of how it looks:

@beniboy said: With the quad, it works better. But the normals of the water mesh should be correct, because if I apply a textured material to it, it shows up normally. Is there an other way to check the normals?

To me, all of your problems look normal related. Normals aren’t used for normal texture mapping so that wouldn’t matter. That are only used for lighting-related stuff and bumpmaps and normal maps.

Can you show us the code you use to build your water geometry? It seems like your normals are exactly 90 degrees off. Like you did 0,0,1 for up instead of 0,1,0 for up.

Edit: because in your screen shot the refraction seems exactly backwards.

This is the code I use for it:
[java]Spatial spat = assetManager.loadModel(“Models/Krijt/Krijt.j3o”);
Spatial water = ((Node) spat).getChild(“Rivier”);
((Node) spat).detachChild(water);
waterProcessor.setReflectionScene(spat);
waterLocation = new Vector3f(0, 0.56830215f, 0);
Plane p = new Plane();
p.setOriginNormal(waterLocation, Vector3f.UNIT_Y);
waterProcessor.setPlane§;
Main.app.getViewPort().addProcessor(waterProcessor);
water.setMaterial(waterProcessor.getMaterial());
water.setShadowMode(ShadowMode.Receive);
water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
rootNode.attachChild(water);[/java]
But I’ve checked the normals by applying the showNormals material to both the quad of the example and the water geometry, and they both showed up as purple.

If you made your geometry so that you don’t have to do this…
water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));

…I wonder if the problem would go away. If so then this could be a bug in how the normals are handled in the water processor. Without actually looking at the code, I can think of a few things that could cause this if some assumptions were made.

If I make the geometry so that I don’t have to rotate it manually in the code, it has absolutely no transparency and is 100% reflective everywere. If I rotate it in Blender, then rotate it back in the code (which is what I do right now), I get a transparent spot at the corner of the map.