How to render a planet?

The place for artists, modellers, level designers et al to discuss their approaches for creating content for OGRE.
Post Reply
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

How to render a planet?

Post by vgmdev »

I have not a clue how to do a planet with some nice effects…
I’m attempting to do earth with the blue marble textures and of course blender, gimp and good old ms-paint as my tool set.

Now I found a nice tutorial how to make one in Photoshop.
http://gallery.artofgregmartin.com/tuts ... lanet.html
Image
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

What *exactly* do you want to do? 2D/3D? Which particular effects? :?
Image
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

Post by vgmdev »

Make a 3D Earth in ogre, and for effects ah, day and night textures, the works.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

Well, for the day and night textures I would take this approach (haven't tried myself but I'm sure it can be done). Two textures: Night and day, the former under the second, and for the day texture, use a mask (in this case, a white lit pass, so that when it's lit, the day texture is shown, and when it isn't, the night texture is shown)

PS: The night texture/pass will need to be unlit or have it's emissive values the highest the possible ;)
Image
guy_iti
Halfling
Posts: 53
Joined: Mon Oct 17, 2005 2:11 pm
Location: Thessaloniki - Greece
Contact:

Post by guy_iti »

Hi,
Unfortunately, if you plan to move around the planet, or to have the planet rotating, you will have to go for complex shader if you want a result as shown :
the illumination technique for planets is not a regular one, as the illuminated part "spreads" more than what Lambert of Phong would give.
For better explanation, have a look at this tutorial :
http://www.highend3d.com/maya/tutorials ... 176-2.html.
The way to do it (in a 3D anim. soft like Maya) will be by using the "facing ratio" of the faces, meaning the angle between the face normal and the light direction (technique identical to the "microscope-type" shaders) to illuminate the object.

I'm sure you can create the same technique as a hardware shader ...

For the day/night, --> Kencho technique, using the above illumination trick.

Keep us posted, I'm interested in the possible results ...
Guy.
Van
Hobgoblin
Posts: 512
Joined: Fri Nov 19, 2004 3:56 am
Contact:

Post by Van »

we use the createSphere() from the Ogre Wiki.

What we do is create three spheres. All three spheres are centered at the same location and each sphere is slightly larger than the previous:

Small/Inner sphere as the water/land mass.
Middle sphere as the clouds.
Largest/Outter shere as the outter atmosphere.

Each sphere gets their appropriate texture. What's nice is you can then control the effects of each sphere. We rotate the inner sphere and we also roteate the middle sphere at different speeds. We use textures and a light source coupled with shaders for night and day effects.
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

Post by vgmdev »

Your link does not exist but a shadier has worked for some but I can't find one. I think RenderMonkey has an example. Of course the day and night textures will be the easiest to do.

Then we will have to deal with the atmosphere...

Using 3 spheres will be too costly. 8)
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

The atmosphere "halo" can be tricked with a slightly larger billboard centered in the sphere. And you can use a vertex shader to "shadow" the dark part if it's seen in profile... That's the easiest and cheapest way to do it ;)
Image
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

Post by vgmdev »

I have download RenderMonkey today (50MB on 56k... grrr)
Basically that is what I would like.
Image
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

Post by vgmdev »

Well... the code is GLSL :?

Vertex Shader

Code: Select all

// Earth vertex shader computes lighting coefficients.
//
// Note: For optimal light animation set the RenderMonkey cycle time 
// for predefined variables to 20 seconds.  (Found in the Edit->Preferences).

// predefined variables used to animate light direction
uniform float cos_time_0_2PI, sin_time_0_2PI;

// artist variable to control season
uniform float season;

// varying variables passed to fragment shader
varying float Diffuse;
varying vec3  Specular;
varying vec2  TexCoord;

