25
$\begingroup$

I'm self-answering this question since I've found the nodes useful and would like to share this with the community since I couldn't really find anything related on it here.


Are there shader nodes / node groups that can be used for basic logic operations in the shader editor, like And, Or and Not?

Since nodes like Math > Greater Than output a 1 or a 0 based on the input conditions, it might be useful to use those outputs in a more logic-oriented fashion with multiple conditions deciding one final answer.

$\endgroup$
4
  • 4
    $\begingroup$ nice posts! just a PS you really did not need the self answer note. $\endgroup$
    – David
    Dec 20, 2019 at 3:38
  • $\begingroup$ @David But it's very laudable. Thank you, OP! $\endgroup$ Dec 20, 2019 at 8:34
  • $\begingroup$ @HeadhunterKev they're not saying the self answer was unnecessary, just the explanation. self answers are an established practice on this network $\endgroup$
    – user371366
    Dec 20, 2019 at 23:04
  • $\begingroup$ I hope I see more of your self-answering posts, because we have got a lot to learn from you. $\endgroup$ Dec 26, 2019 at 3:01

1 Answer 1

48
$\begingroup$

I've spent the past week or so working on basic logic gate implementations in Blender Shader editor. I'm sharing these with the community so anyone who would like to use similar nodes can easily find how to make and use them.
They allow for a little more advanced Shader Node behavior without having to resort to OSL or python scripting.

Here's an overview of the logic gate node groups I've made, along with a .blend file that contains all of them.

Download the .blend file here:

It contains all logic gates discussed in this topic, as well as an example of a 7-segment display and the logic that drives it. You may freely use the contents as you wish, though crediting this post and/or linking back to it would be appreciated.

To use the nodes in your files, open the file you need the nodes in and click File > Append, then open the above .blend file. Navigate to "Materials" and import the Logic Node Library material. This contains all nodes mentioned in this post.

Since the node groups are protected and named, you can add them to your Shader Editor by using Shift+A > Search and entering their names.


Preface

