[SOLVED] SimpleWaterProcessor water seems to be 100% reflective (or refracted image is in wrong place)

I’ve been trying to incorporate the SimpleWaterProcessor into my game, however, the effect seems to be 100% reflective which looks beautiful, but more like mercury that water.

To eliminate anything I’ve done wrong in my own game I started with the TestSimpleWater and that showed the same behaviour. I’ve played with SimpleWaterProcessor#setWaterTransparency and SimpleWaterProcessor#setWaterDepth as well as setting a water color with an alpha component and putting the water plane in the transparent bucket, none of which seem to make any difference

I tried adding another object under the water, a red cube, directly below the JME cube, at a depth of 5 meters and this is what I got

So the scene below the water is cutting through, but (as far as my understanding of refraction goes) at the wrong place. I believe that refraction just makes things seem like they are at a shallower depth than they really are, but should never make the red cube appear the wrong side of the JME cube.

Am I doing something wrong here?

1 Like

SimpleWaterFilter isnot accurate ,I am working on a third person shooter game & made a lake …goes deep but the water from undersurface isnot rendered so anyway I tried using it but it seems that it’s designed to be just a texture …no depth & no real water appearence …as JME wiki states it’s just a couple of textures mixed together …try using Water filter class

In case you need an example …remove the directional light if you donot want it
Example Code:

private void Water_Effect() {
                /** A white, directional light source */ 
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(rootNode.getLocalTranslation());
        sun.setColor(ColorRGBA.Yellow);
        rootNode.addLight(sun); 
        
        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);        
         WaterFilter water = new WaterFilter(rootNode, sun.getDirection());
        water.setWaterHeight(-20);
    
        
        water.setShapeType(WaterFilter.AreaShape.Circular);
        water.setUseFoam(true);
        water.setUseRipples(true);
        water.setDeepWaterColor(ColorRGBA.Brown);
        water.setWaterColor(ColorRGBA.Brown.mult(2.0f));
        water.setWaterTransparency(0.2f);
        water.setMaxAmplitude(0.3f);
        water.setWaveScale(0.008f);
        water.setSpeed(0.7f);
        water.setShoreHardness(1.0f);
        water.setRefractionConstant(0.2f);
        water.setShininess(0.3f);
        water.setSunScale(1.0f);
        water.setColorExtinction(new Vector3f(10.0f, 20.0f, 30.0f));
        water.setRadius(0.1f);
        water.setNormalScale(0.1f);
        fpp.addFilter(water);
        viewPort.addProcessor(fpp);
            
        water.setCenter(new Vector3f(72.81782f,-20f,760.87f));
        water.setRadius(500f);
 
    }

For scaling the water :

water.setCenter(new Vector3f(72.81782f,-20f,760.87f));
        water.setRadius(500f);

Hmm, looks like you are seeing exactly the same problems as me.

I want several small areas of water, rather than a global sea, so I think (unless I’m mistaken) that the water filter wouldn’t work for me, but thanks.

I’m going to try to remember how shaders work and see if I can fix the SimpleWaterProcessor

1 Like

Your welcome :smiley::smiley:,

Use this to scale water filter …you won’t have a global or water shore :

water.setCenter(new Vector3f(72.81782f,-20f,760.87f));
        water.setRadius(500f);

I’ve done a bit of digging and the transparency term seems to be divided by 10 before being passed to the material and I’m not sure why

This implies that the transparency can never be more than 0.1. Git blame implies its been like that since at least 2012

I removed this divide by 10 and set the transparency to 1 and it looks a lot more reasonable (although still not what I would call 100% transparent)

2 Likes

Hmm, it seems like the artefact is caused by the reflectionPlaneOffset being -5 by default

Setting it to zero makes things intersecting with the water (the JME cube in my image) look weird but setting it to something small like 0.5 makes the artefact go away without any other issues. I’m guessing that parameter does need to be adjusted based on wave sizes etc

2 Likes

To conclude this:

Trying that with a real scene look a little strange, I can see why its been effectively clamped at 0.1

Reducing the transparency makes it look less weird but you can no longer see whats below the water.

So I’ve modified the shaders (to be a lot simpler actually) and just had 0.3 * the refracted scene and 0.7 * the reflected scene (no depth, no Fresnel factor) and thats got me a lot closer to what I want

4 Likes

Show us your in game settings, using jme SimpleWaterProcessor, not the one you hacked please.

1 Like

“Modified” please :stuck_out_tongue:

To get the “default” view (where you can just see things below the surface) these are my in game settings

            SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(assetManager);
            waterProcessor.setReflectionScene(mainSceneRootNode);
            waterProcessor.setRenderSize(waterResolution, waterResolution);
            waterProcessor.setWaterTransparency(1.0f);
            waterProcessor.setReflectionClippingOffset(0.9f);
            waterProcessor.setWaveSpeed(0.01f);
            Vector3f waterLocation=new Vector3f(0,height,0);
            waterProcessor.setLightPosition(new Vector3f(0, 300, 0));
            waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));

And the surface is beginning to look odd close to the camera

As a self contained example where you can’t see the underwater scene, even at 100% transparency

