DRAFT
Here is some background info for JME3's frist water implementation, nicknamed SeaMonkey:
A JME3 scene with water uses 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 rootNode
scene
Spatialscene
Spatialscene
Spatial to the mainScene
NodemainScene
NodewaterProcessor
mainScene
Spatial (!)viewPort
quad
water
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.