This might be me or not. At that point I’m not sure, hence this post.
I’m running into an issue in my game where light from an independent viewport “leaks” into the main viewport. So, I tried to find the cause by making a test run in an empty program and I discovered something odd.
The sample program is simple.
On start-up I make a simple box that receives light from two directions (left and camera-facing). The first light direction is settable, the other is static. On the screen, once the program is loaded, you can clearly see the box with two faces lit.
When you press I, that makes an independent viewport what will reuse the makeBox(lightDirection); and put that box into a node that is attached to this viewport (the viewport has a dedicated camera). Now, that new box has one different side lit. top and camera-facing instead of left and camera-facing.
I’m at a loss to explain or understand why this happens. Anyone wants to have a go at it?
NOTE: Replace the texture with your favorite one as the one in the program below won’t be found on your side.
Here’s the sample program:
[java]
package mygame;
import com.jme3.app.SimpleApplication;
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.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
/**
- test
-
@author MadJack
*/
public class Main extends SimpleApplication {
Geometry box;
boolean viewOff = true;
PointLight dl;
Geometry geo;
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(20);
registerKeys();
cam.setLocation(new Vector3f(-1.9600048f, 1.8629576f, 10.093461f));
// make a box with light in UNIT_X direction
box = makeBox(Vector3f.UNIT_X);
// attach box
rootNode.attachChild(box);
// make sure light and box are updated
rootNode.updateGeometricState();
}
private void makeView(Vector3f lightDirection) {
if (viewOff) {
// make new camera
Camera viewCam = new Camera(165, 165);
viewCam.setFrustumPerspective(90.0f, 1f, 1f, 75f);
viewCam.setLocation(new Vector3f(-1.9600048f, 1.8629576f, 3.093461f));
System.out.println(viewCam.getUp());
viewCam.setViewPort(1.46f, 3.46f, 1.76f, 3.76f);
// make a pointlight at 20 on Y axis
dl = new PointLight();
dl.setPosition(new Vector3f(0, 20, 0));
dl.setColor(ColorRGBA.randomColor());
// make a new box with light according to lightDirection
geo = makeBox(lightDirection);
// add the light to the geometry
geo.addLight(dl);
// turn camera to look at origin
viewCam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
System.out.println(viewCam.getUp());
// make sure geometry’s light is updated
geo.updateGeometricState();
Node n = new Node(“viewNode”);
n.attachChild(geo);
n.updateGeometricState();
// rootNode.attachChild(geo);
// rootNode.updateGeometricState();
ViewPort vp = renderManager.createMainView(“view”, viewCam);
vp.attachScene(n);
// vp.attachScene(rootNode);
vp.setClearEnabled(true);
vp.setEnabled(true);
vp.setBackgroundColor(ColorRGBA.DarkGray);
viewOff = false;
} else {
viewOff = true;
renderManager.removeMainView(“view”);
}
}
private Geometry makeBox(Vector3f lightDirection) {
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom = new Geometry(“Box”, b);
geom.updateModelBound();
DirectionalLight dl1 = new DirectionalLight();
DirectionalLight dl2 = new DirectionalLight();
dl1.setDirection(lightDirection);
dl2.setDirection(Vector3f.UNIT_Z.negate());
dl1.setColor(ColorRGBA.Yellow);
dl2.setColor(ColorRGBA.Cyan);
Material mat = new Material(assetManager, “Common/MatDefs/Light/Lighting.j3md”);
Texture tex = assetManager.loadTexture(“Textures/ClassA.png”);
mat.setTexture(“ColorRamp”, tex);
geom.addLight(dl1);
geom.addLight(dl2);
geom.setMaterial(mat);
return geom;
}
private void switchViewColor() {
dl.setColor(ColorRGBA.randomColor());
geo.updateGeometricState();
}
private void registerKeys() {
inputManager.addMapping(“ViewOnOff”, new KeyTrigger(KeyInput.KEY_I));
inputManager.addMapping(“SwitchColor”, new KeyTrigger(KeyInput.KEY_O));
inputManager.addListener(buttonListener, “ViewOnOff”, “SwitchColor”);
}
private ActionListener buttonListener = new ActionListener() {
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals(“ViewOnOff”) && !isPressed) {
makeView(Vector3f.UNIT_Y.negate());
} else if (name.equals(“SwitchColor”) && !isPressed) {
switchViewColor();
}
}
};
@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
[/java]
If you want, you can comment/uncomment the following lines and see the cube in the main window “flips” as the view pops up as the viewport use the rootNode instead of new node.
[java]
Node n = new Node(“viewNode”);
n.attachChild(geo);
n.updateGeometricState();
// rootNode.attachChild(geo);
// rootNode.updateGeometricState();
[/java]
[java]
vp.attachScene(n);
// vp.attachScene(rootNode);
[/java]
EDIT: Sorry for the mistake, the commented lines were inverted. Fixed now.