Every logic gate can be made from Not-And or Nand gates. (This also goes for NOR, but I'm not using those).

When implementing logic gates, you first need a Nand gate; with this gate you can make any other gate using solely Nand gates. Most of the gates in this answer are solely composed of Nand gates.

All node groups have inputs that are clamped to a range of 0 to 1. Due to how the Nand gate operates, any value greater than 0 is seen as a logic 1. The Nand gate is also the only gate that utilizes an internal value that surpasses 1; they do binary math with decimal numbers.

The outputs are also clamped to a value between 0 and 1, this makes it easy to chain node groups without losing 'signal' quality.

The terminology I'm using, just for clarification:
1 indicates that the node outputs a True signal.
0 indicates that the node outputs a False signal.

All inputs are noted as capital letters. The output node is named O for most gates.

Outputs of Logic Gate Nodes can be fed into just about any node that accepts values. For instance, connecting the output to a Mix Shader Node fac input allows you to control which shader to use based on your logic. It's effectively a "switch" which allows you to switch between materials based on specific conditions.

The inputs of logic gates can manually be set, or controlled through keyframes.
Another possibility is to split a RGB color value into it's three component color channels and use either one of those values for logic input(since these are also ranged between 0 and 1).

If you have input values that exceed the 0 to 1 range, you can use a Map Range node to map the input range to the output range.


Basic Gates

In this section I'll describe the construction and operation of the four basic logic gates:
- Nand
- Not
- Or
- And

Nand

The Nand gate outputs a 1 unless both inputs are 1, then it outputs a 0.

This is implemented as follows;

A basic Nand gate implementation Both inputs are fed through a Math > Ceil node which rounds the value up to the nearest integer. For 0 this would be 0, for anything between 0 and 1, this would be a 1.

These values are then added together using a Math > Add node, which results in an internal value which is denoted as X in the following truth table:

Truth table:

Nand
A  B  |  O  X
-------------
0  0  |  1  0
0  1  |  1  1
1  0  |  1  1
1  1  |  0  2

The X value is finally passed through a Math > Less Than node which outputs a 1 if the input is less than 2. If the value is 2 it will output a 0. This node is clamped so the output value will never exceed the 0 - 1 range.

Considering every following gate consists of Nand gates that contain both input and output clamps, there is no need to further clamp these nodes.


Or

On to the first compound gate(a gate made from other gates).
This gate outputs a 1 when either of its inputs, or both, are 1. If all inputs are 0, it'll output a 0.

Truth table:

Or
A  B  |  O
----------
0  0  |  0
0  1  |  1
1  0  |  1
1  1  |  1

The node group consists of three Nand gates: enter image description here


Not

This node has a pretty simple effect; it inverts the input. Is the input a 1, then it'll output a 0 and vice versa.

It is constructed from one NAND gate with both inputs linked to the group input node. enter image description here

Truth table:

Not
A  |  O
----------
0  |  1
1  |  0

And

Finally, the last basic logic gate(and perhaps one of the most useful ones): And. This gate outputs a 1 only if both inputs are 1. Else, it'll output a 0.

Truth table:

And
A  B  |  O
----------
0  0  |  0
0  1  |  0
1  0  |  0
1  1  |  1

It consists of a Nand gate linked to a Not gate. Remember how Nand stands for Not-And? This gate effectively is Not-Not-And. enter image description here


Other gates

With these four basic gates, you can construct gates that exhibit more complex behavior. I'll describe three gates:
- Nor
- Xnor
- Xor


Nor

This gate is a bit like the opposite of an And gate; its output is only 1 if all inputs are 0. Else, the output is 0.

Truth table:

Nor
A  B  |  O
----------
0  0  |  1
0  1  |  0
1  0  |  0
1  1  |  0

This gate can be used as a last option for conditions; this gate activates only if none of the inputs are active.

It consists of an Or and a Not gate: enter image description here


Xnor

The Xnor gate outputs a 1 if both inputs are equal. Are they different? Then it'll output a 0.

Truth table:

Nor
A  B  |  O
----------
0  0  |  1
0  1  |  0
1  0  |  0
1  1  |  1

It is constructed like so:
enter image description here


Xor

Finally, Xor is a gate that outputs a 1 only if both inputs are not equal. It's like the inverse of the Xnor gate.

Truth table:

Nor
A  B  |  O
----------
0  0  |  0
0  1  |  1
1  0  |  1
1  1  |  0

enter image description here


More complex components

In the Blender Shader engine I wouldn't expect things like binary adders and 7 segment drivers to be useful.
Singular gates operating on a few inputs are likely way more useful. I've implemented them anyway; since they're fairly complex I will not explain how they are constructed. Instead, see the attached .blend file for more information.

Included in this file are the previously named base gates, a few gates with multiple inputs (things like And with 4 inputs), adders(half, full and 4 bit) and some groups related to handling Blender's decimal numbers.

enter image description here enter image description here

Here's a quick description of these gates:

The DecimalToBinary node group converts the value on a single input to a 4-bit binary value (0000 - 1111 or 0 - 15). Currently, this only actually supports numbers 0 - 9, since the 4th bit is needed to be able to count to 9. The values 10-15 are not used. I'll add this to the post as soon as I've found a solution for this.

The input value is passed through the DecToDigits node, which converts a singular value to 10 output values (Y0 - Y9).
These effectively convert a number to their digits; 4 would turn output Y4 on and leave the rest off, 8 turns Y8 on and leaves the others off, and so on.

These values are passed to the DigitToBin group which converts the digits to a 4-bit binary number (again, only 0-9 for now) using a fairly complicated node group.

In the .blend file I've also included a WIP 7-segment shader which controls a single digit based on the (keyframe-driven) input value, which is passed through the DecimalToBinary node group. Currently every digit has its own material to account for decimals and hundreds, tens, ones. I hope to find a better solution for this since every material on its own contains about 800 nodes.
The whole display encompasses about 4000 nodes!
This is also included as an example; choose Play Animation to see the display count up. This works best in Cycles render, though LookDev also works but is a lot less responsive.

enter image description here

In terms of performance, I haven't noticed any performance slowdowns when using a few of them here and there in my materials. In the 7-segment shader however, there are 4000 nodes in use which noticeably slows down animation speed to about 1 fps.

Again, if you only use a few of these nodes performance shouldn't be an issue.

In conclusion

Boolean logic is absolutely possible within Blender's Shader editor and may prove useful for making certain materials, like switching shaders or colors based on a keyframed value.
Things like binary computation are also possible, though that is not the focus of this post.

I'm sure people can find interesting applications of these nodes!
I will also add examples of the basic nodes later so you can see what they can be used for.

$\endgroup$
10
  • 9
    $\begingroup$ Damn. That's one thorough answer :). Thanks for investing your time into this, I'm sure many others will find it useful. $\endgroup$ Dec 19, 2019 at 13:51
  • 1
    $\begingroup$ Got my upvote just for the insane and seemingly stupid effort you take on this. Implementing an own node would possibly have been easier than this. $\endgroup$ Dec 19, 2019 at 22:47
  • 5
    $\begingroup$ As a computer scientist, I'm used to thinking about Boolean operators as being restrictions to {0, 1} of polynomials. You have: a AND b = ab; a OR b = a + b - ab; NOT a = 1 - a, XOR = a + b - 2ab. You could get the same results on {0, 1} inputs with fewer nodes by using these formulae. You could add in the Greater Than node on the inputs if you want to preserve the "anything greater than zero is true" behavior, although the polynomial interpretations are also used for continuous values in probability and fuzzy logic. $\endgroup$ Dec 20, 2019 at 16:31
  • 1
    $\begingroup$ The operator f(a, b) = a + b - ab is in some sense the "natural" continuous extension of the Boolean OR operator. It is actually called probabilistic OR, because if a and b are the probabilities of independent events occurring, then f(a, b) gives the probability that at least one of a or b occurs. ab and 1 - a are of course the probabilistic analogues for Boolean AND and NOT, respectively. $\endgroup$ Jan 3, 2020 at 20:45
  • 1
    $\begingroup$ if i play the animation, i hoped to see numbers in the ones and tens and so on. But just single segments were highlighted. Do i have to do more than play the animation? $\endgroup$
    – Chris
    Jun 5, 2021 at 15:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .