The new Universal Centennial Logo which you might have already seen in the cinema this year. Great CG by Weta Digital:
A journey to create a CG model of our beautiful
home planet
while learning more about
its wonders along the way...
Topics
- atmosphere (5)
- clouds (3)
- making-of (8)
- moon (1)
- night (5)
- ocean (3)
- research (16)
- scattering (4)
- shaders (5)
- specular (3)
- terminator (3)
- WIPshots (21)
Wednesday, September 12, 2012
Sunday, September 9, 2012
Making of a Planet - Part 4 - Simple atmosphere shader
Here's a good place to start if you need some instant texture maps for creating a CG Earth: JHT's Planetary Pixel Emporium. The color, bump and specular maps are self-explanatory, although in my case I'm using true displacements instead of bump. You can also get the Blue Marble textures from NASA's Visible Earth here.
The tricky part is to create the Earth's atmosphere. From reference photos, we can see that due to the curvature of the planet, the atmosphere appears more visible along the circumference compared to the center.
To achieve this effect, we can make use of the facing ratio of the surface toward the camera. Referring to the diagram below, when the view vector and the surface normal is in line, the facing ratio is 1, when they are perpendicular, the facing ratio is 0. Surfaces that face away from the camera are not rendered, so need not be considered. As such, the facing ratio at any point always fall between 0 and 1:
There are different ways to obtain the facing ratio. Maya has a very useful Sampler Info utility node which will provide that information. In Houdini, it is simple to build using the Eye vector (I) and the surface Normal vector (N). Just do a dot product, which will give you the cosine of the angle between them as long as the vectors are normalized. When the angle is 0° (I aligned with N), the cosine is 1. When the angle is 90° (I perpendicular to N), the cosine is 0°. Remember to normalize both N and I, and also, since I is the direction from Eye (camera) to the surface, it has to be negated. Finally, an Absolute node is used to ensure that the output values are positive. The SHOP network is shown below:
The network above will shade any object as if there is a headlight attached to the camera (surfaces facing the camera are brighter and surfaces facing away are darker). From there, we will adjust the output into a suitable type and range using a bit of math. The diagram below illustrates what we are trying to achieve:
The following SHOP network does exactly the above:
The Complement node inverts the black and white facing ratio, and the Power node (exponent of 6 used in this example) adjusts the intensity. A Constant of type "color" set to a suitable shade of blue is multiplied with the output of the Power node to get the blue tinted version, which is then output as the Surface Color. The output from the Power node is fed into the Surface Opacity output to allow for transparency.
Let's apply this shader to a new sphere object slightly larger (1% larger in this example, using a uniform scale factor of 1.01) than the original Earth sphere :
Of course, this is just a starting point. There is immediately the problem of the atmosphere being lit even along the shadowed side of the Earth. This is easily remedied by multiplying the output color by a shadow term, or by a self-shadowing diffuse shader such as Lambert:
![]() |
The example below uses a Lambert diffuse intensity of 2 |
While this is more physically correct, the previous unshadowed version looks aesthetically more pleasing, which is why many planetary artists invoke artistic license to bend the laws of physics. Alas, our goal is photorealism, so we will stick with the correct look for this kind of exposure levels. Just remember it is a viable option because the stars (and sometimes the Moon) always provide faint illumination to the night side of the Earth.
Long way to go...
There's still so much that needs to be done to improve the quality of my CG Earth, and I've been exploring options and learning that I really don't have enough know-how to get there yet.
Clouds are the biggest challenge and I've never been happy with my solution, so I'm going back to the drawing board with them. It's a tough nut to crack so it might be a while before I can achieve a proper cloud-filled Earth.
Next, surface detail. Considering I'm using at best 500m/pixel data from BMNG, I began experimenting with adding fractal noise to the displacement and other channels in the hopes of being able to do more close-up shots.
Since I'm starting with a displacement map, just adding displacement noise without regard for the existing topography will result in very artificial output - the same way that simply combining multiple orders of fBm noise will not make a fractal landscape look natural. I'm convinced I need some kind erosion algorithm (fractal, hydraulic, thermal...) but I haven't been able to find any good reference on the subject.
Sometimes when I look up one subject, I find that I need to understand several other topics before I can proceed. Other times, one subject leads to several other related issues that I had not been aware of. There's so much to study, understand and implement that I have to become less of an artist and more a weekend programmer, mathematician and scientist. Gradually, I hope to summarize what I've learnt that is relevant to the CG Earth project within the pages of this blog.
Meanwhile, here's another WIP shot. It has subtly better atmosphere and surface detail than a similar shot I created last year.
Clouds are the biggest challenge and I've never been happy with my solution, so I'm going back to the drawing board with them. It's a tough nut to crack so it might be a while before I can achieve a proper cloud-filled Earth.
Next, surface detail. Considering I'm using at best 500m/pixel data from BMNG, I began experimenting with adding fractal noise to the displacement and other channels in the hopes of being able to do more close-up shots.
Since I'm starting with a displacement map, just adding displacement noise without regard for the existing topography will result in very artificial output - the same way that simply combining multiple orders of fBm noise will not make a fractal landscape look natural. I'm convinced I need some kind erosion algorithm (fractal, hydraulic, thermal...) but I haven't been able to find any good reference on the subject.
Sometimes when I look up one subject, I find that I need to understand several other topics before I can proceed. Other times, one subject leads to several other related issues that I had not been aware of. There's so much to study, understand and implement that I have to become less of an artist and more a weekend programmer, mathematician and scientist. Gradually, I hope to summarize what I've learnt that is relevant to the CG Earth project within the pages of this blog.
Meanwhile, here's another WIP shot. It has subtly better atmosphere and surface detail than a similar shot I created last year.
![]() |
2012 version with better terrain detail, specular (rivers) and atmospherics (no more volumetric hack). |
![]() |
2011 version, took some hacking to get it looking like this. |
Wednesday, August 22, 2012
Another making-of
Ever wondered about the Earth image on the screen background of every new iPhone? Turns out it's another Blue Marble image and here is an article on how it's made written by the artist Robert Simmon himself: Crafting the Blue Marble.
Sunday, August 19, 2012
Iconic Earth images
While researching, I stumbled across this great article about 10 Iconic Images of the Earth from Space. Images featured include the Blue Marble and the Pale Blue Dot.
One of the most iconic photos ever is the Earthrise taken by astronaut William Anders on Dec 24, 1968 during the Apollo 8 mission. To quote Anders: "We came all this way to explore the Moon, and the most important thing is that we discovered the Earth"
In 2007, JAXA (Japan Aerospace Exploration Agency) launch a lunar orbiter SELENE (nicknamed Kaguya after the moon princess from Japanese folklore) whose on-board HDTV cameras recorded high-definition video footage of a newer Earthrise:
We are indeed lucky to be living at a time when technology allows us to appreciate our home planet from a perspective that must have once been unimaginable.
One of the most iconic photos ever is the Earthrise taken by astronaut William Anders on Dec 24, 1968 during the Apollo 8 mission. To quote Anders: "We came all this way to explore the Moon, and the most important thing is that we discovered the Earth"
The first public image of an Earthrise from Moon orbit (Dec 24, 1968) |
In 2007, JAXA (Japan Aerospace Exploration Agency) launch a lunar orbiter SELENE (nicknamed Kaguya after the moon princess from Japanese folklore) whose on-board HDTV cameras recorded high-definition video footage of a newer Earthrise:
We are indeed lucky to be living at a time when technology allows us to appreciate our home planet from a perspective that must have once been unimaginable.
Wednesday, August 15, 2012
Shader upgrades ^^
Necessity can be a great motivator. A recent freelance opportunity meant I had to create much faster shaders to get the job done in time. I dove head first into VEX code writing for the first time, and managed to adapt Sean O'Neil's real-time atmospheric scattering algorithm into my new Earth shaders.
My method uses the CPU instead of GPU and is not real-time, but is still multiple times faster than my old method while looking visually very similar. Some volumetric shadow effect is lost, but not really noticeable if you are not looking for it, and the amount of speed up is well worth tradeoff.
Naturally, the implementation is not straightforward and took me almost 3 days to get it working properly. Perhaps I'll post more details under the "making-of" label in future.
My method uses the CPU instead of GPU and is not real-time, but is still multiple times faster than my old method while looking visually very similar. Some volumetric shadow effect is lost, but not really noticeable if you are not looking for it, and the amount of speed up is well worth tradeoff.
Naturally, the implementation is not straightforward and took me almost 3 days to get it working properly. Perhaps I'll post more details under the "making-of" label in future.
Making of a Planet - Part 3 - Shader Basics
In this post I'll be describing what I learnt about shaders when building the CG Earth, with specific examples of Houdini VEX shader networks. First off, a quick introduction to how shaders work.
Shaders are actually program code written in a shading language. However, Houdini allows the code to be build visually as a node network (called a SHOP network, for SHader OPerators). The most famous industry shader language for rendering CGI is the RenderMan shading language. For real-time graphics (e.g. games and 3D applications) you will hear names like GLSL and HLSL. Houdini's shading language is called VEX (Vector EXpressions).
Regardless of shading language used, the simplest shader returns a constant color at every point, making the object appear uniformly flat. In the following example, a constant color blue is being fed into the surface output of a Material Shader Builder node in Houdini's SHOP network:
Let's consider how light may affect how the surface looks.
The following example is the basic Lambert shader (which mathematically is the dot product of the normalized surface normal vector, N, and the normalized light vector, L). It's amazingly elegant that this single dot product formula is enough to describe how the light falls off a surface depending on its angle to the light source:
So we now have a properly lit teapot, but what if we want it in blue color? All we need to do is to multiply the result of the illuminance loop with a constant (blue color) before passing it to the output:
Houdini already includes a selection of basic CG shaders (such as Lambert) as a network node so we don't really need to create our own illuminance loops. However, writing your own illuminance loop function allows specific low-level control over the look of your material. For the Earth shader, I adapted a light wrap shader inside the illuminance loop to simulate atmospheric scattering.
The example below is a slightly more complex shader including specular highlights and texture mapping, but the basic concept is the same as the previous examples. Notice that the texture map (diffuse color) is multiplied with the Lambert shading, and the specular is added to the results.
Shader writing may not be everyone's cup of tea, but with some effort anyone can write their own shader. There's a definite amount of mathematics and logical thinking involved, but with it comes the power to go beyond what is available off-the-shelf.
If you're keen to find out more, I recommend the following books:
1) Texturing and Modeling: A Procedural Approach
2) The RenderMan Companion: A Programmer's Guide to Realistic Computer Graphics
3) Advanced RenderMan: Creating CGI for Motion Pictures
That's it for today. Next post I'll elaborate more about my Earth shaders.
What are Shaders?
Shaders can be thought of a set of program instructions that tells a renderer how to determine the color of a surface (or volume) at any given location. In 3D programs, they are also referred to as materials.Shaders are actually program code written in a shading language. However, Houdini allows the code to be build visually as a node network (called a SHOP network, for SHader OPerators). The most famous industry shader language for rendering CGI is the RenderMan shading language. For real-time graphics (e.g. games and 3D applications) you will hear names like GLSL and HLSL. Houdini's shading language is called VEX (Vector EXpressions).
Regardless of shading language used, the simplest shader returns a constant color at every point, making the object appear uniformly flat. In the following example, a constant color blue is being fed into the surface output of a Material Shader Builder node in Houdini's SHOP network:
![]() |
The constant shader instructs the renderer... |
![]() |
...to use the same color for every point on the surface |
Let's consider how light may affect how the surface looks.
The following example is the basic Lambert shader (which mathematically is the dot product of the normalized surface normal vector, N, and the normalized light vector, L). It's amazingly elegant that this single dot product formula is enough to describe how the light falls off a surface depending on its angle to the light source:
![]() |
A classic Lambertian shader... |
![]() |
...makes the teapot surface react correctly to light |
Lighting Inside a Loop
In Houdini, this lighting calculation must take place inside what is called an illuminance loop. A loop in computer programming is a sequence of instructions that repeats itself until particular conditions are met. Think of it as repeatedly calculating the same lighting formula (dot product) for all the points on the surface that appears in the final image, using the corresponding N and L vectors for each point location.So we now have a properly lit teapot, but what if we want it in blue color? All we need to do is to multiply the result of the illuminance loop with a constant (blue color) before passing it to the output:
![]() |
The Lambert shading network from before is actually hidden inside the illuminance loop node above |
![]() |
Only one dot product and one multiplication is needed to get this blue teapot |
Houdini already includes a selection of basic CG shaders (such as Lambert) as a network node so we don't really need to create our own illuminance loops. However, writing your own illuminance loop function allows specific low-level control over the look of your material. For the Earth shader, I adapted a light wrap shader inside the illuminance loop to simulate atmospheric scattering.
Building Visual Complexity
When shaders take into account various factors such as lighting and texturing, more complex looks can be achieved. Notice also how we can take the first two separately rendered images (the constant blue and the grayscale lit teapots) and combine them using a multiply blending in a 2D program to get the same results (blue lit teapot). Therein lies the flexibility and power of render passes and compositing, because we can tweak the amount of blending without having to re-render in 3D.The example below is a slightly more complex shader including specular highlights and texture mapping, but the basic concept is the same as the previous examples. Notice that the texture map (diffuse color) is multiplied with the Lambert shading, and the specular is added to the results.
![]() | |
No illumination loop used here |
![]() |
More complex shaders will result in more realistic surface appearance |
Shader writing may not be everyone's cup of tea, but with some effort anyone can write their own shader. There's a definite amount of mathematics and logical thinking involved, but with it comes the power to go beyond what is available off-the-shelf.
If you're keen to find out more, I recommend the following books:
1) Texturing and Modeling: A Procedural Approach
2) The RenderMan Companion: A Programmer's Guide to Realistic Computer Graphics
3) Advanced RenderMan: Creating CGI for Motion Pictures
That's it for today. Next post I'll elaborate more about my Earth shaders.
Subscribe to:
Posts (Atom)