SimplePBR: No Normals or Emission?

[edit] Ah, nevermind–I’ve just noticed in the spec that “use_normal_maps” defaults to “False”! If I set it instead to “True”, I get normals as expected!

I still don’t get emission that I see, but that’s not important to me right now.

I’m leaving the original post below, both for transparency and in case others have similar problems.
[/edit]

I’m experimenting with “simplepbr”, and have made a little bit of progress thus far, I think. Specifically, I have a simple model rendering, and showing the effects, I believe, of both metallicity and roughness.

However, for some reason I don’t seem to be getting the effects of normals or emission.

Note that if I enable the auto-shader I do get normals, so the normal-map would seem to be functional, and the model would seem to have tangents and binormals.

I’ve followed the spec given here, I believe: the first texture is colour, the second is metallic-roughness, the third is normal-map, and the final texture is emission.

The test-model is a simple cube with some basic testing-textures; these files should be attached below:
pbrTest.zip (613.5 KB)

This is the result that I get with simplepbr:

Note that colour and metallicity-roughness appear to be present, but normals and emission don’t.

And here is the result that I get with the auto-shader:

Note that normals appear to be present, and that the emission-texture (which provides the red circle) is at least shown on the surface.

And finally, here is my testing-program at time of writing:

from direct.showbase.ShowBase import ShowBase

from panda3d.core import PandaNode, NodePath, DirectionalLight

from panda3d import __version__ as pandaVersion
print (pandaVersion)

import sys
print (sys.version)

import simplepbr

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        simplepbr.init()

        self.accept("escape", base.userExit)

        self.updateTask = taskMgr.add(self.update, "update")

        self.model = loader.loadModel("pbrTest")
        self.model.reparentTo(render)
        self.model.setY(5)

        light = DirectionalLight("mew")
        light.setColor((1, 1, 1, 1))
        lightNP = render.attachNewNode(light)
        lightNP.setHpr(5, -5, 0)
        render.setLight(lightNP)

    def update(self, task):
        dt = globalClock.getDt()

        self.model.setH(self.model, dt*17)

        return task.cont

app = Game()
app.run()

All that said, it is possible that the issue lies with my machine–I’ve had some problems with the rendering of PBR materials before, I think.

So, am I doing something wrong here?

Your problem is that you are not using .gltf, as far as I know, SimplePBR requires a standard gltf for storing a 4-component tangent and no bi-tangents.

But I could be wrong.

Thus far, and aside from emission, that doesn’t seem to be the case.

With the above-mentioned change to the initialisation of simplepbr, this is the result that I get:

I don’t know whether the above is accurate to “proper” pbr, but at the least it has a working normal-map, and as mentioned above, metallicity-roughness and colour both seemed to already work.

So I think that it’s accepting an egg-file happily enough.

SimplePBR is an interesting idea, but due to the fact that it does not support shadows from point light, this makes it unsuitable for production. However, since this also does not support the panda auto-shader, it is not entirely clear what can be done with it.

It depends on what you want to do with it, I think. In my case specifically, the lack of shadows isn’t necessarily a problem.

I think you should use the “emission” envtype for the emission map and the “selector” envtype for your metal-roughness map.

As for normal maps, I think simplepbr does expect the tangent data of the model to be provided in a special manner, but I’m not sure what the result will be if you simply pass regular 3-component tangent values.

Hmm… No apparent effect that I’m seeing. Although it may be that my metallicity-roughness map, at least, just doesn’t have values that highlight the difference.

In case I’m mistaken in how I applied that change, I simply opened the egg-file, located the relevant texture-entries, and in the lines that read <Scalar> envtype { MODULATE } I replaced “MODULATE” with “EMISSION” and “SELECTOR”, I believe that it was.

At the least normal-maps seem to be working, now that I have the relevant parameter being passed to the initialisation function of simplepbr. Is there something in the screenshot above that indicates that something is still incorrect…?

@Thaumaturge
Please note that the material properties need to be edited.

Now the alpha component - diffa is supported.

<Material> Material {
  <Scalar> diffr { 0.640000 }
  <Scalar> diffg { 0.640000 }
  <Scalar> diffb { 0.640000 }
  <Scalar> diffa { 1 }
  <Scalar> specr { 0.500000 }
  <Scalar> specg { 0.500000 }
  <Scalar> specb { 0.500000 }
  <Scalar> shininess { 12.5 }
  <Scalar> ambr { 1.000000 }
  <Scalar> ambg { 1.000000 }
  <Scalar> ambb { 1.000000 }
  <Scalar> emitr { 1.000000 }
  <Scalar> emitg { 1.000000 }
  <Scalar> emitb { 1.000000 }
}

Aah, thank you! I didn’t know about that! And you’re quite right, changing that–specifically, changing the “emit” values–results in emission now working as expected! :slight_smile:

(As to “diffa”, it looks like that defaults to “1” when it’s not specified.)

However, if it is set and less than 1, the model will have transparency. Previously, this was not the case.

Also now the record looks like this:

  <Scalar> baser { 0.640000 }
  <Scalar> baseg { 0.640000 }
  <Scalar> baseb { 0.640000 }
  <Scalar> basea { 1 }

What makes exporting YABEE to egg obsolete.

Indeed, which is quite neat, I think!

Only for exporting PBR materials. As that’s something that I’m currently not likely to do often–the purpose for which I’m experimenting here is an exception–it’s not obsolete for me, at least.

This is quite strange to me. This should work if there is no texture, however, this happens even when a texture with an alpha channel is installed.

In any case, thank you for studying this question, I previously wondered how SimplePBR works. Your post has put all the dots in this.

1 Like

While I haven’t tried it with a semi-transparent texture, I think what I would expect is that the resultant transparency would be that of the texture multiplied by that of the material–that, at least, is what makes sense to me!

It’s my pleasure! I’m glad if the thread and discussion has helped! :slight_smile: