Anybody written a Plugin that adds Material Nodes?

Title is self-explanatory really, I want to write a plug-in that will give me a few extra material nodes, with the code then being handled by the plug-in.

Trying to do Atmospheric Scattering with nodes but it’s just proving to be more difficult. Really I need to do it in HLSL.

If you are coding the shader logic in HLSL anyway, why not use the custom node ?

Because I need to split the work into multiple functions, which need to call each other and pass parameters, therefore I’m stuck with that one!

So you could make a material function that wraps the HLSL code. It provides the input and outputs. Inside thefunction you do the stuff in one or more custom nodes…
Then you use the function(s) to make your material…

I know how to add a code node but not how to do it as a plugin. But doing it as a plugin should not be terribly hard. Try looking up Rama’s plugin tutorial and adapting these suggestions.

I made a code node called “Box Mask” that will probably never get used since engine-coders preferred to keep it as a material function (which is safer). But it makes a good example node now.

First try just injecting your node into the regular material node file: “MaterialExpressions.cpp”

Here is the code for my boxmask node (it’s basically spheremask with different math):

Then to get this to work you need a header file that goes under:
UE4\Engine\Source\Runtime\Engine\Classes\Materials\

This one is called “MaterialExpressionBoxMask.h”. It includes the following code:

Note that the .h is where you declare values that will override the defaults. This allows the values to have a fallback default. The UPROPERTY data is actually in unrealscript, make sure that if you specify an overriding property that you specify the right variable name or you will run into a super recursive slowness bug whenever you drag your node around.

Going forward, it will be nice if we can make it so that the Custom node gets named function calls.
I ran into this same limitation recently and ended up just re-pasting giant code blocks a bunch of times as a workaround.

You actually CAN communicate between different custom nodes but you have to call them like “CustomExpression_0(Parameters, x,y)”, which means the names can change depending on how you add them to the material so its not reliable or shareable between different materials.

To give some context, this is the Shader I’m trying to re-create, albeit for a 3D Object instead of just a 2D Viewport. The basic idea and math is the same though (if anybody wants to help, feel free ;)) Shader - Shadertoy BETA

The additional problem is that I need to do some pre-computation for the scattering functions, since I don’t think they’re fast enough to run continuously. A look-up table or texture would do for this. Somebody has already done that, but I can’t for the life of me find it now.

Anyway…

Before Ryan mentioned that you can Call Custom nodes from Other Custom nodes I would have said that wasn’t possible for me. In the HLSL I posted, you can see that a function increments some values then calls another, with new parameters, before spitting out the final result. I could have possibly duplicated the nodes a few times, but that would have probably ramped my instruction count up.

Additionally, the Custom node can only return one value, so it starts getting out of hand with the amount of split-up nodes I’d need and I couldn’t return stuff simply to pass it into a parameter. There’s just not a nice way to do for loops and compact math statements at the moment (+=, -+, *=, etc/)

Thanks (again) Ryan!

I had no idea you could call existing custom nodes from each other… that might make life easier. I’m guessing they need to be hooked up to the main material block in order to be picked up by the compiler, or can I just have floating nodes? Thanks for the code and the tips too, seems fairly simple to just have them picked up by the engine, without changing too much.

I’ll have a look at creating plug-ins. I managed to code a module for Cascade sometime last year, but adding that via a plugin hasn’t been possible. Hopefully the same doesn’t go for Material Nodes.

You could first make a material that ourputs your scatter values incremented by the UV-Y value or something to make a texture inside of the editor.

basically you just make your scatter function, then at each point you use the Y value of your UV to solve (and bias-scale if you need to capture over -1 to 1 etc). then using the render to texture blueprint or just by taking a screenshot you can get your image.

Does making an exr screenshot save your shader values into the texture to half float 16-bit nicely? how would that work across vendors?

Also I haven’t used the renderToTexture node yet but what if you want precise values to be stores per pixel? Does filtering mess with that or can you specify no AA/filtering etc to get pixel perfect textures. One thing I want to do is store precomputed blackbody temperature in U and white balance offsets in V.

hey guys … I’ve been doing a plugin that automates a art pipeline and the materials are in the plugin for some reason the materials are only rendering in a the project I’m developing the plugin when I transfer the plugin elsewhere the material slot is assigned to the proper material in the plugin but it looks like it hasn’t complied or something … anybody has bumped into something similar??

Just wondering if anyone ended up finding an easy way to write create custom material nodes as a plugin (or maybe editing source files). My hope was that I could easily modify the Blueprint Library plugin template to create material nodes instead of regular blueprint nodes.