Jump to content

Blender Principled BSDF mapping for export


Recommended Posts

I think I asked for this before, but not in a specific topic.  I need to know at the detailed level how Blender's Principled BSDF shader maps to BJS.

The BJS relevant doc seems to be: http://doc.babylonjs.com/api/classes/babylon.pbrmaterial

Blender describes the shader here: https://docs.blender.org/manual/en/dev/render/cycles/nodes/types/shaders/principled.html

There is no place in the Blender API docs which layout how to access / set this, but there is this: https://blender.stackexchange.com/questions/105463/principled-shader-inputs

Link to comment
Share on other sites

Is doing drawings like this can be useful? https://www.draw.io/?lightbox=1&highlight=0000ff&edit=_blank&layers=1&nav=1&title=BJS Blender exporter.xml#Uhttps%3A%2F%2Fraw.githubusercontent.com%2FVinc3r%2FDraw.io-drawings%2Fmaster%2FBJS%20Blender%20exporter.xml (source available here)

If so, I will finish my first try on this. Already facing issues for some properties, I think we should read this gltf issue about exporting Principled node, it can help (and why not be consistent in the logic they use).

Link to comment
Share on other sites

OK so this is, I think, a good first start to work on a conversion: still the same link.

BJS%20Blender%20exporter.png

  •  for some missing textures nodes, or even number values, maybe we can think about a node convention using add or mix shader node to enhance the export (like in this example from gltf issue). But for now it's probably too complex, we can wait before adding this such features. The big question about that is that artist should be able to get a convenient and realistic render using this node setup in Blender (example : emissive using add shader, AO using multiply, etc <- this is why gltf currently use a custom nodes group, maybe a solution too for .babylon, and this will make the Principled allowing just simple material setup?)
  • when 2.8 will be production usable (still some months to wait), we will have to think on how to be able to export to standardMaterial too (because of the deletion of Blender Render). At this moment, I think we should only support Eeeve engine and get rid of Cycles (it's in fact just a detail because Principled BSDF is both compatible, but it can help to lower potential addon bugs)

 

 

Link to comment
Share on other sites

Wow, I knew there was a problem when only one or 2 of the principled properties had a name in BJS.  We are going to need some type of node analyzer to determine if PBR can be transferred, or the whole thing just needs to be baked.

I think to get best results, perhaps we need to add an operation in the Materials tab, which creates the exact structure we support.  It would probably not be laid out very well, at least initially.  It would save work, and avoid baking at the same time.  If a given did not have say a bump texture, you could just nuke the node.

This is such a free form organization, it is not going to be easy.

Link to comment
Share on other sites

I've already have to make some bits of Blender python code to detect values in nodes, it's not such difficult as it looks like. We can probably start with something like, exporter point of view:

  • if an object have one (or multiple) material, then it's a PBRMaterial (here the exporter already have default values for PBR properties
  • if this material output is linked to a Principled, then we check the few equivalent values (color, alpha, metallic, roughness)
  • if these values have something linked to them, we check,
  • etc
  • if the artist connect something we does'nt recognize, we fallback to the default value

 

Link to comment
Share on other sites

gltf is Apache licensed, so we could steal anything we might want from there. 

I not exactly sure what you mean by a an exporter POV.  I am leaning towards making a nodes directory.  In the directory, each type of Node would have it's own class & file name, if we support it.  E.G. BsdfDiffuse.py.  Many files would be very small, but once made would not likely to need to be changed.  This suits a repo very well.

The constructor for a node class would get passed in the Blender node instance.  The constructor would be responsible for parsing any fields used & do anything to get the values prepped, as required, to be output in the 2nd pass.  If something about this node means that this material must be baked, then the construct would set self.mustBake = True

To handle the chaining of nodes in a single spot, all node classes would inherit from AbstractNode.py.  I am hoping this constructor, which would run prior to the sub-classe's, would process each of the input nodes to the current node.  This would effectively go all the way down the chains, if the original instance is called with the node with no parent:

for node in material.node_tree.nodes:
    if node.parent is None:
        self.node = AsbtractNode(node)

Just writing directly into this topic, the straw man for AbstractNode.py would be something like:


def __init__(self, shader):
    self.mustBake = False
    self.inputs = []
    for input in shader.inputs
        node = AbstractNode.determineNodeClass(shader)
        if node.mustBake:
            self.mustBake = True
            break
        else:
            self.inputs.append(node)

     # end of super class constructor, sub-class constructor now runs
            

@staticmethod
def determineNodeClass(shader):
    shaderName = shader.bl_idname

    if shaderName == 'ShaderNodeBsdfPrincipled':
        return BsdfPrincipled(shader)

    elif shaderName == 'ShaderNodeBsdfDiffuse':
        return BsdfDiffuse(shader)

    ...

    else:
        return MustBakeNode(shader)

There may also need to pass the parent or type of input into the constructor.  Each node class would be responsible for writing their part of the material.

Link to comment
Share on other sites

You lost me ? (out of my skills). But I can prepare a small Cycles test scene with commons examples + same scene but in gltf. The last one should give us kind of a guiding thread.

If you're interested in it, it can be done... ASAP? (maybe this wkd)

Link to comment
Share on other sites

  • 1 month later...

Unless that consistency is to NOT be all PBRMaterials.  Personally, I see no need for PBRMaterials in my work.  I am not to this point yet, but am thinking a scene level, "no PBR materials" check box.  Principled is setup to do "everything".  If you are not doing PBR, you should not have to pay for it.

I am successfully "reading" the currently active node tree recursively.  Am doing this in the TOB code base on 2.79.  The 2.80 convert work is being done on the EEVEE branch of the JSON exporter.  At some point they will "merge".  Neither is ever going to be published with PBR for 2.79.  This is just a vehicle to work in parallel.

Link to comment
Share on other sites

  • 3 weeks later...

Ok, starting to generate output (javascript), at least for the environment texture & sky box.  Everything is not right yet, but still significant.  I am looking at your principled picture, @V!nc3r.  You seem to have a single texture for for multiple channels (occlusion, roughness, & metallic).  I understand that these occupy different colors of the texture, but not how you would actually get such data into one texture?

More over, that multiple to one relationship was not in the prior exporters.  Am in the process of that final piece for principled Node, and generation of JS from that.  I just want to make sure before the JSON exporter starts to get modified that this can be expressed there too?  Do you @Deltakosh?

Also, Occlusion does not seem possible in Cycles, so that probably cannot be done.

Link to comment
Share on other sites

I was taking example from glTF process, where ORM texture is available (even if Occlusion map have its own node, we can use the same texture as Metallic Roughness). And about how to merge metallic, roughness & occlusion in only on texture: you get your differents passes as black and white images, and the simpliest way I found until then is to use Allegorithmic Substance Designer which is perfect to combine image data, but I think its also doable through Photoshop, Gimp, maybe Krita and even CLI tools like ImageMagick. Substance Painter can also export directly ORM using gltf export pattern.

About occlusion it needs some node mixing to get it in a Cycle shader (but if its in ORM texture, BJS user can activate AO pass using useAmbientOcclusionFromMetallicTextureRed = true;)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...