The Blog

About Me


Marius Oberholster Hey! I'm having an incredible learning experience, not only learning how Blender works (yes, still learning), but also about Open-Source and the incredible software available. Stick around!

Building a formula with nodes

Posted by Marius Oberholster on Wednesday, January 3, 2018 Under: News
Hey all!

Building a formula with nodes is not as hard as it seams, but it can certainly be harder than you think as well.

You have to take quite a few things into account and these make it confusing:
 - Order of operations (will affect result)
 - Vector math functions available
 - Vector math output appropriacy (which output from vector math to use and when)
 - Vector transforms required
 - Vector separation and joinings required (available math functions dependent)
 - Math node functionality
 - Math node functions available

That's the biggest deal to get sorted. I recommend that if you do well to write things out by hand first, to plan out your node system before building it. Sometimes you're, like I was, being led and that means you just go with the HOLY SPIRIT and let HIM decide how, what and when.

On top of this, you also then have to contend with the two areas of a typical NPR shader:
 - Diffuse
 - Specularity
and how to combine these and output them to the mesh, so you can actually see the result.

In this initial stage, Wasili was the expert. He gave me an already diffuse toon shader that output to through the emission shader to get a flat look. This was great, but we need specularity as well. While I personally leave it off for most of the toon materials (it tends to look like shiney plastic to me), it is certainly needed for anything glossy (metals in general or wet things like the tongue, eyes, slimey animals, water surface, etc.).

I was dumbfounded at this point. Wasili then sent me the Phong formula from the Wikipedia page and I built that using the node system. Of course, too many issues to mention, but some were (and still are to a degree):
 - transform stuck to the world origin (solved)
 - minor specularity change whether above or below horizon (unknown cause)
 - camera location not taken into account, freezing specularity in place, just like diffuse (really not good, thankfully solved)
 - attempts at tracking camera location were good, but using the camera data node's location was exactly what the formula ordered, haha - obviously solved, haha.
 - not knowing vector transforms were required to localize the formula to each object (solved)
 - Adding vector math nodes to normalize where needed (Blinn only issue, solved)
 - tracking an empty first instead of the light source itself - later switching to tracking the point lamp, but tracking empties for the sun lamp (explaining that later) - solved!
 - difficulty with the normal maps and bump maps (quickly solved with averaging - praise GOD!)
 - difficulty getting the normals to let the shader show flat (solved)
 - difficulty with the material fading to black based on world horizon (sun lamp issue unresolved atm)
 - preventing the specularity from showing when the light source is behind the shape (solved)

Because we are working with:
 - vectors with three values
 - a vector math node that does not have all the functions we need
 - and two outputs
we will need to sometimes split our vectors in three (X,Y,Z) and apply the next step to all three individually (using math nodes), after which they can be combined again. The reason we can't simply use the math node as if it's a vector node, is because it does not support color. You can try to do some of the calculations using a mix node (also has some good basic math functions as well, but I don't know if it can handle negative values tbh).

How is the diffuse built?
Wasili built the diffuse with a very simple formula:
Diffuse = (N.L)


It's really as simple as that. Of course, in order for it to be localized, it had to be vector transformed to be individualized.

As an example, I want to show you how something can be built.
Let's take 
H = (L+V)/2

Let's built that.
H will end up being the result, so we don't need H, we will get H. We have L (we can and have tracking on our light source's location with drivers on X, Y and Z). We have V from the Camera Data node (it has Location output).

Firstly, we want to keep the splitting of vectors to a minimum (can create a nodal mess very quickly). Thankfully, the brackets we can calculate using the Vector Math node alone. We set it to add and simply plug in our Camera Location and our tracked light source vector.

The Vector Math node does not have a divide. That means we need to split our vector values and go for the math node or try the MixRGB node (I recommend splitting it for negative values - just in case). So we separate them, add a math node for each axis (X, Y and Z), set it to divide (top value is our value to be divided by the bottom or second value) and make the bottom value 2 for each. Then you can combine them. The resulting vector is your H for the rest of the formula.

That's how the whole thing was built - piece by piece.



Of course you get to all manner of technical issues that just don't work in the nodes (or I just don't know how to do them, haha). Such as the max in the formula. I tried adding maximum math nodes and setting them to 0, but this didn't give the desired result of blocking out the specularity when the light source is behind the object. In these cases, you need out of the box solutions, such as masking the specularity with a larger diffuse (has to be larger, since the specularity often overlaps the diffuse borders pre-shadow). Shadows also help, but at this point, I was still using the emission node and shadows are not an option there (there is no in-material shadow pass the end-user has access to without coding - I don't even know of one with coding, though I'm certainly not the one to ask on that, haha). Another great example of difficulty mentioned above is the localization of the vectors. Blender needs vectors transformed in order for them to respond a certain way and this happens on two levels (location and type). And they do make a difference - you can see it visually.

Additional adjustments for features
Math nodes have more functions than just building the formulas. For example, you can make a resulting gradient shrink or grow (such as diffuse size or specularity size) by adding or subtracting. You can broaden or shorten a gradient when you divide or multiply to it. They are there for you to be able to adjust the shader to fit your NPR needs. It can bulk out your UI a lot, but honestly, I think it's worth it!

Now, I do recommend that when you build a formula out, that you check to see if the result is going right. This can be done by connecting your results (as they progress) to an existing shader, like the emission shader for example. It'll give you an unbiased flatness.

Why is the sun so different?
The sun lamp's building was an absolute gift from GOD - just like all the others, but especially this one. I was completely stuck on it's building and how to make it shine from the same direction on every single object and the answer HE gave was so simple - add the coordinates of the light to the normal coordinates. This meant that, to get the right result, the new location had to essentially be in the center of the scene to display correctly for every object (the relative calculation just works that way - I don't know why - GOD does, that's why HE had me do it that way). This also means that our light source coordinates have to be handled relative to the world origin as well, because every object with this shader now effectively sits on (0,0,0). The rotation has to point in the opposite direction of the sun lamp in order for it to shine in the right direction for the sun lamp. To set this up, I had the sun lamp point straight down and the light source be exactly above the world origin. Then it's a matter of copying the rotation of the sun lamp and you don't have to touch the empties again (unless you want to use them to adjust diffuse and specularity size).

Adding them to a scene
Of course, I did cover this in the video, but basically, you just append everything (except the camera). For the point lamp models, this is easier, because you only need the material (it's directly tied to the point lamp). For the sun lamp models, the setup has various empties, and while connected, are not closely enough related for Blender to see it all tied to the material to add only that. You need to append all the objects for the sun lamp (except the camera, unless your scene needs one).

Summary:
 - Point lamp
Appending only the material is needed and assign to an object(s)
 - Sun lamp
Appending all the objects is needed (camera not needed here). Delete the suzanne and assign material.

As an asside, I am still working on the sun lamp issue mentioned above, where the sun dims out based on the rotation of the sun lamp, but I know a solution will be given - GOD has always been faithful and will always be!

In the next post, we'll be looking at what is still planned, what has happened and more!

Biggest thanx to GOD for helping me with this. Without HIM, none of this would be possible! :D

Know JESUS yet?

Have a great one!!!

Thank YOU!!!!!!

In : News 


Tags: god  jesus  holy spirit  blender  anime  toon shaders  eevee  progress  2.8  development 
Social
(+27) 073 104 2834   |   marius.oberholster@gmail.com   |   Contact

Make a free website with Yola