Defold PBR extension

Defold PBR Support

We’ve been working on improving our 3D support during the past year or so, and we now feel it’s time to release an alpha version of the PBR extension! For issues, bug reports or suggestions - please navigate to the github project page open a ticket regarding the matter there.

Live demo: defold-pbr 1.0
Project repository: GitHub - defold/defold-pbr
Integration guide & manual:


  • linux support - the extension does currently not seem to work on the linux platform
  • optimise shader size - the built GLSL shaders are quite large because of heavy use of includes
  • add more GLTF PBR features - we currently support a somewhat small set of features from the reference GLSL from the GLTF viewer, but we would like to have more feature parity between our viewer and the official Khronos one.

Finally! :partying_face: Just playing with the demo, runs without hick-ups so far on the mini m1. And is soooo cool. :star_struck:
Thank you all!


Looks awesome! :heart::heart_eyes:


Runs perfectly smoothly on the low spec Pixel 5, too! :star_struck:


Great to hear! :slight_smile:

1 Like

Working just fine here on Silverblue 38!


Oh, cool! I know @AGulev had some issues but glad it works! Is it the web demo or the desktop version? If it’s desktop could you try to generate a hdr env map? Should be one in the repo

So it looks like the problem is with Debian distros? This is test on my Ubuntu 20.04:

1 Like

Does the browser version work for you? If not can you run it in debug mode and see if anything prints in the console?


That’s a screenshot of the desktop version and it runs just as well on Firefox and Brave.

Guessing you mean the Defold PBR - Create Environment Assets command? I tried running that on both .hdr files in /assets/environment-maps but it gives a very odd error:

ERROR:EXT: Defold PBR - Create Environment Assets's "run" in /defold-pbr/core.editor_script failed:
ERROR:EXT: {2, {["action"] = "shell", ["command"] = {"mkdir", "-p", "assets/environment-maps/blue_photo_studio_2k"}}} needs "action" key to be "set" or "shell"
ERROR:EXT: {3, {["action"] = "shell", ["command"] = {"build/plugins/defold-pbr/plugins/pbr-utils-linux", "assets/environment-maps/blue_photo_studio_2k.hdr", "assets/environment-maps/blue_photo_studio_2k", "--generate", "irradiance", "--generate", "prefilter", "--meta-data", "--verbose"}}} needs "action" key to be "set" or "shell"
ERROR:EXT: Defold PBR - Create Environment Assets's "run" in /defold-pbr/core.editor_script failed:
ERROR:EXT: {2, {["action"] = "shell", ["command"] = {"mkdir", "-p", "assets/environment-maps/christmas_photo_studio_07_2k"}}} needs "action" key to be "set" or "shell"
ERROR:EXT: {3, {["action"] = "shell", ["command"] = {"build/plugins/defold-pbr/plugins/pbr-utils-linux", "assets/environment-maps/christmas_photo_studio_07_2k.hdr", "assets/environment-maps/christmas_photo_studio_07_2k", "--generate", "irradiance", "--generate", "prefilter", "--meta-data", "--verbose"}}} needs "action" key to be "set" or "shell"

However, removing get_platform_tool_prereq_cmd() from the returned actions fixes it and leads to the next error:

ERROR:EXT: Defold PBR - Create Environment Assets's "run" in /defold-pbr/core.editor_script failed:
ERROR:EXT: Cannot run program "build/plugins/defold-pbr/plugins/pbr-utils-linux" (in directory "/var/home/potota/Documents/Defold/defold-pbr-master"): error=13, Permission denied

And after setting that program as executable it finally opens a blank “PBR Utils” window for a few seconds and everything works!

More hardware/software details if you need it:



Thanks for testing it out! I haven’t tested all editor scripts on all platforms, there’s probably platform dependent caveats all around that we need to cater for… but good that you could get it to run at least! So far so good :crossed_fingers:


Hi, congrats on the alpha release. I’ve tested the link on an Android (13) phone, with device Samsung Galaxy A03s (Samsung SM-A037F, PowerVR Rogue GE8320), using DuckDuckGo (5.164.2.zp) browser. It shows everything except the reflection.

I hope this helps.


If anyone (@Pawel or @AGulev maybe?) could try and capture a faulty frame in renderdoc I could perhaps deduce something from that :thinking: otherwise I’d have to get my hands on Linux on a non-VM

1 Like

I have run defold-pbr (88101508450f1ba07ef3c19cd21f87dc329ab27d) on Ubuntu 22.04.2 LTS. Looks good to me including reflections. Runs in the editor and as a Linux bundle using between 13% and 17% CPU. No errors. I also tried debug mode, no errors, nothing looks wrong.


So I guess it’s a driver issue then :thinking: the reflection cube map is using a half float format for performance reasons and I suspect it’s the culprit but that format has been around for a while so I would be surprised if it wouldn’t work…


Tested on Fedora 38 KDE with a AMD RX 6800. Fresh install. Works and looks great!


I also had to remove get_platform_tool_prereq_cmd() to make the “Create Environment Assets” script run on Windows.

And a question: Does the script mirror the cubemap sides somehow? I tried to render a normal skybox using the 6 images from the Blue Photo Studio environment, and it displayed a mirrored version of the room (I guess from rendering the inside of a cube). So I either had to mirror the images myself or by negating the sample point z value in the vertex shader.

But when I used the generated prefilter texture it was already mirrored. Also, the entire was room was rotated by one side in the prefilter texture version, putting the sofa in the front.

The reason I’m using a separate skybox is to increase the resolution of the surroundings. It’s not really a problem, but right now I compensate for the mirroring and rotation at same time by switching x and z in the sample point:

var_position = vec3(position.z, position.y, position.x);

I’ve run into a peculiar problem. I wanted to play around with the fragment shader to display the different stages of the rendering process, similar to the what you can do using the debug menu.

The problem is, setting frag color is not always working. For example, when I wanted to render only the diffuse lighting, I wrote this in pbr.fp:

gl_FragColor = vec4(lightInfo.diffuse, 1);

It just gives me a black helmet. If I wrap this statement in an if-statement with some non compile-time condition (e.g. comparing some uniform variable) it shows the diffuse component correctly.

if (var_position_world.x > -100) gl_FragColor = vec4(lightInfo.diffuse, 1); //Works
if (true) gl_FragColor = vec4(lightInfo.diffuse, 1); //Doesn't work
gl_FragColor = vec4(lightInfo.diffuse, 1); //Doesn't work

Is there anything I’m missing when it comes to GLSL here? I can’t reproduce this in the starter 3D project, but there the model.fp doesn’t include any other GLSL code.

Yes that’s a side effect of our renderer binding textures to numerical units in OpenGL and not by sampler name (which is what we ultimately would like, but that’s another story) together with shader optimization the driver does. So in a sense we expect the order of the units to be bound in a certain way, and if you start removing stuff from the shader the order can be different and the texture can potentially be bound to the wrong samplers.

1 Like

I see. If I understand it correctly, it also explains why I had to output both the diffuse and specular part first to make my hack work – to trick the optimizer not to optimize. What’s the best approach to make sure the textures aren’t bound to the wrong samplers then? Is it to write the fragment shader in such a way that it certainly uses all the samplers from the input?

I should probably try to write some shaders from scratch myself first I realize now. :sweat_smile: Thanks for the help!