OSL Node Equivalent

I’m looking for something similar in Blender. I’ve opened the .osl file from Max, but it isn’t working in Blender. Is there another way of doing this using Blender native nodes? Also, I’m trying to avoid OSL in Blender as it isn’t supported on GPU. Cheers.

Blender has shader nodes for standard math operations, so this is all possible with native nodes.
Is there something you are trying to achieve specifically?
If it is this specific node, what do you need it to be able to do? (resizing, switching operations)


You can group a chain of mix nodes or shader mix nodes and redirect their free inputs as parameters. But you cant redirect “mix mode” slider property to an input parameter.

The idea is to add displacement maps with mid-greys of 0 and 0.5 so it’s not just a regular add. The scalar of the 0.5 maps need to be normalised to 0 for the 3 maps to add together correctly.

The 1d 2d and 3d channels, are for handling float(all 32bit maps)

Here’s the graph I’ve set up in Max… Multiplies are to control the strength and mix of the Zbrush greyscale baked map and the Mari 3-channel RGB painted map

The osl code would be more useful to see whats going on

Of course:

// Adds (and optionaly scales) two colors
// ColorAdd.osl, by Zap Andersson
// Modified: 2018-02-08
// Copyright 2018 Autodesk Inc, All rights reserved. This file is licensed under Apache 2.0 license
// https://github.com/ADN-DevTech/3dsMax-OSL-Shaders/blob/master/LICENSE.txt

shader plusMinusAverage
[[ string help = “The Plus Minus Average utility node allows you find the sum, difference or average of a set of input attributes. It has three parts — two or more input attributes, an operator that you apply to the attributes, and an output attribute that holds the result of the operation.”,
string label= “plusMinusAverage (color)”,
string category = “Math\Color” ]]
int Operation = 0
[[ string widget=“mapper”,
string help = “Operation controls the mathematical operation done by this node. It has four possible values. No operation: The first input is copied to the output. All other inputs are ignored. Sum: All of the inputs are added together, and the output is set to their sum. Subtract: The output is set to the first input, minus all the other inputs. Average: The output is set to the sum of all the inputs, divided by the number of inputs.”,
string options=“No:0|Sum:1|Subtract:2|Average:3”,
int editable=0 ]],
int NumOfInput = 1 [[ string label = “Number of Input”,
int min = 1,
int max = 4]],
float input_3D_0 = 0.0 [[ string label = “input 3D[0]” ]],
float input_3D_1 = 0.0 [[ string label = “input 3D[1]” ]],
float input_3D_2 = 0.0 [[ string label = “input 3D[2]” ]],
float input_3D_3 = 0.0 [[ string label = “input 3D[3]” ]],
output float Out = 0.0,
if (Operation == 0) {
Out = input_3D_0;
if (Operation == 1) {
Out = input_3D_0 + input_3D_1 + input_3D_2 + input_3D_3;
if (Operation == 2) {
Out = (input_3D_0 - input_3D_1 - input_3D_2 - input_3D_3);
if (Operation == 3) {
Out = (input_3D_0 + input_3D_1 + input_3D_2 + input_3D_3)/NumOfInput;

If Operation is one of [1,2], its simple. It just chains all inputs with ‘+’ or ‘-’ (excep caset Operation == 3). You can chain mix nodes with ‘add’ or ‘subtract’ mode the same way.

If Operation is set to average mode (3), I am not sure whether it works as I expect. I assume you also need a mix node set to divide connected to the chain. Second color input gets its value from a scalar value (bigger or equal one). I am not sure how mix treats color values with slot bigger 1.

Thanks, my experience with building graphs in Blender is very limited, but the adds would have to handle float data for the 32bit displacement maps.

I’ll do some more experimenting based on what you’ve said. Thanks.

I dont think 32 bit floats would cause problems here.

If you like, an idea for a node which calculates average color of 3 input colors. Playing with it, node setup seems to work as expected.

Thanks, I’ll try this out and post back. :+1:

@Leonard_Siebeneicher I’m still not able to get this working. I think it’s more than just adding these nodes together. I’m not sure if the add nodes are float. This plusminus node exists in OSL because regular math nodes in Arnold won’t do it. It’s to do with normalising the grey mid-point of the 2 different types of disp maps.

All I need from that osl node is the float sum of the inputs.

1 Like

The inputs in that osl script are not colors, they are floats.

To recreate the average of three floats, you can change the RGBMix nodes from @Leonard_Siebeneicher 's setup, with simple Math nodes; and the color inputs to float inputs.


Thanks mate, could you post a graph example? I’m very unfamiliar with Blender’s nodes.

could you explain a little more what those nodes should do? (i don’t get the displacement part)

you just want to average 3 (mixed types) displacement maps ?

Basically, I have 2 displacement maps: 1 baked from Zbrush with a 0 mid-point, and the other is a 3-channel RGB map that I painted in Mari with a mid-point of 0.5.

I need to average the sum of the 2 maps(which will ultimately be the Red channel from ZB and the Red/Green channels from Mari averaged in a single node before output) and normalise the scalar mid-point as floats(32-bit disp maps)

Because the 2 displacement maps are using different mid-points they need to be averaged using float values. Otherwise, they won’t display correctly.

I have set this up in both Max and Maya, but I’m not at all familiar with Blender’s Math nodes.

that should do the trick?

midlevel is just a subtract + multiply

1 Like

Thanks a lot. I’ll try it now. :+1:

Can you explain this? I thought the Midlevel nodes are just displacement nodes?

ja you could use the displacement nodes but they spit out a vector not a float you would have to extract the first channel again

thats the midlevel node - this one decodes the midlevel 0.5 maps to proper floats

subtract the baked midlevel and multiply by the scale you got from mari or guess :wink:

1 Like

@nudelZ Brilliant! This worked perfectly, and by just adding a multiply to the ZB map before adding it I have full control as I had in Max/Maya. Seperating the RGB rather than XYZ was obviously where I was going wrong.

Thanks alot, mate, and thanks to everyone else who pitched in. :+1: :+1:

they have the same function actually (everything is float based) :slight_smile:

i’m curious how this setup looks applied - any image? :wink: