I was watching the Create a Realistic Earth tutorial by Andrew Price and I was able to follow along in Cycles until I hit the part where he mixes the day and night materials together so that the lights show up on the "dark side" of the earth.

How can I recreate this effect in cycles? I thought I could use the ray information to tell me if there was incoming light but I've found no such node to give me this information.


I have made a little shader that does this. See below for the node setup and a test render.

First there are two shaders, one for the ground (green-brown-noise) and one for the glowing city lights.

Second, there is a mask for the city lights that makes them appear as spots.

Third, and this is answering your question, a value calculated as the dot product between the normal of the planet surface and the vector from the light source to the planet. Very simplified, dot product does this: If they point in the same direction, the dot product will be 1. If they point in opposite direction, dot product is 0. It was a loong time since I studied linear algebra so don't sue me over this.

Fourth, the second mask is multiplied with the third and this is fed as a factor into the mix node that mixes the two materials (land vs city lights).

Node setup. Note how I had to manually calculate the vector for the dot product. In this case (my planet is at 0, 0, 0) it is only the negative value of the light source position.

node setup

Test render:

test render

  • $\begingroup$ Great answer :) As a small note, this is also possible using multiple renderlayers in compositing, however this solution is far nicer. $\endgroup$
    – gandalf3
    Dec 29 '13 at 23:17
  • $\begingroup$ Dot product is actually 0 when perpendicular and -1 when parallel but pointing the opposite direction, i believe. $\endgroup$
    – StarWeaver
    Dec 8 '14 at 10:18
  • 3
    $\begingroup$ No one seems to hardcode dot products in shaders here :D Dot product = lengthA x lengthB x cosine(AB). So for normalized vectors, lengthA x lengthB = 1. The cosine then varies from 1 (same direction) to -1 (opposite directions), 0 being perpendicular vectors. In Blender cycles normals are normalized as in every engine, so using a non normalized vector of length L for light source makes your result stand between L (same direction) and -L (opposite directions). Since Blender uses factors from 0 to 1 the dot product showed here is automatically clamped between those values, so it works :) $\endgroup$
    – Atrahasis
    Jan 18 '16 at 17:29

cycles nodes to mix based on incoming light cycles nodes to mix based on incoming light

  • 4
    $\begingroup$ Please do not rely only on pictures. Posts need text. $\endgroup$
    – David
    Feb 22 '18 at 13:25
  • $\begingroup$ "cycles nodes to mix based on incoming light" Also this is not based on incoming light, it is based on Lamp object position actually $\endgroup$ Feb 26 '20 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.