Hi,
Does anyone have any experience with using 3D textures in jme3???
I can see that TextureCubeMap exists but when I tried to use it the results were rather poor
Could someone show me an example of using it ??
Cube map != 3dtexutre
Cube map is for reflection/sky only,
while a 3d texutre is a real texture with 3dimensions. However as far as I know there is currenlty no build in support for this(though it shouldnāt be that hard to implement one)
OK, thanks for answer.
Iāll try to look into 3D textures matter.
Maybe it is really not difficult to implement it
Why not use a normal map? It gives a 3D āsimulationā based on a normal map (image) of the texture you want with some relief.
Normal map will not fit for what I am going to implement.
I need to attach 3D texture to a 3D object and not creating a bump effect.
The 3D object must look like it was carved out of a 3D texture image.
Imagine a cube of marble and create a sphere out of it using appropriate tools
The sphere will look like covered with the marble texture and that is what I intend to have.
If there is anyone who has been implementing the textures in jme I would appreciate help with this.
Iāve created very simple 3D texture class but when I apply it, it looks odd.
Some letters appear on my sphere not knowing why
the letter texture is usualy a case of wrong / false state updates
OK, so I really think I will not be able to do it without help
Here is my Texture3D code:
[java]
public class Texture3D extends Texture {
private WrapMode wrapS = WrapMode.EdgeClamp;
private WrapMode wrapT = WrapMode.EdgeClamp;
private WrapMode wrapR = WrapMode.EdgeClamp;
public Texture3D() {
}
public Texture3D(Image image) {
this.setImage(image);
}
public Texture3D(String name, Image image) {
this.setName(name);
this.setImage(image);
}
@Override
public void setWrap(WrapAxis axis, WrapMode mode) {
if (mode == null) {
throw new IllegalArgumentException("mode can not be null.");
} else if (axis == null) {
throw new IllegalArgumentException("axis can not be null.");
}
switch (axis) {
case S:
this.wrapS = mode;
break;
case T:
this.wrapT = mode;
break;
case R:
this.wrapR = mode;
break;
default:
throw new IllegalStateException("Unknown wrap axis: " + axis);
}
}
@Override
public void setWrap(WrapMode mode) {
if (mode == null) {
throw new IllegalArgumentException("Wrap mode can not be null.");
}
this.wrapS = mode;
this.wrapT = mode;
this.wrapR = mode;
}
@Override
public WrapMode getWrap(WrapAxis axis) {
switch (axis) {
case S:
return wrapS;
case T:
return wrapT;
case R:
return wrapR;
}
throw new IllegalArgumentException("Unknown wrap axis: " + axis);
}
@Override
public Type getType() {
return Type.ThreeDimensional;
}
@Override
public Texture createSimpleClone() {
return this.createSimpleClone(new TextureCubeMap());
}
@Override
public Texture createSimpleClone(Texture rVal) {
rVal.setWrap(WrapAxis.S, wrapS);
rVal.setWrap(WrapAxis.T, wrapT);
rVal.setWrap(WrapAxis.R, wrapR);
return super.createSimpleClone(rVal);
}
}
[/java]
And here is my simple game code:
[java]
public class Texture3DTest extends SimpleApplication {
public Texture3DTest() {
showSettings = false;
}
@Override
public void simpleInitApp() {
//mouseInput.setCursorVisible(true);
flyCam.setMoveSpeed(10);
//creating a sphere
Sphere sphere = new Sphere(32, 32, 1);
//getting the boundingbox
sphere.updateBound();
BoundingBox bb = (BoundingBox)sphere.getBound();
Vector3f min = bb.getMin(null);
float[] ext = new float[] {bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2};
//we need to change the UV coordinates (the sphere is assumet to be inside the 3D image box)
sphere.clearBuffer(Type.TexCoord);
VertexBuffer vb = sphere.getBuffer(Type.Position);
FloatBuffer fb = (FloatBuffer) vb.getData();
float[] uvCoordinates = BufferUtils.getFloatArray(fb);
//now transform the coordinates so that they are in the range of <0; 1>
for(int i=0;i<uvCoordinates.length;i+:3) {
uvCoordinates = (uvCoordinates - min.x)/ext[0];
uvCoordinates = (uvCoordinates - min.y)/ext[1];
uvCoordinates = (uvCoordinates - min.z)/ext[2];
}
//apply new texture coordinates
VertexBuffer uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
uvCoordsBuffer.setupData(Usage.Static, 3, com.jme3.scene.VertexBuffer.Format.Float,
BufferUtils.createFloatBuffer(uvCoordinates));
sphere.setBuffer(uvCoordsBuffer);
//create geometry, and apply material and our 3D texture
Geometry g = new Geometry("sphere", sphere);
Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
try {
Texture texture = this.getTexture();
material.setTexture("DiffuseMap", texture);
} catch (IOException e) {
e.printStackTrace();
}
g.setMaterial(material);
rootNode.attachChild(g);
//add some light so that it is visible
PointLight light = new PointLight();
light.setColor(ColorRGBA.White);
light.setPosition(new Vector3f(5, 5, 5));
light.setRadius(20);
rootNode.addLight(light);
light = new PointLight();
light.setColor(ColorRGBA.White);
light.setPosition(new Vector3f(-5, -5, -5));
light.setRadius(20);
rootNode.addLight(light);
}
/**
- This method creates a RGB8 texture with the sizes of 10x10x10 pixels.
/
private Texture getTexture() throws IOException {
ArrayList<ByteBuffer> data = new ArrayList<ByteBuffer>(1);
ByteBuffer bb = BufferUtils.createByteBuffer(1010103);//all data must be inside one buffer
for(int i=0;i<10;++i) {
for(int j=0;j<10*10;++j) {
bb.put((byte)255);
bb.put((byte)255);
bb.put((byte)255);
}
}
bb.rewind();
data.add(bb);
return new Texture3D(new Image(Format.RGB8, 10, 10, 10, data));
}
}
[/java]
@Kaelthas, it canāt work with the DiffuseMap parameter itās a sampler2D. You need a sampler3D in the shader for it to work, and reading a 3D texture on the shader side is different.
What should your test case do?
ok I added texture3D to the core, look at the test case, itās basically yours, but with a custom shader that supports 3D textures.
I changed a bit the texture generation to have some white to blue gradient.
see
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestTexture3D.java?spec=svn8002&r=8002
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/tex3D.j3md?spec=svn8002&r=8002
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/tex3D.vert?spec=svn8002&r=8002
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/tex3D.frag?spec=svn8002&r=8002
Actually yes, the implementation looks right, the problem is that Texture3d and ArrayTextures are only usable with Shaders. (Hey seems like my guess was right, its the Texturestate that is false)
OK thanks guys
Iāll look into it as soon as I can
You can now load DDS 3D Textures see this example : http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/texture/TestTexture3DLoading.java?spec=svn8003&r=8003
Woow,
that really works awesome
Thanks.
Iāll be able to finish texture mapping now.
I guess that within 2 weeks blender loader will load textures that not only have UV defined
Thanks a lot.
Youāre welcome