Problem where water filter and skybox meets

Picture worth a thousands words! Here is a video.



(I accidentally deleted this vidoe, see my next post for a better video)

http://www.youtube.com/watch?v=f_qc_bqXR0w



It shows the sudden change of color in the horizon while I move the mouse. But, why this is happening?



This happens on form this angle(so far)

Only @nehon would know the anwer…

mhh… I never notice this. Could you test the TestPostWater and see if you have similar behavior?

I have tried replacing the skybox(replaced with the default comes with jme test pack). The change is interesting and the issue is more noticeable.



http://www.youtube.com/watch?v=IbaICigF5vE



the opposite end of the island, i see sun reflection on the water. But it should be on the other side.



I’ll setup the character in the test scene. Will post back when its done.

yeah… you know I read the entire forum right?

One issue at a time please.

OK…it’s reflection map issue… how do you init your cam? you have a chaseCam?

Yes, I am using ChaseCam. In a CharacterNode(which extends Node) has the following method.

[java] public void setupChaseCam(InputManager inputManager){

ChaseCamera chaseCam = new ChaseCamera(GameMain.getInstance().getCamera(), this.getMainNode(), inputManager);

chaseCam.setDefaultHorizontalRotation(-FastMath.HALF_PI);

// chaseCam.setSmoothMotion(true);

chaseCam.setChasingSensitivity(5f);

chaseCam.setTrailingSensitivity(0.5f);

chaseCam.setRotationSensitivity(5f);

chaseCam.setTrailingRotationInertia(0.1f);

chaseCam.setDefaultDistance(20);

chaseCam.setMaxDistance(30);

chaseCam.setMinDistance(15);

chaseCam.setDragToRotate(false);

chaseCam.setInvertVerticalAxis(true);

}[/java]



Its used like this,



[java] rabbit = new EntityBuilder(game)

.assetName("rabbit")

.assetUserData("player")

.localScale(0.25f)

.localTranslation(new Vector3f(0, 100, 0))

.physicsControl(new CharacterControl(new CapsuleCollisionShape(1.7f, 3.8f), 0.05f))

.control(new PlayerControl()) // for assigning movement

.parentNode(rootNode)

.buildCharacter();



playerControl = rabbit.getMainNode().getControl(PlayerControl.class);

playerControl.setupAnimationSystem();



rabbit.registerWithInput(game.getInputManager());

rabbit.setupChaseCam(game.getInputManager());[/java]

@nehon here is another issue I reported earlier, that I think deserves your attention :smiley:



http://hub.jmonkeyengine.org/groups/general/forum/topic/scene-with-sky-causes-pssm-issue/

Should I upload the project to a repository? So, its easier for you to check.

no…you should make a simple test case as requested by Normen in the pssm post.

Did you test TestPostWater as i requested?

The thing is if you can’t reproduce the issue in a simple test case, the problem probably stands in a combinations of things you are doing in your code.



Making a simple test case may lead you to the cause of the issue on your own, and if that’s not the case, it may help me later on to investigate further.

Here is the test case,



(I ve also included a video, what you will see after running the program)

[java]package mygame;



import com.jme3.animation.AnimChannel;

import com.jme3.animation.AnimControl;

import com.jme3.animation.AnimEventListener;

import com.jme3.app.SimpleApplication;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

import com.jme3.bullet.collision.shapes.CollisionShape;

import com.jme3.bullet.control.CharacterControl;

import com.jme3.bullet.control.RigidBodyControl;



import com.jme3.bullet.util.CollisionShapeFactory;

import com.jme3.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;

import com.jme3.post.FilterPostProcessor;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial;

import com.jme3.terrain.geomipmap.TerrainQuad;

import com.jme3.terrain.heightmap.AbstractHeightMap;

import com.jme3.terrain.heightmap.ImageBasedHeightMap;

import com.jme3.texture.Texture;

import com.jme3.texture.Texture.WrapMode;

import com.jme3.util.SkyFactory;

import com.jme3.water.WaterFilter;

import jme3tools.converters.ImageToAwt;



