Here is some background info for JME3's basic water implementation:
A JME3 scene with water can use a com.jme3.water.SimpleWaterProcessor (which implements the SceneProcessor interface).
To achieve a water effect, JME3 uses shaders and a special material, Common/MatDefs/Water/SimpleWater.j3md. The water surface is a quad, and we use normal map and dU/dV map texturing to simulate the waves.
mainScene NodemainScene Node to the rootNodescene Spatialscene Spatialscene Spatial to the mainScene NodemainScene NodewaterProcessormainScene Spatial (!)viewPortquadwater Geometry from the Quadwater Geometry to the rootNode. (Not to the mainScene!)
The sample code can be found in jme3/src/jme3test/water/TestSimpleWater.java and jme3/src/jme3test/water/TestSceneWater.java.
Here is the most important part of the code:
// we create a water processor
SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
waterProcessor.setReflectionScene(mainScene);
// we set the water plane
Vector3f waterLocation=new Vector3f(0,-6,0);
waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
viewPort.addProcessor(waterProcessor);
// we set wave properties
waterProcessor.setWaterDepth(40); // transparency of water
waterProcessor.setDistortionScale(0.05f); // strength of waves
waterProcessor.setWaveSpeed(0.05f); // speed of waves
// we define the wave size by setting the size of the texture coordinates
Quad quad = new Quad(400,400);
quad.scaleTextureCoordinates(new Vector2f(6f,6f));
// we create the water geometry from the quad
Geometry water=new Geometry("water", quad);
water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
water.setLocalTranslation(-200, -6, 250);
water.setShadowMode(ShadowMode.Receive);
water.setMaterial(waterProcessor.getMaterial());
rootNode.attachChild(water);
You can lower the render size to gain higher performance:
waterProcessor.setRenderSize(128,128);
The deeper the water, the more transparent. (?)
waterProcessor.setWaterDepth(40);
A higher distortion scale makes bigger waves.
waterProcessor.setDistortionScale(0.05f);
A lower wave speed makes calmer water.
waterProcessor.setWaveSpeed(0.05f);
If your scene does not have a lightsource, you can set the light direction for the water:
waterProcessor.setLightDirection( new Vector3f(0.55f, -0.82f, 0.15f));
Instead of creating a quad and specifying a plane, you can get a default waterplane from the processor:
Geometry waterPlane = waterProcessor.createWaterGeometry(10, 10); waterPlane.setLocalTranslation(-5, 0, 5); waterPlane.setMaterial(waterProcessor.getMaterial());
You can offer a switch to set the water Material to a static texture – for users with slow PCs.