Texture Mapping a Sphere

Hey everyone! I’ve been a long time lurker of jME since version 2, but I am just now getting started on my project with jME3.



I was wondering if anyone had some wisdom about this problem I’m having.



I’m trying to texture map a sphere. It’s supposed to be a planet floating in space. I’ve tried everything, except maybe making my own j3md file…



Thanks for your help!!



Here is where I’m at so far:

http://i.imgur.com/wqB2F.jpg



It’s not treating the texture as a cube map.



lush_planet.j3m

[java]

Material lush_planet : Common/MatDefs/Misc/Unshaded.j3md

//Common/MatDefs/Light/Lighting.j3md

{

MaterialParameters {

//Ambient : 1 1 1 1

//Ambient : 0.1 0.1 0.1 0.1

//Specular : 0.0 0.0 0.0 0.1

//ParallaxHeight : 0.05

//UseMaterialColors : true

//Shininess : 8.192

//DiffuseMap : textures/planets/lush_planet.jpg

ColorMap : cubemaps/red_clouds.dds

}

}

[/java]



CubemapTester.java

[java]

package com.gohlke.games.space;



import com.jme3.app.SimpleApplication;

import com.jme3.asset.AssetManager;

import com.jme3.asset.TextureKey;

import com.jme3.asset.plugins.FileLocator;

import com.jme3.bounding.BoundingSphere;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.material.RenderState;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.queue.RenderQueue;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Sphere;

import com.jme3.texture.Image;

import com.jme3.texture.Texture;

import com.jme3.texture.TextureCubeMap;



import java.io.File;



/**

  • <p>TODO: This class needs a description!</p>
  • <p>Date: 2/12/12</p>
  • <p>Time: 1:56 AM</p>

    *
  • @author Jgohlke

    */

    public class CubemapTester extends SimpleApplication

    {

    public static File artDir = new File( "D:\JavaProgramming\Space\trunk\art\final" );



    public static String blueClouds = "cubemaps/blue_clouds.dds";

    public static String redClouds = "cubemaps/red_clouds.dds";

    public static String starfield = "cubemaps/starfield.dds";



    public static void main( String[] args )

    {

    CubemapTester app = new CubemapTester();

    app.start(); // start the game

    }



    @Override

    public void simpleInitApp()

    {

    guiViewPort.setBackgroundColor( ColorRGBA.Magenta );



    assetManager.registerLocator( artDir.getAbsolutePath(), FileLocator.class );



    boolean sphereMap = false;



    TextureKey starfieldTextureKey = new TextureKey(starfield, true);

    starfieldTextureKey.setGenerateMips(true);

    starfieldTextureKey.setAsCube(!sphereMap);

    Texture starfieldTexture = assetManager.loadTexture(starfieldTextureKey);



    TextureKey redCloudsTextureKey = new TextureKey(redClouds, true);

    redCloudsTextureKey.setGenerateMips(true);

    redCloudsTextureKey.setAsCube(!sphereMap);

    Texture redCloudsTexture = assetManager.loadTexture(redCloudsTextureKey);



    TextureKey blueCloudsTextureKey = new TextureKey(blueClouds, true);

    blueCloudsTextureKey.setGenerateMips(true);

    blueCloudsTextureKey.setAsCube(!sphereMap);

    Texture blueCloudsTexture = assetManager.loadTexture(blueCloudsTextureKey);



    Spatial starfieldSkybox = createSky( assetManager, starfieldTexture, sphereMap, 20 );

    rootNode.attachChild( starfieldSkybox );



    Spatial redCloudsSkybox = createSky( assetManager, redCloudsTexture, sphereMap, 15 );

    rootNode.attachChild( redCloudsSkybox );



    Spatial blueCloudsSkybox = createSky( assetManager, blueCloudsTexture, sphereMap, 10 );

    rootNode.attachChild( blueCloudsSkybox );



    Spatial planet = assetManager.loadModel("models/planets/lush_planet.j3o");

    /Material mat_default = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");/

    Material mat_default = assetManager.loadMaterial( "models/planets/lush_planet.j3m" );

    planet.setMaterial(mat_default);

    rootNode.attachChild( planet );



    DirectionalLight sun = new DirectionalLight();

    sun.setDirection(new Vector3f(1,0,-2).normalizeLocal());

    sun.setColor(ColorRGBA.White);

    rootNode.addLight(sun);

    }



    /**
  • Creates a sky using the given texture (cubemap or spheremap).

    *
  • @param assetManager The asset manager to use to load materials
  • @param texture Texture to use for the sky
  • @param normalScale The normal scale is multiplied by the 3D normal
  • to get a texture coordinate. Use Vector3f.UNIT_XYZ to not apply
  • and transformation to the normal.
  • @param sphereMap The way the texture is used
  • depends on this value:<br>
  • <ul>
  • <li>true: Its a Texture2D with the pixels arranged for
  • <a href="http://en.wikipedia.org/wiki/Sphere_mapping">sphere mapping</a>.</li>
  • <li>false: Its either a TextureCubeMap or Texture2D. If its a Texture2D
  • then the image is taken from it and is inserted into a TextureCubeMap</li>
  • </ul>
  • @param sphereRadius If specified, this will be the sky sphere’s radius.
  • This should be the camera’s near plane for optimal quality.
  • @return A spatial representing the sky

    */

    public static Spatial createSky(AssetManager assetManager, Texture texture, Vector3f normalScale, boolean sphereMap, int sphereRadius) {

    if (texture == null) {

    throw new IllegalArgumentException("texture cannot be null");

    }

    final Sphere sphereMesh = new Sphere(10, 10, sphereRadius, false, true);



    Geometry sky = new Geometry("Sky", sphereMesh);

    sky.setQueueBucket( RenderQueue.Bucket.Sky);

    sky.setCullHint(Spatial.CullHint.Never);

    sky.setModelBound(new BoundingSphere(Float.POSITIVE_INFINITY, Vector3f.ZERO));



    Material skyMat = new Material(assetManager, "Common/MatDefs/Misc/Sky.j3md");



    skyMat.setVector3("NormalScale", normalScale);

    if (sphereMap) {

    skyMat.setBoolean("SphereMap", sphereMap);

    } else if (!(texture instanceof TextureCubeMap )) {

    // make sure its a cubemap

    Image img = texture.getImage();

    texture = new TextureCubeMap();

    texture.setImage(img);

    }

    skyMat.setTexture("Texture", texture);

    skyMat.setTransparent( true );

    skyMat.getAdditionalRenderState().setBlendMode( RenderState.BlendMode.Alpha);

    sky.setMaterial(skyMat);



    return sky;

    }



    public static Spatial createSky(AssetManager assetManager, Texture texture, boolean sphereMap, int sphereRadius) {

    return createSky(assetManager, texture, Vector3f.UNIT_XYZ, sphereMap, sphereRadius);

    }

    }

    [/java]