public class Main extends SimpleApplication implements ActionListener, AnimEventListener {



public static Main game;

public Node oto;

private AnimChannel channel;

private AnimControl control;

private BulletAppState bulletAppState = new BulletAppState();

WaterFilter water;

float initialWaterHeight = 0.8f; // choose a value for your scene

private float time = 0.0f;

private float waterHeight = 0.0f;

private CharacterControl characterControl;

private boolean f = false, b = false, l = false, r = false;

private Vector3f walkDirection = Vector3f.ZERO;

float runValue = 1f;



public static void main(String[] args) {

game = new Main();

game.showSettings = false;

game.start();

}

private Material mat_terrain;

private TerrainQuad terrain;



@Override

public void simpleInitApp() {

stateManager.attach(bulletAppState);

initTerrain();

initWaterLight();

initOto();

}



@Override

public void simpleUpdate(float tpf) {

time += tpf;

waterHeight = (float) Math.cos(((time * 0.6f) % FastMath.TWO_PI)) * 1.5f;

water.setWaterHeight(initialWaterHeight + waterHeight);

walkDirection.set(0,0,0);



if(f & r)

walkDirection.interpolate(new Vector3f(cam.getDirection().getX(),0,cam.getDirection().getZ()), cam.getDirection().cross(Vector3f.UNIT_Y), 0.5f).normalizeLocal().multLocal(runValue);

else if(f & l)

walkDirection.interpolate(new Vector3f(cam.getDirection().getX(), 0, cam.getDirection().getZ()), cam.getDirection().cross(Vector3f.UNIT_Y).negate(), 0.5f).normalizeLocal().multLocal(runValue);

else if(b & r)

walkDirection.interpolate(new Vector3f(-cam.getDirection().getX(), 0, -cam.getDirection().getZ()), cam.getDirection().cross(Vector3f.UNIT_Y), 0.5f).normalizeLocal().multLocal(runValue);

else if(b & l)

walkDirection.interpolate(new Vector3f(-cam.getDirection().getX(), 0, -cam.getDirection().getZ()), cam.getDirection().cross(Vector3f.UNIT_Y).negate(), 0.5f).normalizeLocal().multLocal(runValue);

else if(f)

walkDirection = new Vector3f(cam.getDirection().getX(),0,cam.getDirection().getZ()).normalizeLocal().multLocal(runValue);

else if(b)

walkDirection = new Vector3f(-cam.getDirection().getX(),0,-cam.getDirection().getZ()).normalizeLocal().multLocal(runValue);

else if®

walkDirection = cam.getDirection().cross(Vector3f.UNIT_Y).normalizeLocal().mult(runValue);

else if(l)

walkDirection = cam.getDirection().cross(Vector3f.UNIT_Y).normalizeLocal().negate().mult(runValue);





if(!walkDirection.equals(Vector3f.ZERO)){

characterControl.setViewDirection(walkDirection);

}



characterControl.setWalkDirection(walkDirection);

}



@Override

public void simpleRender(RenderManager rm) {

}



public void initOto() {



oto = (Node) assetManager.loadModel(“Models/Oto/Oto.mesh.xml”);

oto.setLocalTranslation(-202.61884f, 12.38065f, -266.54138f);

rootNode.attachChild(oto);



control = oto.getControl(AnimControl.class);

control.addListener(this);

channel = control.createChannel();

channel.setAnim(“stand”);



characterControl = new CharacterControl (new CapsuleCollisionShape(2.2f,3.8f), 0.05f);

oto.addControl(characterControl);

bulletAppState.getPhysicsSpace().add(characterControl);



ChaseCamera chaseCam = new ChaseCamera(getCamera(), oto, inputManager);

chaseCam.setDefaultHorizontalRotation(-FastMath.HALF_PI);

// chaseCam.setSmoothMotion(true);

chaseCam.setChasingSensitivity(5f);

chaseCam.setTrailingSensitivity(0.5f);

chaseCam.setRotationSensitivity(5f);

chaseCam.setTrailingRotationInertia(0.1f);

chaseCam.setDefaultDistance(20);

chaseCam.setMaxDistance(30);

chaseCam.setMinDistance(15);

chaseCam.setDragToRotate(false);

chaseCam.setInvertVerticalAxis(true);



inputManager.addMapping(“f”, new KeyTrigger(KeyInput.KEY_W));

inputManager.addMapping(“b”, new KeyTrigger(KeyInput.KEY_S));

inputManager.addMapping(“l”, new KeyTrigger(KeyInput.KEY_A));

inputManager.addMapping(“r”, new KeyTrigger(KeyInput.KEY_D));



inputManager.addListener(this, new String[]{“f”, “b”, “l”, “r”});

}



public void onAction(String name, boolean isPressed, float tpf) {

if (name.equals(“f”)) {

if (isPressed) {

f = true;

} else {

f = false;

}

} else if (name.equals(“b”)) {

if (isPressed) {

b = true;

} else {

b = false;

}

} else if (name.equals(“l”)) {

if (isPressed) {

l = true;

} else {

l = false;

}

} else if (name.equals(“r”)) {

if (isPressed) {

r = true;

} else {

r = false;

}

}

}



public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {

}



public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {

}



private void initTerrain() {

mat_terrain = new Material(assetManager,

“Common/MatDefs/Terrain/Terrain.j3md”);



mat_terrain.setTexture(“Alpha”, assetManager.loadTexture(

“Textures/Terrain/splat/alphamap.png”));



Texture grass = assetManager.loadTexture(

“Textures/Terrain/splat/grass.jpg”);

grass.setWrap(WrapMode.Repeat);

mat_terrain.setTexture(“Tex1”, grass);

mat_terrain.setFloat(“Tex1Scale”, 64f);



Texture dirt = assetManager.loadTexture(

“Textures/Terrain/splat/dirt.jpg”);

dirt.setWrap(WrapMode.Repeat);

mat_terrain.setTexture(“Tex2”, dirt);

mat_terrain.setFloat(“Tex2Scale”, 32f);



Texture rock = assetManager.loadTexture(

“Textures/Terrain/splat/road.jpg”);

rock.setWrap(WrapMode.Repeat);

mat_terrain.setTexture(“Tex3”, rock);

mat_terrain.setFloat(“Tex3Scale”, 128f);





AbstractHeightMap heightmap = null;

Texture heightMapImage = assetManager.loadTexture(

“Textures/Terrain/splat/mountains512.png”);

heightmap = new ImageBasedHeightMap(

ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));

heightmap.load();



int patchSize = 65;

terrain = new TerrainQuad(“my terrain”, patchSize, 513, heightmap.getHeightMap());



terrain.setMaterial(mat_terrain);

terrain.setLocalTranslation(0, -10, 0);

terrain.setLocalScale(2f, 1f, 2f);



CollisionShape cs_terrain = CollisionShapeFactory.createMeshShape(terrain);

RigidBodyControl control_terrain = new RigidBodyControl(cs_terrain, 0);

terrain.addControl(control_terrain);

rootNode.attachChild(terrain);

bulletAppState.getPhysicsSpace().add(control_terrain);

}



private void initWaterLight() {

Spatial sky = SkyFactory.createSky(assetManager, “Scenes/Beach/FullskiesSunset0068.dds”, false);

rootNode.attachChild(sky);



DirectionalLight sun_1 = new DirectionalLight();

sun_1.setDirection(new Vector3f(-0.30160007f, -0.27755475f, -0.91214097f));

sun_1.setColor(ColorRGBA.White);

rootNode.addLight(sun_1);



FilterPostProcessor filterProcessor = new FilterPostProcessor(assetManager);

water = new WaterFilter(rootNode, sun_1.getDirection());

water.setWaterHeight(initialWaterHeight);

filterProcessor.addFilter(water);

viewPort.addProcessor(filterProcessor);



}

}[/java]



http://www.youtube.com/watch?v=Si6d-9N344M



I didn’t understand, what did you mean by test TestPostWater. Does it mean taking my character with this settings and see if the issue is occurring on that world?

ok it happen when the direction of the camera is strictly parallel to the water surface



a quick workaround is do this



chaseCam.setMinVerticalRotation(0.0001f);



this way your cam direction will never be parallel to the water surface and you won’t notice the difference.



in the mean time i’m gonna change the WaterFilter to ensure this does not happen.

Thank you :slight_smile: