From Unify Community Wiki
Jump to: navigation, search
The Earth/Planet shader with a milky way backdrop.
Suggested settings to produce this screenshot.

Author: Julien Lynge



A shader originally designed for the Earth, though it can be used for any planet. This shader is a modification of code produced by the Strumpy Shader Editor. The original tutorial for creating the earth (minus night lights and night-side coloring) can be found at

The corresponding cloud shader can be found at, along with a complete Unity package with the shaders, textures, and a camera script for reproducing the screenshot at right.


If you're looking for Earth textures to use with this shader, we used Blue Marble (from NASA) as the Earth texture. You can find black & white topo images (which you can import to Unity as bump maps) and nighttime lights many places; here's an example:


Day and night lighting.

The night side of the earth is ever-so-slightly desaturated (greyed-out) and tinted blue. Both of these effects are very subtle, so feel free to play with these numbers. The corresponding lines are:

   c.g -= .01 * s.Alpha; //lower green by .01 on the dark side - desaturate
   c.r -= .03 * s.Alpha; //lower red by .03 on the dark side - desaturate
   c.b = saturate(c.b + s.Alpha * .02); //raise blue by .02; saturate() clamps the value between 0 and 1

Night lights.

Lights appear on the dark side and fade in during 'dusk'. The code that sets this is

   half invdiff = 1 - saturate(16 * diff); //change the '16' to adjust how far dusk should extend)

Lights are tinted slightly yellow. The two lines below apply the rgb of the lights to the world:

   c.rg += min(s.Custom, s.Alpha);
   c.b += 0.75 * min(s.Custom, s.Alpha);

If you want the lights to be white, just get rid of the 'c.b' line and make the other 'c.rgb'. If you want them bright yellow, get rid of the 'c.b' line with no change to the other line.

Bump map

Supports a bump map for mountains and other features. The bump is taken into account with night lights (e.g. cities that are behind mountains 'turn on' earlier than those atop mountains - each changes when it becomes 'dark.'

Atmospheric shading

A slight light scattering due to the atmosphere is created at the edges of the planet. The color and intensity can be set from the inspector.

The Shader

Invalid language.

You need to specify a language like this: <source lang="html4strict">...</source>

Supported languages for syntax highlighting:

4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, algol68, apache, applescript, apt_sources, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, f1, falcon, fo, fortran, freebasic, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, j, java, java5, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, objeck, ocaml, ocaml-brief, oobas, oracle11, oracle8, oxygene, oz, pascal, pcre, per, perl, perl6, pf, php, php-brief, pic16, pike, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, uscript, vala, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic

    Shader "TerraViz/Earth-NightLights"

      //Earth Shader created by Julien Lynge @ Fragile Earth Studios
      //Upgrade of a shader originally put together in Strumpy Shader Editor by Clamps
      //Feel free to use and share this shader, but please include this attribution

    _MainTex("_MainTex", 2D) = "black" {}
    _Normals("_Normals", 2D) = "black" {}
    _Lights("_Lights", 2D) = "black" {}
    _LightScale("_LightScale", Float) = 1
    _AtmosNear("_AtmosNear", Color) = (0.1686275,0.7372549,1,1)
    _AtmosFar("_AtmosFar", Color) = (0.4557808,0.5187039,0.9850746,1)
    _AtmosFalloff("_AtmosFalloff", Float) = 3




    Cull Back
    ZWrite On
    ZTest LEqual
    ColorMask RGBA

    #pragma surface surf BlinnPhongEditor
    #pragma target 2.0

    sampler2D _MainTex;
    sampler2D _Normals;
    sampler2D _Lights;
    float _LightScale;
    float4 _AtmosNear;
    float4 _AtmosFar;
    float _AtmosFalloff;

          struct EditorSurfaceOutput {
            half3 Albedo;
            half3 Normal;
            half3 Emission;
            half3 Gloss;
            half Specular;
            half Alpha;
            half4 Custom;

          inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
    half3 spec = light.a * s.Gloss;
    half4 c;
    c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
    c.g -= .01 * s.Alpha;
    c.r -= .03 * s.Alpha;
    c.rg += min(s.Custom, s.Alpha);
    c.b += 0.75 * min(s.Custom, s.Alpha);
    c.b = saturate(c.b + s.Alpha * .02);
    c.a = 1.0;
    return c;


          inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
            half3 h = normalize (lightDir + viewDir);

            half diff = max (0, dot ( lightDir, s.Normal ));

            float nh = max (0, dot (s.Normal, h));
            float spec = pow (nh, s.Specular*128.0);

            half4 res;
            res.rgb = _LightColor0.rgb * diff;
            res.w = spec * Luminance (_LightColor0.rgb);
            res *= atten * 2.0;

        //s.Alpha is set to 1 where the earth is dark.  The value of night lights has been saved to Custom
        half invdiff = 1 - saturate(16 * diff);
        s.Alpha = invdiff;

            return LightingBlinnPhongEditor_PrePass( s, res );

          struct Input {
            float3 viewDir;
    float2 uv_MainTex;
    float2 uv_Normals;
    float2 uv_Lights;


          void surf (Input IN, inout EditorSurfaceOutput o) {
            o.Gloss = 0.0;
            o.Specular = 0.0;
            o.Custom = 0.0;
            o.Alpha = 1.0;

        float4 Fresnel0_1_NoInput = float4(0,0,1,1);
        float4 Fresnel0=(1.0 - dot( normalize( float4( IN.viewDir.x, IN.viewDir.y,IN.viewDir.z,1.0 ).xyz), normalize( ) )).xxxx;
        float4 Pow0=pow(Fresnel0,_AtmosFalloff.xxxx);
        float4 Saturate0=saturate(Pow0);
        float4 Lerp0=lerp(_AtmosNear,_AtmosFar,Saturate0);
        float4 Multiply1=Lerp0 * Saturate0;
        float4 Sampled2D2=tex2D(_MainTex,IN.uv_MainTex.xy);
        float4 Add0=Multiply1 + Sampled2D2;
        float4 Sampled2D0=tex2D(_Normals,IN.uv_Normals.xy);
        float4 UnpackNormal0=float4(UnpackNormal(Sampled2D0).xyz, 1.0);

        o.Albedo = Add0;
        o.Normal = UnpackNormal0;
        //o.Emission = Multiply0;
            o.Emission = 0.0;

            //float4 Multiply0=Sampled2D1 * _LightScale.xxxx;
        o.Custom = tex2D(_Lights,IN.uv_Lights.xy).r * _LightScale;

            o.Normal = normalize(o.Normal);
      Fallback "Diffuse"
Personal tools