Extensions
  • Home
  • Add-ons
  • Themes
  • Approval Queue
  • About
  • Upload Extension
  • Sign in
  • BLENDER.ORG

    • Download

      Get the latest Blender, older versions, or experimental builds.

    • What's New

      Stay up-to-date with the new features in the latest Blender releases.

    LEARNING & RESOURCES

    • Blender Studio

      Access production assets and knowledge from the open movies.

    • Manual

      Documentation on the usage and features in Blender.

    DEVELOPMENT

    • Developers Blog

      Latest development updates, by Blender developers.

    • Documentation

      Guidelines, release notes and development docs.

    • Benchmark

      A platform to collect and share results of the Blender Benchmark.

    • Blender Conference

      The yearly event that brings the community together.

    DONATE

    • Development Fund

      Support core development with a monthly contribution.

    • One-time Donations

      Perform a single donation with more payment options available.

All Add-ons

Add-on Math Formula
Math Formula

Quickly add nodes by typing in a formula.
Add-on by WannesMalfait
About What's New Permissions Reviews Version History
Creating a rounded square shader Creating a twisted cube in geometry nodes

Lets you add (shader/geometry) nodes by typing in a formula into a prompt. For complicated formulas, this can save a lot of time.

Main features:

  • Custom prompt with autocomplete to help speed things up.
  • Support for (nearly) all nodes available in the shader editor or geometry nodes editor.
  • Keep using the same node setup? You can save it to a convenience function, that will always then always be available for you to use.
  • Comes with some common functions built-in.
  • Formulas are type-checked to automatically select the correct variant of a node (such as vector math node vs math node).

Quick start:

  1. Go to the shader (or geometry) nodes editor, and open an existing node tree.
  2. Use the keyboard shortcut Alt + F to open the formula editor at your mouse location.
  3. Type 4 + 5 and hit Ctrl + Enter to confirm the formula.
  4. A math node set to "Add" is added at the mouse location, with as input values "4" and "5".

Now, for a slightly more complicated formula:

  1. Hit Alt + F again to create a new formula.
  2. Type a * b + (c - d) and hit Ctrl + Enter to confirm the formula.

This time, multiple nodes are created, which together represent the formula.

Finally, let us look at an example using not just math nodes.

NOTE This one will only work in the shader nodes editor.

  1. Open the formula editor as before using the shortcut Alt + F.
  2. Type te in the prompt
  3. Press Tab to autocomplete.
  4. It should now show tex_coords() with your cursor in between the parentheses.
  5. Type ) to move the cursor out of the auto-closed parentheses. You can also use the arrow keys.
  6. Type a ..
  7. Hit Tab again to autocomplete.
  8. Keep pressing Tab until object is suggested.
  9. Finish the formula by multiplying by 2: tex_coords().object * 2.

This creates a "Texture Coordinate" node and connects the "Object" output of the node to a "Vector Math" node set to "Scale".

Issues

If you encounter any problems/bugs, or have a question you can create an issue or discussion on the GitHub page for the add-on code: https://github.com/WannesMalfait/Blender-Add-ons/issues

Usage

The main usage of the add-on is as follows:

  1. Use the keyboard shortcut Alt + F to open the formula editor.
  2. Type in some code/formula for the node setup you want.
  3. Use the shortcut Ctrl + Enter to confirm, and add the nodes to your node tree.

Your hands don't need to leave the keyboard during this process, so it can be a very fast way to add nodes.

Let us now look at the "syntax" of the formulas you can type:

Syntax

NOTE These examples are for the Geometry Nodes editor, but most of it is applicable to shaders too. The syntax is based on a combination of python and typescript.

The following example illustrates the basics of the syntax.

selection = dot(normal(), {1,0,1}) > 5;
uv_sphere = uv_sphere(18,20);
g1, g2 = separate_geometry_point(uv_sphere, selection);
x, y = position();
set_position(g1,_, {x, y, 1/(x*y)});

Let us explain what is going on line by line:

selection = dot(normal(), {1,0,1}) > 5;

This creates a variable selection, and assigns it to expression on the right-hand side of the equals sign. The right-hand side computes the dot product between the normal and the vector {1,0,1}, and then checks if that is greater than 5. The function dot is a shorthand for vector_math_dot_product.

