Page 1 of 1

How to render a planet?

Posted: Sat May 13, 2006 10:56 pm
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

Posted: Sat May 13, 2006 11:05 pm
by Kencho
What *exactly* do you want to do? 2D/3D? Which particular effects? :?

Posted: Sat May 13, 2006 11:08 pm
by vgmdev
Make a 3D Earth in ogre, and for effects ah, day and night textures, the works.

Posted: Sun May 14, 2006 11:46 am
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 ;)

Posted: Sun May 14, 2006 1:18 pm
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.

Posted: Sun May 14, 2006 3:33 pm
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.

Posted: Sun May 14, 2006 5:10 pm
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)

Posted: Sun May 14, 2006 10:46 pm
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 ;)

Posted: Mon May 15, 2006 1:38 am
by vgmdev
I have download RenderMonkey today (50MB on 56k... grrr)
Basically that is what I would like.
Image

Posted: Mon May 15, 2006 2:01 am
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);
}

Posted: Mon May 15, 2006 10:59 am
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 ;)

Posted: Mon May 15, 2006 5:25 pm
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.

Posted: Mon May 15, 2006 8:55 pm
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?

Posted: Mon May 15, 2006 11:56 pm
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 ;)

Posted: Tue May 16, 2006 12:03 am
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
			}
		}
	}
}