This weekend, I upgraded our game engine's renderer to support PBR — check out how big of a difference it is!

This is a thread full of the steps (and missteps) I took along the way.

#rustlang #gamedev The classic "Damaged Helmet" PBR asset distributedThe classic "Damaged Helmet" PBR asset distributed
Most of the techniques I implemented this weekend came from the Filament PBR docs: google.github.io/filament/Filam…
as well as from Hotham (github.com/leetvr/hotham), a game engine built by my friend @Kane_rogers!
The first thing we had to do was get all of the PBR material information into the engine and start sampling it in our shaders.

Adam, the test character we've been using, is not designed for PBR and the new material parameters are NOT hooked up right. He looks worse than before! A balding guy in a poorly lit environment wearing a suspicio
Next, I adjusted our global lighting to use ✨Physical Units✨ and... got immediately blinded by the sun being 120,000 times too bright.

Someday, I'll come back to the physical units problem, but for now, I just turned down the brightness of the sun by a few orders of magnitude. Oh my god, my eyes! Everything is super bright white from th
After the sun crisis was resolved, I started iterating on how we mapped the material parameters into all these lighting equations I stole from Filament.

I don't think this character's suit is made of red teflon, so something must be up. Enter: the Standard glTF PBR Test Spheres! Person in a red teflon motorcycle suit with a motorcycle helA grid of spheres showing how the renderer responds. The ver
I fixed where the wires were crossed with the red suit guy. I think he's going to be our new test player character.

It's easy to get parameters mixed up, especially when the Metallic-Roughness texture actually stores them in the other order. Oops! The red suit guy's suit is actually made of latex! Surprise!
I imported the Khronos "Damaged Helmet" model to see where we were at. I used our engine's shader hot reloading to flip back and forth between our old and new material models.

Even with just metallic-roughness and direct lighting, things look a lot better! Khronos "Broken Helmet" model with the old materiaKhronos "Broken Helmet" with the in-progress mater
Next, I took a bit of a detour. A longstanding issue our engine has had is the lack of mipmaps.

If you look at the horizon in pictures I've posted before, you can see that the grass is super noisy. That's the moiré effect, and the fix is to generate and use mipmaps.
I added KTX2 texture support to our engine and used github.com/leetvr/squisher — a tool that generates bootleg glTF files with KTX2 textures — and suddenly, mipmapping!

I had to bodge our texture loading at first, so here are before/after screenshots where everything is grass. A grassy man stands next to a grassy spaceship on a grassy fA grassy man stands next to a grassy spaceship on a grassy f
I used the new KTX2 support to redo our skybox implementation. Gone are the days of loading 6 PNG files for cubemaps! A red suit person jumps on a grassy plane floating in space
Then, I was added support for emissive textures. This ended up being really easy and I took some screenshots of the helmet in the dark.

I think there's some future work to do here with bloom once we have an HDR pipeline. For now, it'll work! The "Damaged Helmet" asset in the dark, with a new
A big task on the roadmap was to implement indirect lighting.

Image Based Lighting (IBL) is a technique involving sampling lighting information from cubemaps to compute indirect lighting. I pulled an IBL image from Hotham and suddenly the helmet started looking like this: The Damaged Helmet now has reflections. It's sitting in the
The IBL I used looked like it was taken in the middle of a photography studio. There aren't a lot of details, it's black and white, and it's really bright.

But... now we had reflections! The helmet suddenly became shiny and that was really exciting.
The final bit of material information to hook up was the ambient occlusion texture. It adjusts the amount of indirect lighting an object should receive in a given spot.

It helps add detail to the nooks and crannies of an asset on the very small scale. It's pretty subtle! Damaged Helmet without ambient occlusion.Damaged Helmet without ambient occlusion.
Finally, I found a reasonable HDR image online and wrestled with PVRTexTool to generate a new IBL.

I tweaked our lighting a bit more and... boom! The final result: Broken Helmet sitting in the middle of the MIT campus, with
I learned a ton about rendering and lighting during this project.

This was my first time implementing these features in a renderer and it was a lot easier than I expected. There's a lot more to learn and do, but this is a great foundation for our future work.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with lpg@mastodon.gamedev.place

lpg@mastodon.gamedev.place Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(