I have a moving object and a sky box. When I try to use TextureCubeMap to make the object reflect the environment, I get the reflection, but is static - when I move the object, the reflection does not move. In TestCubeMap testcase, the object is fixed, but rotates - in that case, the reflections are properly shown. I modified that test so now the object does not rotate, but simply moves with the camera. Now, when I move the camera around, the object also moves, but the reflection on it does not. How do I make it to reflect the skybox in proper way when the object moves?
Here is the ready to run test code (based on TestCubeMap with some mods):
package jmetest.renderer;
import java.nio.FloatBuffer;
import org.lwjgl.util.vector.Matrix4f;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.image.TextureCubeMap;
import com.jme.image.Texture.ApplyMode;
import com.jme.image.Texture.CombinerFunctionRGB;
import com.jme.image.Texture.EnvironmentalMapMode;
import com.jme.image.Texture.MagnificationFilter;
import com.jme.image.Texture.MinificationFilter;
import com.jme.image.Texture.WrapMode;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.TexCoords;
import com.jme.scene.Spatial.CullHint;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.shape.Quad;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.util.TextureManager;
import com.jme.util.geom.BufferUtils;
/**
* <code>TestCubeMap</code>
*
* @author Joshua Slack
* @version $Id: $
*/
public class TestCubeMap1 extends SimpleGame {
private Quaternion rotQuat = new Quaternion();
private float angle = 0;
private Vector3f axis = new Vector3f(1, 1, 0);
private Sphere sphere;
private Node sky;
Texture envTex=null;
/**
* Entry point for the test,
*
* @param args
*/
public static void main(String[] args) {
TestCubeMap1 app = new TestCubeMap1();
app.setConfigShowMode(ConfigShowMode.AlwaysShow);
app.start();
}
float x=0;
float y=0;
Quaternion q=new Quaternion(1,1,1,1);
private Vector3f qaxis = new Vector3f(0, 1, 0);
protected void simpleUpdate() {
Vector3f v=cam.getDirection().normalizeLocal().mult(50);
sphere.setLocalTranslation(v);
}
protected void simpleInitGame() {
sphere= new Sphere("s",30,30,10);
sphere.setModelBound(new BoundingBox());
sphere.updateModelBound();
sphere.setCullHint(CullHint.Dynamic);
sphere.copyTextureCoordinates(0, 1, 1.0f);
sphere.scaleTextureCoordinates(0, 8);
rootNode.attachChild(sphere);
TextureState ts = display.getRenderer().createTextureState();
envTex=generateCubeMapTexture();
ts.setTexture(envTex);
ts.getTexture().setEnvironmentalMapMode(EnvironmentalMapMode.ReflectionMap);
ts.getTexture().setApply(ApplyMode.Combine);
ts.getTexture().setCombineFuncRGB(CombinerFunctionRGB.AddSigned);
sphere.setRenderState(ts);
generateSky();
rootNode.setCullHint(CullHint.Never);
rootNode.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
cam.setLocation(new Vector3f());
sky.getLocalTranslation().set(cam.getLocation());
}
private void generateSky() {
TextureState ts;
sky = new Node("sky");
sky.setCullHint(CullHint.Never);
sky.setLightCombineMode(LightCombineMode.Off);
rootNode.attachChild(sky);
ts = display.getRenderer().createTextureState();
ts.setTexture(generateCubeMapTexture());
sky.setRenderState(ts);
ZBufferState zbuff = display.getRenderer().createZBufferState();
zbuff.setWritable(false);
zbuff.setEnabled(true);
zbuff.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
sky.setRenderState(zbuff);
sky.setRenderQueueMode(Renderer.QUEUE_SKIP);
Quad posXQuad = new Quad("test", 10, 10);
FloatBuffer tbuf = BufferUtils.createFloatBuffer(12);
tbuf.put(1).put(1).put(-1);
tbuf.put(1).put(-1).put(-1);
tbuf.put(1).put(-1).put(1);
tbuf.put(1).put(1).put(1);
posXQuad.setTextureCoords(new TexCoords(tbuf, 3), 0);
posXQuad.setLocalRotation(new Quaternion(new float[] { 0,
(float) Math.toRadians(270), 0 }));
posXQuad.setLocalTranslation(new Vector3f(5, 0, 0));
sky.attachChild(posXQuad);
Quad negXQuad = new Quad("test", 10, 10);
tbuf = BufferUtils.createFloatBuffer(12);
tbuf.put(-1).put(1).put(1);
tbuf.put(-1).put(-1).put(1);
tbuf.put(-1).put(-1).put(-1);
tbuf.put(-1).put(1).put(-1);
negXQuad.setTextureCoords(new TexCoords(tbuf, 3), 0);
negXQuad.setLocalRotation(new Quaternion(new float[] { 0,
(float) Math.toRadians(90), 0 }));
negXQuad.setLocalTranslation(new Vector3f(-5, 0, 0));
sky.attachChild(negXQuad);
Quad posYQuad = new Quad("test", 10, 10);
tbuf = BufferUtils.createFloatBuffer(12);
tbuf.put(-1).put(1).put(-1);
tbuf.put(1).put(1).put(-1);
tbuf.put(1).put(1).put(1);
tbuf.put(-1).put(1).put(1);
posYQuad.setTextureCoords(new TexCoords(tbuf, 3), 0);
posYQuad.setLocalRotation(new Quaternion(new float[] {
(float) Math.toRadians(90), (float) Math.toRadians(270), 0 }));
posYQuad.setLocalTranslation(new Vector3f(0, 5, 0));
sky.attachChild(posYQuad);
Quad negYQuad = new Quad("test", 10, 10);
tbuf = BufferUtils.createFloatBuffer(12);
tbuf.put(1).put(-1).put(-1);
tbuf.put(-1).put(-1).put(-1);
tbuf.put(-1).put(-1).put(1);
tbuf.put(1).put(-1).put(1);
negYQuad.setTextureCoords(new TexCoords(tbuf, 3), 0);
negYQuad.setLocalRotation(new Quaternion(new float[] {
(float) Math.toRadians(270), (float) Math.toRadians(270), 0 }));
negYQuad.setLocalTranslation(new Vector3f(0, -5, 0));
sky.attachChild(negYQuad);
Quad posZQuad = new Quad("test", 10, 10);
tbuf = BufferUtils.createFloatBuffer(12);
tbuf.put(1).put(1).put(1);
tbuf.put(1).put(-1).put(1);
tbuf.put(-1).put(-1).put(1);
tbuf.put(-1).put(1).put(1);
posZQuad.setTextureCoords(new TexCoords(tbuf, 3), 0);
posZQuad.setLocalRotation(new Quaternion(new float[] { 0,
(float) Math.toRadians(180), 0 }));
posZQuad.setLocalTranslation(new Vector3f(0, 0, 5));
sky.attachChild(posZQuad);
Quad negZQuad = new Quad("test", 10, 10);
tbuf = BufferUtils.createFloatBuffer(12);
tbuf.put(-1).put(1).put(-1);
tbuf.put(-1).put(-1).put(-1);
tbuf.put(1).put(-1).put(-1);
tbuf.put(1).put(1).put(-1);
negZQuad.setTextureCoords(new TexCoords(tbuf, 3), 0);
negZQuad.setLocalTranslation(new Vector3f(0, 0, -5));
sky.attachChild(negZQuad);
}
private TextureCubeMap generateCubeMapTexture() {
Image posX = TextureManager.loadImage(TestBoxColor.class
.getClassLoader().getResource("jmetest/data/texture/cube_face_posx.png"), true);
Image negX = TextureManager.loadImage(TestBoxColor.class
.getClassLoader().getResource("jmetest/data/texture/cube_face_negx.png"), true);
Image posY = TextureManager.loadImage(TestBoxColor.class
.getClassLoader().getResource("jmetest/data/texture/cube_face_posy.png"), true);
Image negY = TextureManager.loadImage(TestBoxColor.class
.getClassLoader().getResource("jmetest/data/texture/cube_face_negy.png"), true);
Image posZ = TextureManager.loadImage(TestBoxColor.class
.getClassLoader().getResource("jmetest/data/texture/cube_face_posz.png"), true);
Image negZ = TextureManager.loadImage(TestBoxColor.class
.getClassLoader().getResource("jmetest/data/texture/cube_face_negz.png"), true);
Image cubeMapImage = posX;
cubeMapImage.addData(negX.getData(0));
cubeMapImage.addData(posY.getData(0));
cubeMapImage.addData(negY.getData(0));
cubeMapImage.addData(posZ.getData(0));
cubeMapImage.addData(negZ.getData(0));
TextureCubeMap cubeMapTex = new TextureCubeMap();
cubeMapTex.setImage(cubeMapImage);
cubeMapTex.setMinificationFilter(MinificationFilter.BilinearNoMipMaps);
cubeMapTex.setMagnificationFilter(MagnificationFilter.NearestNeighbor);
cubeMapTex.setWrap(WrapMode.EdgeClamp);
return cubeMapTex;
}
}