Question

My problem is the difference between this:

earths

and this:

spheres

I'm trying to create a nice looking solar system with Java3D but when I apply a texture the lighting effect disappears and the 3D effect (when not looking at the planet top-down) goes with it. How can I have this kind of shading on textured surfaces?

The code I used for the earth example is available below. The texture is downloadable here.

import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;

import javax.imageio.ImageIO;
import javax.media.j3d.*;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import java.awt.*;

import static java.lang.Math.PI;
import static java.lang.Math.cos;
import static java.lang.Math.sin;

public class Hello3d {

    public Hello3d()

    {

        SimpleUniverse universe = new SimpleUniverse();

        BranchGroup group = new BranchGroup();

        for(double i=0; i<2*PI; i+=PI/5) {
            group.addChild(basicSphere(0.8*cos(i),0.8*sin(i),0));
        }

        universe.getViewingPlatform().setNominalViewingTransform();

        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 10000000.0);

        PointLight light = new PointLight();
        light.setColor(new Color3f(Color.WHITE));
        light.setPosition(0.0f,0.0f,0.0f);
        light.setInfluencingBounds(bounds);
        group.addChild(light);


        universe.addBranchGraph(group);

    }

    public static void main( String[] args ) {

        new Hello3d();

    }

    private TransformGroup basicSphere(double x, double y, double z) {
        try {
        int primflags = Primitive.GENERATE_NORMALS + Primitive.GENERATE_TEXTURE_COORDS;

        Texture tex = new TextureLoader(
                ImageIO.read(getClass().getResource("earthmap.jpg"))
        ).getTexture();
        tex.setBoundaryModeS(Texture.WRAP);
        tex.setBoundaryModeT(Texture.WRAP);

        TextureAttributes texAttr = new TextureAttributes();
        texAttr.setTextureMode(TextureAttributes.REPLACE);

        Appearance ap = new Appearance();
        ap.setTexture(tex);
        ap.setTextureAttributes(texAttr);

        Sphere sphere = new Sphere(0.1f, primflags, 100, ap);

        Transform3D transform = new Transform3D();
        transform.setTranslation(new Vector3d(x, y, z));

        TransformGroup transformGroup = new TransformGroup();
        transformGroup.setTransform(transform);

        transformGroup.addChild(sphere);

        return transformGroup;
        } catch(Exception e) { e.printStackTrace(); }
        return null;
    }

}
Was it helpful?

Solution

With this:

   texAttr.setTextureMode(TextureAttributes.REPLACE);

you are saying to replace computed lighting value with value from texture. You want to use MODULATE or BLEND, depending on how exactly you want it to look. Check this to see what the different methods do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top