Furthermore, the variable is assigned a "type". The different possible types correspond to the different types of node sockets, e.g. float, boolean, vec3, geometry, ... In this case, the type of selection will be boolean, because > returns a boolean.

uv_sphere = uv_sphere(18,20);

Here we create a new variable, uv_sphere which is assigned to the output of the uv_sphere function. The uv_sphere node usually also takes a radius as input, but because it was omitted the node socket will be left as default. If we only wanted to set the radius and leave the rest as default we could do:

  • Option 1: uv_sphere = uv_sphere(_,_, 2.0);
  • Option 2: uv_sphere = uv_sphere(radius = 2.0);

The second option is useful if there are lots of arguments you want to skip. The uv_sphere variable has type geometry.

g1, g2 = separate_geometry_point(uv_sphere, selection);

The "Separate Geometry" node has a drop-down selection for the domain. For each domain, there will be a corresponding function. Since we want the Point domain, we use the separate_geometry_point function. The "Separate Geometry" node outputs two geometries. We assign these to the variables g1 and g2 respectively. Note how we used the previously created uv_sphere and selection variables as inputs.

x, y = position();

The position function returns a vec3. We can automatically destructure it into its x,y and z components by assigning it like we did here. Note that the z component is discarded since we didn't assign it to any variable.

set_position(g1,_, {x, y, 1/(x*y)});

We update the position of g1, using the "Set Position" node. The selection input is ignored.

Function overloading

Many of the common operations are possible for different types. The add-on tries its best to infer types from expressions to determine the best match. This is best seen with some examples:

x = 10; // x is now of type 'int'
// The integer math node will be used, since we are working in the geometry nodes editor.
y = 5 * x; // The type of y will be 'int'.
// The best match is a 'Vector Math' node set to scale
z = {1,2,3} * y; // The type of z will be 'vec3'
// For 'x < y' a Compare node set to float is used.
// For 'z < 5' a Compare node set to vector is used.
// The 'or' is treated as a Boolean Math node set to 'or'.
test = x < y or z < 5; // The type of test will be 'boolean'.

// 'a' has not been defined, but its type can be inferred.
// The simplest possibility is for 'a' to be a 'float' to add with another 'float'.
// Hence, 'a' is seen as type 'float' and a 'Value' node is added named 'a'.
b = a + 1.5; 
d = c and b < a; // Similarly, 'c' will be of type 'boolean' here.

Remark: When the type of some variable can't be inferred, it is assumed to be a 'float'.

Python expressions

In blender, you can type python expressions in input fields. You can also do this here by using #. The expression after # is evaluated immediately.

