# How can I mix two materials based on incoming light

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. Test render: • Great answer :) As a small note, this is also possible using multiple renderlayers in compositing, however this solution is far nicer. – gandalf3 Dec 29 '13 at 23:17
• Dot product is actually 0 when perpendicular and -1 when parallel but pointing the opposite direction, i believe. – StarWeaver Dec 8 '14 at 10:18
• 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 :) – Atrahasis Jan 18 '16 at 17:29 cycles nodes to mix based on incoming light

• Please do not rely only on pictures. Posts need text. – David Feb 22 '18 at 13:25