public class TestSimpleWater extends SimpleApplication{

    Material mat;
    Spatial waterPlane;
    SimpleWaterProcessor waterProcessor;
    Node sceneNode;

    public static void main(String[] args) {
        TestSimpleWater app = new TestSimpleWater();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        initScene();

        //create processor
        waterProcessor = new SimpleWaterProcessor(assetManager);
        waterProcessor.setReflectionScene(sceneNode);
        waterProcessor.setWaterTransparency(1f);
        waterProcessor.setDebug(true);
        waterProcessor.setReflectionClippingOffset(-0.5f); //with out this you get the artifact I describe in a previous post
        viewPort.addProcessor(waterProcessor);

        waterPlane = assetManager.loadModel("Models/WaterTest/WaterTest.mesh.xml");
        waterPlane.setMaterial(waterProcessor.getMaterial());
        waterPlane.setLocalScale(40);

        rootNode.attachChild(waterPlane);
    }

    private void initScene() {
        //init cam location
        cam.setLocation(new Vector3f(-7, 10, 10));
        cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
        //init scene
        sceneNode = new Node("Scene");
        mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
        Box b = new Box(1, 1, 1);
        Geometry geom = new Geometry("Box", b);
        geom.setMaterial(mat);
        geom.setLocalTranslation(-5, 0, 0);
        sceneNode.attachChild(geom);

        Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat2.setColor("Color", ColorRGBA.Red);
        Box b2 = new Box(1, 1, 1);
        Geometry geom2 = new Geometry("Box", b2);
        geom2.setMaterial(mat2);
        geom2.setLocalTranslation(-5, -5, 0);

        sceneNode.attachChild(geom2);

        // load sky
        sceneNode.attachChild(SkyFactory.createSky(assetManager,
                "Textures/Sky/Bright/BrightSky.dds",
                SkyFactory.EnvMapType.CubeMap));
        rootNode.attachChild(sceneNode);

    }
}
1 Like

Fantastic ! …can you get the camera deep under water , I just wanna be sure of it’s deepness

May be because they want it to be as less shiny as it can , but why cannot you set it to 10 to be 1 ?

SimpleWaterProcessor will not support this as it has no idea what “in the water” is.

Regarding this thread: I hadn’t really played with SimpleWaterProcessor in probably 9 years so I ran the demos. TestSceneWater seems to behave a little better with respect to transparency… and though it is also using SimpleWaterProcessir. I don’t know what the actual difference is, though.

1 Like

yeh, I have tried using SimpleWaterProcessor but it creates no actual water thickness & deepness like the WaterFilter does , as JME wiki states , they are just a couple of mixed textures , but i want to make sure of that :slight_smile: , anyway i am using WaterFilter & find a way to scale it

Water is hard. Anything built in is just a trick.

2 Likes

Fantastic ! …can you get the camera deep under water , I just wanna be sure of it’s deepness

Sure, here is with the camera just under the water (and separately implemented underwater effects turned off)

May be because they want it to be as less shiny as it can , but why cannot you set it to 10 to be 1 ?

The original version of the SimpleWaterProcessor clamps the input to 1, then divides it by 10

Regarding this thread: I hadn’t really played with SimpleWaterProcessor in probably 9 years so I ran the demos. TestSceneWater seems to behave a little better with respect to transparency… and though it is also using SimpleWaterProcessir. I don’t know what the actual difference is, though.

It does, doesn’t it. I have a very bright sky, I wonder if that makes a difference. My scene under a dark grey sky does show a lot more of the underwater scene. I wonder if there’s some maxing out the pixels issue going on. TestSceneWater also uses a real light source, while my light is all pre-baked

Water is hard. Anything built in is just a trick.

Aint that the truth. But I’m fairly happy with my 70% reflected scene + 30% refracted scene, I’m sure I’ll find a corner case it doesn’t work for soon enough though

1 Like

The depth does work and so does transparency.

Look at the TestSimpleWaterProcessor box and its half submerged, 1f above water, 1f below.

Default numbers.

Transparencey 0.4
Depth 1.0

No words show. Mirror surface.

Now with depth:

        waterProcessor.setWaterTransparency(100.0f);
        waterProcessor.setWaterDepth(1.0f);  

We have a blend of depth and transparency.

Now with:

        waterProcessor.setWaterTransparency(1000.0f);
        waterProcessor.setWaterDepth(.1f);   

Words show and the background is misty white.

Now change background color:

        waterProcessor.setWaterTransparency(1000.0f);
        waterProcessor.setWaterDepth(0.1f);         // transparency of water
        waterProcessor.setWaterColor(ColorRGBA.Orange);

Now with:

        waterProcessor.setWaterTransparency(1000.0f);
        waterProcessor.setWaterDepth(1000.0f);

No mist and clear words.

As wiki says, this is for puddles and fountains, i,e non navigable, shallow water.

The SimpleWaterProcessor has less performance impact on your game than the full featured SeaMonkey WaterFilter; the main difference is that the SimpleWaterProcessor does not include under-water effects.

I am not sure if an object intersecting the water plane is the determining factor for depth, or why there is such a large range for the variables but there it is.

4 Likes