example1 = sin(#tau/4)
example2 = sin(#(tau/4))

The difference between the two examples is the following:

  • In the first example a divide node is created, because only tau is evaluated as a python expression.
  • In the second example no divide node is created because tau/4 is evaluated as a python expression.

Chaining calls

When writing a formula we like to think from left to right. However, when we want to compose multiple functions we now have to think from right to left. Say that we want to scale some vector pos and then apply fract to that, we would have to write: fract(scale(pos, 0.5)) or fract(pos * 0.5). Notice that the last thing we wanted to do was the first thing we had to write. To prevent this problem you can also write the following: pos.scale(0.5).fract();. Calling .function() will take the expression before the . and place it in the first argument. For example: pos.scale(0.5) is the same as scale(pos, 0.5). This can feel a lot more natural, because it is also the way we usually build node trees.

Getting specific outputs

Another thing that can be annoying is getting the specific output of a node with many outputs. Take for example the Texture Coordinate node. If we want to get the object output you would have to write: _,_,_, object = tex_coord();. To fix this you can also use the . to get a specific output. So we could write object = tex_coord().object. Combining this with the chaining of function calls we get a concatenative way of writing expressions:

tex_coord().object.scale(0.5).fract().sub(0.5).abs() ...

Loops

If you have something where you need to iterate a node group multiple times (like in ray marching), then you can use a loop. It just repeats its body a given number of times.

// Equivalent to doing 10.sin().sin().sin().sin()
x = 10;
loop 4 {
    x = sin(x);
}

If you need the index of the current iteration as an input, that is also possible:

// i will go from -1 to 1 (inclusive).
loop i = -1 -> 1 {
    loop j = -1 -> 1 {
        x = {i,j}; // Creates a combine XYZ with values {i,j, 0}
    }
}

The general syntax for a loop is:

loop iteration_variable = start -> end {
    // Loop body
}

NOTE The repeat/for each zones are not yet supported, but will be in the future.

Custom Implementations

What if you want to add your own function? This is also possible with "custom implementations". In the preferences you'll find a link to the folder that contains these implementations. There are different types of files in the folder:

  • Files that start with "cache": These are used by the add-on to load them faster. You should not change these.
  • Files that end with "sh": These are implementations specific to shader nodes.
  • Files that end with "gn": These are implementations specific to geometry nodes.
  • Other files apply to both shader and geometry nodes.

What do these "implementations" look like? The general form is like this:

fn function_name(input: type, ..., input: type) -> output: type,..., output: type {
    // function body.
}

Let's look at an example:

fn _and(a: float, b: float) -> c: float {
    // This defines the "and" operation for two floats.
    // The reason for the underscore is that `and` is a reserved keyword.
    out c = a * b;
}

When you create functions with names like 'add', or 'mul', the corresponding operator will also work with these implementations.

fn pow(a: vec3, b: float) -> c: float {
    ax,ay,az = a;
    out c = {ax**b, ay**b, az**b};
}

{1,2,3} ** 5; // This executes the function above

If you want to create a node group instead of a function, you can simply replace the fn with ng

ng asinh(x: float) -> y: float {
    // The node group `asinh` takes a float "x" as input and returns a float "y".
    out y = log(x + sqrt(1+x*x), #e); // Here we set the output "y" using the `out` keyword.
}

What's New

2.1.0 March 12th, 2025
  • Update node info for blender 4.4
  • (Fix) Load custom implementations on register.
  • Translate nodes with mouse when adding a formula.

See all versions


Permissions

This extension requests the following permissions:

  • Files

    Loading and writing custom implementations

  • Clipboard

    Pasting formulas from clipboard

Developer
WannesMalfait
Rating
(2)
Version
2.1.0
Updated
1 mo
Published
Nov. 26th, 2024
Downloads
5022
Size
350.2 KB
Compatibility
Blender 4.3  and newer
Website
github.com/WannesMalfait/Blender-Add-ons/wiki/Users
Report Issues
github.com/WannesMalfait/Blender-Add-ons/issues
License
GNU General Public License v3.0 or later
Node
...or download and Install from Disk
  • 350.2 KB

Reviews

See all
  • fjunk
  • v2.0.4
  • 2 mo

On my system (Linux), Blender 4.32 locks up and I have to kill it - Terminal: Pkill Blender.

Version 4.4 tells me that Math Formula has to be used on less than the Max Version (I guess, currently, 4.4) even though your Description says, Any Version.

So, dead in the water.

  • WannesMalfait replied
  • 1 mo

I've also had blender freezing for a bit when trying to install extensions on Linux (not just with this one). I just uploaded a new version (v2.1.0) of the add-on which can be opened in blender 4.4, and contains some other fixes. Hopefully this version works for you!

  • Still
  • v2.0.4
  • 4 mo

The best add-on to build math nodes! I had to do some custom 3D math computations with Octonions and Quaternions which deal with a lot of math calculations. This add-on did it with no problems!

4.5

2 reviews
5
4
3
2
1
Rate this Add-on
  • About
  • Privacy Policy
  • Terms of Service
Download
  • Latest Blender
  • Blender LTS
  • Blender Benchmark
  • Previous Versions
  • Experimental Builds
  • Source Code
  • Release Notes
  • Requirements
Organization
  • People
  • Jobs
About
  • Blender Foundation
  • Blender Institute
  • Blender Studio
  • License
  • Logo & Trademark
  • Credits
  • Privacy Policy
Articles
  • News
  • Press Releases
  • User Stories
Get Involved
  • Dashboard
  • Development
  • Documentation
  • Education
Blender Studio
  • Films
  • Training
Support
  • Manual
  • Community
  • FAQ
Developers
  • Get Started
  • Projects
  • Docs
  • Blog
  • Forum
  • YouTube
  • Python API
Blender Conference
Follow Blender
Support Blender
  • Donate
  • One-time Donation
Artistic freedom starts with Blender The Free and Open Source 3D Creation Suite