BRDF-Based Deferred Lighting Example

Hi everyone!

In my free time, I’ve been working on graphics effects: writing shaders, experimenting with rendering, and everything related to it. Recently, I put all my work together into a single project - a deferred renderer in Defold. You can use it as a foundation for your own scenes and experiments.

Features implemented:
– G-Buffer with albedo, normals, and depth
– SSAO with smoothing and position reconstruction from depth
– Point light shadows (cubemaps packed into an atlas). The number of lights is limited by atlas size — currently up to 10. It can be significantly increased to x4, with simple settings in the code
– Volumetric lighting — that soft “light in the air” effect
– Simplified PBR (diffuse lighting + a bit of BRDF)
– Tonemapping for proper HDR-to-LDR display (not perfect yet)
– Free camera (WASD + mouse), multiple light sources, and a basic set of objects

Rendering process:

  1. Write data to the G-Buffer

  2. Calculate SSAO

  3. Add shadows

  4. Perform lighting

  5. Display the result on screen

It’s easy to plug in your own models and textures (albedo, normals, roughness), configure materials, and add them into the scene.

The code is open and straightforward: modules, shaders, materials, and rendering utilities.
The project is available for everyone — feel free to try it out, improve it, and use it in your own projects!

26 Likes

That looks amazing, well done!

There are not a lot of resources for advanced rendering in Defold, so this is very useful.

3 Likes

Well done!!! It looks great! And thank you for sharing this with the community.

3 Likes

For those interested, there is a really nice explanation of what is BRDF (and many other techniques) in this video (despite the catchy thumbnail):

3 Likes

Hello @martianov . Very nice example. Tell me , please. Does your project support only vulkan ? Can I run it on my arm64-linux device with open gles ?

Yes, it also works with OpenGL/OpenGL ES, and most importantly it runs in the browser too. Just make sure to implement the TBN matrix for proper normal mapping, and don’t update the lightmaps every frame - make the updates less frequent, for example only when lights or geometry change. I don’t have much time to handle this myself right now ;(

4 Likes

It works super smooth on Linux too! :wink:

I tried to dig into the code as much as I could, some things might be still actually answered in code, but I might didn’t get it, so forgive me if my questions are dumb, but I wanted to ask you some: :wink:

Shadows
You use a cubemap atlas to pack multiple point light shadows. When you pack multiple cube faces into one atlas texture, I thought borders or artifacts could bleed between faces. Did you add padding or some trick to prevent that? Also, what approach (if any, because right now you did it on purpose, I understand) do you plan or suggest to use for filtering (PCF, soft shadows) to smooth out aliasing in the future?

Depth
As far as I can tell I think you are reconstructing position from depth - how does it actually work, do you use some linearised depth or raw depth? Did you run into issues (artifacts, precision loss or distortions) in this reconstruction, and how did you mitigate them?

BRDF
You mention “a bit of BRDF.” I’m trying to see what’s there, but let me ask - which BRDF model are you using underneath? Is it a common model (like GGX, Cook-Torrance) or is it some kind of a simpler version? Did you try others?

Tonemapping
You state “filmic tonemapping” and that it’s “not perfect yet.” What could actually be improved here? :smiley:

Bottlenecks
Also, out of curiosity, what were the biggest performance bottlenecks? Did any particular pass force you to simplify features? Did you test which pass (shadows, lighting, volumetrics) was the most expensive?

Volumetric light
I’m really am excited about volumetric light too, it looks especially nice in this demo, when you are in this tunnel and you look at the big room, because it has a red tint (because you are under the red light). I wish to understand how it’s done :sweat_smile:

And I’m very thankful you shared it - it’s indeed very modular, clean - looks like everything has a place and it’s relatively easy to read and distinguish, great for learning! :heart:

2 Likes

but I see only vulkan in app.appmanifest

So you can change it: App manifest

The App Manifest is used to add or exclude libraries from the the default build. The Vulkan library is added to also support Vulkan. OpenGL is already supported in the default build using no App Manifest, as long as you don’t exclude it.

It becomes clearer if you open the manifest in the Defold editor, where you can view it as a menu with fields instead of the raw text.

You want to say that if I remove strings → platform_vulkan, graphics_vulkan, I will successfully build the project ?

Why? Do you have any problem building it? Just build it and see if you get errors before messing with files hoping it might be needed.

And if you want to change the manifest, just open it with Defold. Then you can just click on what you want to include and exclude.

I have a problem that my platform doesn’t support vulkan, only gles. But you are right, I will try to build without vulkan.

i’ve removed strings with vulkan and all works on the x86_64 platform.

But it doesn’t work (but the build is successful) on the arm64-linux platform with opengl es with app.manifest like this

Crass dump below on pic