Pluggable PBR shader?

I often find myself trying to write a shader that dynamically generates textures based on whatever parameters, but want it to apply those textures onto the standard PBR shader. The way I go about it is by copying the stock PBR shader and modifying it, but this gets tedious very fast. Is there a way I could do this without duplicating existing PBR code? Iā€™m thinking something along the lines of what Unreal material nodes want at the output (base color, metallic, rough, etc. textures) and then apply those textures onto UEā€™s PBR shader.

Whatā€™s the current status of jmeā€™s shader nodes? As far as Iā€™m aware thereā€™s no PBR node, right?

1 Like

i remember someone told it should be moved to Shader Nodes? or at least as a imported methods.

Shader Nodes work already. you can even visually edit it in SDK Material preview Shader Nodes TAB. (Like blender shade nodes)

It would require rebuild all shaders, that is possible but i belive its a lot of work.

Pbr with triplanar is expensive. Doing it for 4, 5, 6 pbr materials (grass, dirt, rocks, snow, etc) is crazy talk, so what you need is an array of packed textures (use all the channels you can). Putting that in a shader node would be a bit unique to the point where it wouldnā€™t make sense anymore to use shader nodes.

Having said that, terrain aside due to its uniquety, thereā€™s no reason you canā€™t use shader nodes with pbr.

It would be nice if someone could break apart PBR into shader nodes so it was more composeable.

ā€¦this was never done for regular lighting either which is why we had to fork it to put things like fog, etc. in.

A shame and probably a relatively straight-forward task for someone wanting to know the shaders and shader node system ā€œinside and outā€. A good learning experience. lol

3 Likes

Just in case this is related!! :wink:

Here is what @nehon wanted to do about shader nodes. A programmable shader node with a Java API.

Iā€™d like to address this, by providing an easier way to code them and build them from java code.

Yeah, I think I convinced him to move towards what my original proposal wasā€¦ which could determine things more implicitly. The code generator is pluggableā€¦ so maybe Iā€™ll take a look at it at some point to see what can be done.

In my approach, shaders could be evolved towards shader nodes as regular shaders and then just broken up into nodes as a last pass. (A called my shaderlets because they were just composeable code snippets that were still valid GLSL.)

3 Likes

so this would be advantages?

  • single shader node file, not j3sn + frag/vert
  • no name name collision avoidance by prefixes
  • programmable Shader via shader node usage
  • generally easier/faster node merging into shader (would just join this files).

i assume it would be ofc able to use same Shader Node twice in process?

Btw, alternative to shader nodes is just use ā€œ.glsllibā€ eg put the pbr routines in a single file and import where needed

From what I understand A node is like a chain of modules that accept an in and out and you chain them to get a result.

So I could have a lighting node or pbr node, I guess the ā€œtrickā€ is where it goes (probably at the end).

As with a lot of work from @nehon - itā€™s usually years later that it gets recognised for what it is.

Yes, for this usecase, glslib could work, you just need to define the Input texture names and are Done. You cant do changes inbetween though

Regarding glsllibs, thereā€™s already this:

Itā€™s not documented how to use it and I suspect itā€™s mostly helper functions, not a computePBRColorFromTextures() or whatever one would call a function I eas describing in the first post.

But with shader nodes you theoretically donā€™t need to toy with shaders at all. You have a pbr node that wants textures and it outputs a color. So you create a node and give it ā€œmodulesā€ and programmatically build it. So before that one could have a pbr IN node, a noise node, a height node that chooses between multiple IN nodes, whatever, then finally pass it through the pbr lighting node and viola. Itā€™s all programmatic. Nodes can be re-used.

Glsl libs require editing vert and frag files. Shader nodes are a lot more re-useable and donā€™t require shader editing. Itā€™s a lot more OOP.

As cool as node editors are, Iā€™m yet to find a node implementation thatā€™s more efficient at math (which generating textures usually is) than good old glsl. In Blender creating procedural textures is a mess exactly because of this.

It can be less efficient at times but what you gain is flexibility, ease of use and speed of creation. And that you donā€™t need to learn shader language. Often times itā€™s also really good to design it with a GUI to test ideas and quickly change things to get the output youā€™re looking for. For a newcomer that could be the end, and for an advanced user they could use that visual as a sheet to work from to write it all in a dedicated shader.

Iā€™m not saying that a shader nodes PBR implementation wouldnā€™t be good for the engine. Iā€™m just saying that it doesnt fit my use case.

Well, as everyone said, for me Shader Nodes should look similar to Blender Node system, like in the link some Artist show one:

so you just connect what you need. it will auto-manage shader glslib imports, variables and others during merge into one shader as i understand.

But what is nice is that you can do things like(also in provided link):

Variable color = new Variable(ā€œvec4ā€, ā€œcolorā€).set(ā€œvec4(0.0)ā€);
Shader.node(ā€œdash100.fragā€, ā€œDashā€) // finds the Dash node
.inputs(
new Variable(ā€œvec4ā€, ā€œinColorā€).set(ā€œvec4(1.0)ā€),
ā€¦
)
.outputs(color);
// then use color as an input for another node for example

that you cant do just using glslibs.

Since anyway most of JME users are developers, it would not be problem to use just glslibs, but myself i think it would be good to have programmable Shader Nodes or GUI edited too. IMO its quite easy and its not ā€œMessā€. Look at this image that artist provided, imo there would be much more ā€œMessā€ when doing it as single shader(even with glslibs) instead of shaderNodes where you only care about in/out. (you dont need to know all behind it, while in glslibs you othen need to know things like ā€œuse this function, but before i need use this function, also i cant use it twice, because some variable might be doubled in valueā€. So here i would say Shader nodes are like ā€œproper Object encapsulationā€ term.

Ofc its just my opinion, i will be happy with anything that will upgrade shader system. (also i think @RiccardoBlb might tell much here).

Iā€™m the wrong person to ask, i generally dislike any form of node editors.

The beauty of glsl is that the language itself is simple and barebone, there is not much that can go wrong. Using a node system on top of that adds a new layer of abstraction and complexity that is not really justified in my opinion.

I agree that the current shaders are very hard to maintain and poorly designed, but i believe that we can improve them by using only properly designed functions and structs.

6/21 nodes in that node graph are math nodes, not to mention various separate/join RGB nodes which are not needed in glsl. Thatā€™s why I think some things are done in glsl much easier.

The idea behind shaderlets was that you split your shader up into functions with inputs/outputs (which can generally be determined implicitly). This idea morphed into what shader nodes is now which essentially REQUIRES graphical editing to do anything non-tedious. I mean, you can do it manually but itā€™s very painful.

The idea for shaderlets was that youā€™d just add them all into a list and your shader would come out the other end. It would autowire based on naming and/or you could insert shaderlets to remap things.

I lobbied strongly to have the shader generation pluggable so that I might come back and play with my ideas. It was only years later that nehon and I were talking and he saw the benefit of the approach.

I still want to do it. Every time I want to add just one little thing to the end of some shader, I want to cry.

5 Likes