void main(void)
{
    // calculate vertex position in eye coordinates
    vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
    
    // compute the transformed normal
    vec3 tnorm      = normalize(gl_NormalMatrix * gl_Normal);

    // compute the light vector pointing toward the sun, in model coordinates
    // x,y compose the longitude and z the (seasonal) lattitude of the nadir point.
    vec3 lightVec = normalize(gl_NormalMatrix * vec3(cos_time_0_2PI, season,sin_time_0_2PI));

    // compute the reflection vector
    vec3 reflectVec = reflect(-lightVec, tnorm);
    
    // compute a unit vector in direction of viewing position
    vec3 viewVec    = normalize(vec3 (-ecPosition));

    // Calculate specular light intensity, scale down and
    // apply a slightly yellowish tint. 
    float specIntensity = pow(max(dot(reflectVec, viewVec), 0.0), 8.0);
    specIntensity       = 0.3 * specIntensity; 
    Specular            = specIntensity * vec3 (1.0, 0.941, 0.898);
    
    // Calculate a diffuse light intensity
    Diffuse             = dot(lightVec, tnorm);

    // Pass texture coordinates fragment shader
    TexCoord    = vec2 (gl_MultiTexCoord0);
    TexCoord.x  = TexCoord.x;
    
    // output final vertex information
    gl_Position     = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Fragment Shader

Code: Select all

// Earth fragment shader blends day/night/cloud/gloss textures based on local time of day.

uniform sampler2D EarthDay, EarthNight, EarthCloudGloss;
uniform bool cloudCover;

varying float Diffuse;
varying vec3  Specular;
varying vec2  TexCoord;

const float Terminator = 0.3;
const float InvTerminator = 1.0 / (2.0 * Terminator);

void main (void)
{
    // separate maps are packed into the color components of this texture
    // clouds.r = cloud opacity
    // clouds.g = water glossiness
    vec2  cg     = texture2D(EarthCloudGloss, TexCoord).rg;
    float clouds = cg.r * float(cloudCover);
    float gloss  = cg.g;

    // load daytime color, plus a specular component modulated by the gloss map  
    vec3 daytime   = texture2D(EarthDay, TexCoord).rgb * Diffuse + Specular * gloss;
    
    // mix in diffusely-lit clouds, modulated by the cloud opacity
    daytime = mix(daytime, vec3(abs(Diffuse)), clouds);

    // load night image, modulated by cloud opacity
    vec3 nighttime = texture2D(EarthNight, TexCoord).rgb * (1.0 - clouds);

    // assume day, to start
    vec3 color = daytime;
 
    // if fully dark, select night
    if (Diffuse < -Terminator)
    {
        color = nighttime;
    }

    // within the twilight zone, mix night/day
    if (abs(Diffuse) < Terminator )
    {
        color = mix(nighttime, daytime, (Diffuse + Terminator) * InvTerminator);
    }
    
    gl_FragColor = vec4 (color, 1.0);
}
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

It's basically what I proposed you, but done in a single pass through a shader. You choose: To run in older cards but worse performance with multiple textures or passes, or better performance but shader-capable cards with the shader method ;)
Image
User avatar
BlasterN
Gnome
Posts: 378
Joined: Thu Mar 24, 2005 1:07 am
Location: Spain
Contact:

Post by BlasterN »

My point of view.

Create a material with three passes.
Pass 1. 2 textures (day & night)
Pass1. Shader: Pass the near light diffuse. And with that value mix the two textures.
Pass 2. 1 texture. The clouds.
Pass 2. Shader. A little noise to muve the clouds (if you want it) maybe passing time_0_x
Pass 3. Glow shader

easy eh ?!
You can find glow shader in rendermokey, noise in the postfilters (i think) and you can start with the Celshadding shader to do the mix shader.
Works:
MapToMesh | Bengine B9 @ www.sourceforge.net/projects/maptoogremesh/
3DWorldStudio exporter@ www.blastern.info
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

Post by vgmdev »

Kencho wrote:It's basically what I proposed you, but done in a single pass through a shader. You choose: To run in older cards but worse performance with multiple textures or passes, or better performance but shader-capable cards with the shader method ;)
Where can I find that shader at?
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

You posted it above :) Ogre supports GLSL, so I think you won't have any problems using it. I'm a newbie in shaders though, so I can't help much more in that field ;)
Image
User avatar
vgmdev
Greenskin
Posts: 110
Joined: Tue Feb 08, 2005 2:58 am
Location: MI, USA

Post by vgmdev »

Yes I’m a newbie with shaders too, its like unlearning BASIC :shock: , and then learn C++ with OO....

Well, the only thing left to do is the .material script.

Code: Select all

material Earth
{
	technique
	{
		pass
		{

			texture_unit
			{
				texture Earth.jpg
				texture EarthNight.jpg
				texture EarthClouds.jpg
			}
		}
	}
}
Post Reply