Well, I went ahead and wrote my own j3md, a vertex shader, and a fragment shader. Here it is if anyone would be interested. Currently it ignores scene lights, I’ll be adding that in later.



http://imgur.com/0EbHb.jpg



UnshadedMapped.j3md

[java]MaterialDef UnshadedMapped {



MaterialParameters {

TextureCubeMap ColorMap

TextureCubeMap LightMap

Color Color ( Color )

Boolean VertexColor



// Texture of the glowing parts of the material

TextureCubeMap GlowMap

// The glow color of the object

Color GlowColor

}



Technique {

VertexShader GLSL100: materials/UnshadedMapped.vert

FragmentShader GLSL100: materials/UnshadedMapped.frag



WorldParameters {

WorldViewProjectionMatrix

}



Defines {

SEPARATE_TEXCOORD : SeparateTexCoord

HAS_COLORMAP : ColorMap

HAS_LIGHTMAP : LightMap

HAS_VERTEXCOLOR : VertexColor

HAS_COLOR : Color

SPHERE_MAP : SphereMap

}

}



Technique PreNormalPass {



VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert

FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag



WorldParameters {

WorldViewProjectionMatrix

WorldViewMatrix

NormalMatrix

}



RenderState {



}



}





Technique Glow {



VertexShader GLSL100: Common/MatDefs/Misc/Unshaded.vert

FragmentShader GLSL100: Common/MatDefs/Light/Glow.frag



WorldParameters {

WorldViewProjectionMatrix

}



Defines {

HAS_GLOWMAP : GlowMap

HAS_GLOWCOLOR : GlowColor

HAS_COLORMAP // Must be passed so that Unshaded.vert exports texCoord.

}

}



Technique FixedFunc {

}



}[/java]



UnshadedMapped.vert

[java]uniform mat4 g_WorldViewProjectionMatrix;

attribute vec3 inNormal;

attribute vec3 inPosition;

varying vec3 normal;



#ifdef HAS_VERTEXCOLOR

attribute vec4 inColor;

varying vec4 vertColor;

#endif



void main(){

#ifdef HAS_VERTEXCOLOR

vertColor = inColor;

#endif



gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

normal = inNormal;

}[/java]



UnshadedMapped.frag

[java]varying vec3 normal;

uniform vec4 m_Color;



#ifdef HAS_COLORMAP

uniform samplerCube m_ColorMap;

#endif



#ifdef HAS_LIGHTMAP

uniform samplerCube m_LightMap;

#endif



#ifdef HAS_VERTEXCOLOR

varying vec4 vertColor;

#endif



void main(){

vec4 color = vec4(1.0);



#ifdef HAS_COLORMAP

color *= textureCube(m_ColorMap, normal);

#endif



#ifdef HAS_VERTEXCOLOR

color *= vertColor;

#endif



#ifdef HAS_COLOR

color *= m_Color;

#endif



#ifdef HAS_LIGHTMAP

color.rgb *= textureCube(m_LightMap, normal).rgb;

#endif



gl_FragColor = color;

}[/java]

3 Likes