1 Attachment(s)
3D Solar System - web demo
Coincidently I've been working on space graphics for a pet project of mine. I'ts just going to be a solar system/orbit demo to put on my website in real time. The only requirement is teh WildTangent web driver. Unfortunatly some people seem to think it's spy ware when it's not. Just as a word of warning if you think you might want to work with it, when you download teh driver uncheck the box that says install teh toolbar companion. ANtispybot software will pick up WildTangent as spyware, but only because it actively checks for wt updates. It's safe - from a few years of personal experience.
Since a lot of you probably dont have WT installed for your browser, here is a screenshot of what I've got working so far.
Basically the planets are multilayered shaders, the base texture, hue overlay, and cloud textures really give teh planet depth. The clouds were the funnest part of the shader, as I had to do some manipulation to make sure they maintained the lightmap from the base layer shader. Fun stuff. The best part is its all JavaScript. I'm posting the source just to show you what the code looks like.
Code:
function on_load()
{
wt = document.WTScene;
wt.designedForVersion("3.0");
stage = wt.createStage();
pLight = wt.createLight(1); // point light
aLight = wt.createLight(0);
aLight.setColor( 10, 10, 10 );
lightGroup = wt.createGroup();
lightGroup.addObject( pLight );
pLight.setPosition( 0, 20, 0 );
// lightGroup.setConstantRotation( 1, 1, 1, 20);
camera = stage.createCamera();
camera.setAbsolutePosition( -5, -12, 0 );
camera.setAbsoluteOrientationVector( 1, 0, 0, 0, 0, 1 );
camera.setRotation(0, 1, 0, 15);
bmpEarth = wt.createBitmap( "art/earth.wjp" );
bmpEarthC = wt.createBitmap( "art/earthclouds.wjp" );
bmpPlanet = wt.createBitmap( "art/planet.wjp" );
bmpStars = wt.createBitmap( "art/stars.wjp" );
bmpNebula = wt.createBitmap( "art/redgalaxy.wjp" );
earthObj = new planetoid(10, bmpEarth, 3, bmpEarthC, 4);
marsObj = new planetoidC(scalePlanet(3, 10, 4), bmpPlanet);
starsObj = new planetoid(-1000, bmpStars, 2, bmpNebula, 2);
earthObj.group.setPosition(0, -10, 0);
shaderShifter(earthObj.shader, 1, 1.0, 1.0, -0.008, 0.0)
marsObj.group.setPosition(0, 10, 0);
marsObj.group.setRotation(0, 1, 0, 90);
marsObj.planet.setColor(223, 112, 45);
shaderReplaceLayer(marsObj.shader, 0, 2, 3, 8, bmpPlanet);
shaderAddLayer(marsObj.shader, 2, 4, 8, bmpEarthC);
shaderAddLayer(marsObj.shader, 0, 3, 8, 0);
shaderShifter(marsObj.shader, 1, 1.0, 1.0, -0.01, 0.0)
shaderShifter(starsObj.shader, 1, 5.0, 5.0, 0.005, 0.005);
shaderAddLayer(starsObj.shader, 2, 5, 8, bmpNebula);
shaderShifter(starsObj.shader, 3, 1.0, 1.0, 0.001, 0.001);
starsObj.group.setPosition(0, 0, 0); shaderShifter(starsObj.shader, 0, 5.0, 5.0, 0.0, 0.0);
space = wt.createGroup();
space.addObject(earthObj.group);
space.addObject(marsObj.group);
space.setAbsolutePosition( scaleOrbitR(3, 0.00000027), 0, 0 );
//document.write( scaleOrbitR(3, 0.0007848061528802386) );
//stage.addObject( pLight );
stage.addObject( aLight ); stage.addObject( lightGroup );
stage.addObject( starsObj.group ); stage.addObject( space );
wt.start();
//document.write( scalePlanet(3, 10, 4) );
}
////////////////////////////
// typical surface shader //
// initializes to 1 layer //
// use shaderAddLayer to //
// increase the number of //
// layers up to 8(7base0) //
////////////////////////////
function shader( iSource, iType, iGenMethod, bmpTexture )
{
var shader = wt.createSurfaceShader();
shader.setNumLayers(1);
if(iSource==2) // use texture
shader.setTexture(0, bmpTexture);
shader.setLayerSource(0, iSource);
shader.setLayerType(0, iType);
shader.setTextureCoordGenMethod(0, iGenMethod);
return shader;
}
//////////////////////////////
// adds an additional layer //
// to surface shaders //
//////////////////////////////
function shaderAddLayer( shader, iSource, iType, iGenMethod, bmpTexture )
{
shader.setNumLayers( shader.getNumLayers()+1 ); // incriment number of layers
var layer = shader.getNumLayers() -1;
if(iSource == 2) // use texture
shader.setTexture(layer, bmpTexture);
shader.setLayerSource(layer, iSource);
shader.setLayerType(layer, iType);
shader.setTextureCoordGenMethod(layer, iGenMethod); // default
}
function shaderGenMethod(shader, layer, Method) {
shader.setTextureCoordGenMethod(layer,Method);
}
function shaderShifter(shader, layer, xScale, yScale, xSpeed, ySpeed) {
var str ="shifter uscale = " + xScale +
" vscale = " + yScale +
" uspeed = " + xSpeed +
" vspeed = " + ySpeed;
shader.setProceduralWithString( layer, str );
}
//////////////////////////////
// replaces existing layer //
// of a surface shader //
//////////////////////////////
function shaderReplaceLayer( shader, layer, iSource, iType, iGenMethod, bmpTexture ) {
shader.setTexture(layer, bmpTexture );
shader.setLayerSource(layer, iSource);
shader.setLayerType(layer, iType);
shader.setTextureCoordGenMethod(layer, iGenMethod);
}
function planetoidC(r, bmpTexture) {
this.group = wt.createGroup();
this.planet = wt.createSphere( r, 20 ); // model sphere radius r, 20 sides
if(bmpTexture.getName() == "empty") { this.shader = shader( 0, 2, 8, 0); }
else { this.shader = shader( 2, 2, 8, bmpTexture); }
this.planet.setSurfaceShader(this.shader);
this.group.attach(this.planet);
this.group.setRotation( 1, 0, 0, 90 ); // orient to coordinate system
}
function planetoid(r, bTex, bType, dTex, dType) {
// create group, model and shader
this.group = wt.createGroup();
this.planet = wt.createSphere( r, 20 ); // create model sphere radius r, 20 sides
this.shader = wt.createSurfaceShader();
if(bType == 2)
this.shader.setNumLayers(3);
else
this.shader.setNumLayers(3);
this.planet.setSurfaceShader(this.shader);
this.group.attach(this.planet);
this.group.setRotation( 1, 0, 0, 90 );
// initiate base layer of shader
this.shader.setTexture( 0, bTex ); // set layer texture
this.shader.setLayerSource( 0, 2 ); // use texture
this.shader.setLayerType( 0, bType ); // blend option
this.shader.setTextureCoordGenMethod( 0, 8 );
this.sfxBaseProcedure = "shifter uscale = 1.0 vscale = 1.0 uspeed = 0.01 vspeed = 0.00";
this.sfxDetailProcedure = "shifter uscale = 1.0 vscale = 1.0 uspeed = 0.008 vspeed = 0.0";
this.shader.setProceduralWithString( 0, this.sfxBaseProcedure );
// initiate detail layer of shader
this.shader.setTexture( 1, dTex ); // set layer texture
this.shader.setLayerSource( 1, 2 ); // use texture
this.shader.setLayerType( 1, dType ); // blend option
this.shader.setTextureCoordGenMethod( 1, 8 );
this.shader.setProceduralWithString( 1, this.sfxDetailProcedure );
// if necessary initiate light map fix
if(bType != 2) {
this.shader.setLayerSource( 2, 0 ); // use diffuse of layer, not texture...
this.shader.setLayerType( 2, 3 );
this.shader.setTextureCoordGenMethod( 2, 8 );
} else {
this.shader.setLayerSource( 2, 0 ); // use diffuse of layer, not texture...
this.shader.setLayerType( 2, 4 );
this.shader.setTextureCoordGenMethod( 2, 11 );
}
}
///////////////////////
// scaling functions //
function scalePlanet(compareIndex, compareScale, baseIndex) {
var modifier = compareScale / planetScale[compareIndex];
//document.write( modifier );
return planetScale[baseIndex] * modifier;
}
function scaleOrbit(compareIndex, compareScale, baseIndex) {
var modifier = compareScale / orbitScale[compareIndex];
return orbitScale[baseIndex] * modifier;
}
function scalePlanetR(index, percentage) {
return planetScale[index] * percentage;
}
function scaleOrbitR(index, percentage) {
return orbitScale[index] * percentage;
}
I've also got orbit scaling and planet size scaling implemented, just had to look up a giant list of sizes and distances on nasa's site. I actually learned a bit about the orbit sizes of our system. All the planetary models you see may have proper planet size ratio, but very likely do NOT have propper orbit scale.
I'm currently using a more exciting skybox for space, as I got bored at looking at stars. When I finish the project I hope to have a real star map texturing the sky.
IF any one is interested in seeing the live demo (that requires wildtangent) just let me know and I'll put it on my public site for viewing.