[HOW-TO??] make reflective a simple Object3D (like a cube)

Started by Charles_Stain, October 09, 2010, 05:47:16 PM

Previous topic - Next topic

Charles_Stain

Hello everyone,
I think that a picture worth 1000 words, so this is my situation now:



And this is what I would like to obtain (picture taken from a 3d renderer coded from my university prof.):


As you can see every edge is lit and you can recognize it.. in the first picture even if I move the camera I can't recognize a vertex from another one.
Actually I use a default global light + a simple light positioned in the same place of my camera.
I hope you have understood me :D

Have a nice day,
A.

paulscode

A code sample would be helpful, but my first impression is that you have the ambient light up too high.  Try adjusting the brightness of both the ambient light and the point light source.

On a separate note, for some reason, your pictures didn't show up in my browser (Firefox 3.6.10, Ubuntu Lucid 64-bit).  I had to grab the links from the page source.  I'm guessing it is due to the fact that they are in .tiff format.  In case anyone else has the same issue, the links are:
http://www.fileden.com/files/2008/10/14/2142989/no_ref.tiff
and:
http://www.fileden.com/files/2008/10/14/2142989/reflecting.tiff

Charles_Stain

In first place, thank you for the quick reply.
Here is a significant code piece:


public ObjectViewer(Object3D genericShape) throws Exception {

this.world = new World();
this.world.setAmbientLight(50,50,50);

// CAMERA
this.cameraX = 50;
this.cameraY = -50;
this.cameraZ = 5;
this.cameraPositionVector = new SimpleVector(this.cameraX, this.cameraY, this.cameraZ);

// LIGHT ASSOCIATED WITH THE CAMERA
this.cameraLight = this.world.addLight(this.cameraPositionVector, 0, 0, 0);

this.genericShape = genericShape;
this.genericShape.setEnvmapped(Object3D.ENVMAP_ENABLED);
this.genericShape.build();
this.world.addObject(this.genericShape);

this.world.getCamera().setPosition(this.cameraPositionVector);
this.world.getCamera().lookAt(this.genericShape.getTransformedCenter());


}

public void loop() throws Exception {
this.buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
this.buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
this.buffer.enableRenderer(IRenderer.RENDERER_OPENGL);

// Mouse mapper creation
[...]

// Key mapper creation
[...]

while (!org.lwjgl.opengl.Display.isCloseRequested()) {
this.buffer.clear(java.awt.Color.GRAY);
this.world.renderScene(this.buffer);
this.world.draw(this.buffer);
this.buffer.update();
this.buffer.displayGLOnly();
updateCameraWithMouse();
updateCameraWithKeyboard();
updateCameraLight();
Thread.sleep(10);
}
this.buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
this.buffer.dispose();
System.exit(0);
}


Note that the setAdditionalColor is invoked Clojure side on the Object3D genericShape passed to the class.
The important part is the first one which:

1) I set an ambientLight as the tutorials tells me to do.
2) I create and position a source of light at the same place of my camera

Cheers,
A.

paulscode

Well, I haven't a clue what "Clojure side" means, but I can tell you that a point light of color 0,0,0 is like having no light at all.  Also, setAdditionalColor acts the same as making the ambient light brighter on whatever object it is applied to.  Ambient light alone without a point light source makes the entire object all the same shade, which is exactly the effect that you are seeing.  Make your point light brighter and reduce the brightness of whatever value you are sending to the setAdditionalColor method (or remove the call to that method entirely), and you should achieve the effect you are after.

Charles_Stain

Ok, I've played a bit with the parameters of ambient and spot light and now i have a nicer effect:

The last thing I wish to know is how to get rid of the ugly look to see the light reflecting on the triangles that make the objects:

Thanks for the help :)
A.

paulscode

For those who can't see the images again, here are the links from the page source:
http://www.fileden.com/files/2008/10/14/2142989/improv.tiff
and:
http://www.fileden.com/files/2008/10/14/2142989/nasty.tiff

Might I suggest using a format more common on the web, like jpg?

In regards to your question, I am not sure what direction you are looking at the cube from in the second picture.  Are you looking directly toward a corner or toward a face?  If you are looking toward a face and getting this effect, then it is probably because the face is made up of four triangles with a central vertex.  Since shading on polygons start from the vertices, and since the light source is over that central vertex, you get the effect in your second image.

If that is the case, I would reduce the number of triangles you are using on that face.  There is no reason for a face to have four triangles instead of two.  I'm assuming you created this cube using jPCT's Primitives.getCube method, which has four triangles on at least two of the sides for some reason.  You could try building your cube manually, only using two polys per side.  Something like this should work (untested, but you get the general idea):
    // Creates a cube of the specified color
    private Object3D coloredCube( float scale, Color color )
    {
        TextureManager.getInstance().addTexture( "CubeClr",
                                               new Texture( 4, 4, color) );

        // 'offset' is simply half the length of the cube's side:
        float offset = 0.5f * scale;

        // Create a new object with the proper number of polys:
        Object3D obj = new Object3D( 12 );
        // Define the object's polys:
        obj.addTriangle( new SimpleVector( -offset, -offset, -offset ), 0, 0,
                         new SimpleVector( -offset, offset, -offset ), 0, 1,
                         new SimpleVector( offset, offset, -offset ), 1, 1,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( offset, offset, -offset ), 1, 1,
                         new SimpleVector( offset, -offset, -offset ), 1, 0,
                         new SimpleVector( -offset, -offset, -offset ), 0, 0,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( offset, -offset, offset ), 0, 0,
                         new SimpleVector( offset, offset, offset ), 0, 1,
                         new SimpleVector( -offset, offset, offset ), 1, 1,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( -offset, offset, offset ), 1, 1,
                         new SimpleVector( -offset, -offset, offset ), 1, 0,
                         new SimpleVector( offset, -offset, offset ), 0, 0,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( -offset, -offset, offset ), 0, 0,
                         new SimpleVector( -offset, offset, offset ), 0, 1,
                         new SimpleVector( -offset, offset, -offset ), 1, 1,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( -offset, offset, -offset ), 1, 1,
                         new SimpleVector( -offset, -offset, -offset ), 1, 0,
                         new SimpleVector( -offset, -offset, offset ), 0, 0,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( offset, -offset, -offset ), 0, 0,
                         new SimpleVector( offset, offset, -offset ), 0, 1,
                         new SimpleVector( offset, offset, offset ), 1, 1,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( offset, offset, offset ), 1, 1,
                         new SimpleVector( offset, -offset, offset ),1, 0,
                         new SimpleVector( offset, -offset, -offset ), 0, 0,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( -offset, -offset, offset ), 0, 0,
                         new SimpleVector( -offset, -offset, -offset ), 0, 1,
                         new SimpleVector( offset, -offset, -offset ), 1, 1,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( offset, -offset, -offset ), 1, 1,
                         new SimpleVector( offset, -offset, offset ), 1, 0,
                         new SimpleVector( -offset, -offset, offset ), 0, 0,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( -offset, offset, -offset ), 0, 0,
                         new SimpleVector( -offset, offset, offset ), 0, 1,
                         new SimpleVector( offset, offset, offset ), 1, 1,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.addTriangle( new SimpleVector( offset, offset, offset ), 1, 1,
                         new SimpleVector( offset, offset, -offset ), 1, 0,
                         new SimpleVector( -offset, offset, -offset ), 0, 0,
                         TextureManager.getInstance().getTextureID( "CubeClr" ) );
        obj.build();
        return obj;
    }

Charles_Stain

I think it would be a useless complication, so I'll keep the things like they are now :)
Thank for the help,
A.