If you are not interested on the story and how does it works, just skip to the end and enjoy the shader. (Require unity Shader Graph, created on 2018.4.5f1 LWRP)

I have became an indie game developer more than a year. I am still struggling to get a good artistic look of my game. It is pretty hard to learn programming shader especially for a solo indie developer like me. Shader graph is an alternative which is much easier to learn. After a year of exploring the PBR shader graph, I suddenly found that unlit shader graph is the thing I am looking for.

Unlit shaders do not interact with unity light. It is good to use when we are trying to create stylized scene. Each surface of the model has a RGB value on the screen. In this case, we only consider three parameters to compute the RGB value on the screen. The RGB value from UV mapping, the angle of the surface and the color you want to add.

(Actually I combine six similar parameters into one, you will see why)

Now, revise a little bit simple maths:

Every flat surface has a ** normal vector**. A normal vector is just an unit vector perpendicular to its face. An

**has a special property that its magnitude equal to one.**

__unit vector__A vector in 3D space can always written in a form (x,y,z). If you are a developer, you should be pretty familiar (e.g. this.transform.position is written in (x,y,z) form ). Now, lets say we have an unit Vector3 (Î±, Î², Î³). The magnitude of it equals to Î± ^2 + Î² ^2 + Î³ ^2 and also equals to one. If we do a ** dot product** between ( Î±, Î², Î³ ) and ( 1, 0, 0), it will gives us the value of Î±. If we do a dot product between ( Î±, Î² , Î³ ) and ( 0, -1, 0), it will gives us the value of -Î² and so on.

Now, we use this idea to split a RGB into x, y, z direction, just like write a vector into (x, y, z) form. We have RGB = RGB * 1

=> RGB * 1 = RGB * ( Î± ^2 + Î² ^2 + Î³ ^2 )

=>RGB * ( Î± ^2 + Î² ^2 + Î³ ^2 ) = RGB * ( Î± ^2 ) + RGB * ( Î² ^2 ) + RGB * ( Î³ ^2 )

How do we get Î± or Î² or Î³ now?

We do the dot product of a normal vector of a surface with direction vector.

Such as ( 1, 0, 0 ) & ( 0, 1, 0 ) & ( 0, 0, 1 ) & ( -1, 0, 0 ) & ( 0, -1, 0 ) & ( 0, 0, -1 ).

Now you may ask, it sounds trivial since we are doing nothing. RGB is still RGB. What is so interesting here? We can now multiply a custom color separated by axis!!!

*We can do RGB * ( Î± ^2 ) * ColorA + RGB * ( Î² ^2 ) * ColorB + RGB * ( Î³ ^2 ) * ColorC.*

We have actually 6 parameters here because we have 6 direction vectors here. One thing to be careful here is the face normal. Always check the dot product gives a positive value with the direction vectors else it gives the anti-value of the opposite face. Color will cancel out.

I hope this will help you in your project. If I wrote something wrong or you have a better solution, please leave a comment and let me know. I just create this shader today and trying to implement in my project. Feel free to modify the shader on your own.