I’ve been working on PBR env map generation again and I’m in the mood of talking about it… so bare with me.
TL;DR if your PBR env lighting looks like crap with some envs, you may need to use “HighQuality” as a parameter when you generate your light probe, but it will be slower.
I happened to be testing a particular env map in JME, from this wonderful web site (that I recommend btw) https://hdrihaven.com/hdris/
Especially this environment https://hdrihaven.com/hdri/?h=flower_road
It was producing very shitty lighting in JME and I didn’t know why:
Shitty heh? this is done in 4.4 seconds.
I talked with my coworkers and it turned out that this env map has a huge lighting range. from 0 (the darkest spot) to 380000 (the brightest spot). Yes there is no typo.
You may not be familiar with how env maps are generated, but in short, we generate several blurry images of the env map, dividing the size by 2 for each new images. Those additional images are stored in the mip map of the env image and when rendering we go fetch the right one depending on the roughness of the material… easy.
But when you say “blur”, you say “samples”, and when you say “samples” you often say “lot of samples” to have good blur quality. And when you say “Lot of samples” you say “dead slow”.
In the original implementation we had progressive samples, meaning that we increased the samples depending on the mip map we were generating (because the more the roughness increase the blurrier is the image). so it was basically 1 for the first image (no need to blur this one) and up to 8192 for the last one.
Seems it’s not enough for this env map.
So I tried the blunt way of increasing these numbers… and went up to 131072 samples for each map except the first one and it literally took hours… for a shitty result (less shitty than the previous one… but nothing that’s worse hours).
So I dug up some implementations (have to say that I had huge hints from my sketchfab fellows). And it turns out there are some nice techniques to drastically reduce the number of samples you need.
first one, is to generate mip maps for the original env maps, and instead of fetching the samples in the biggest images, go fetch in the mips depending on the sample. There was a huge improvement
This was generated in 5.5 seconds.
Pretty cool, my hours long generation was not even close to this.
Though you can still see some weird patterns, and while it looks okish on spheres it was giving me very bad shading artifacts on real objects with different levels of roughness.
So I went ahead and added another step. the idea is that for each sample, we rotate it a bit and take another sample. Then we do it again. I achieved good results by rotating 18 times the samples for each pixels and here we go.
But of course… more samples… so more time, this one took 68 seconds to generate…
I figured it was a good compromise for this quality.
So I introduced a GenerationType params when you generate an env map. “Fast” won’t do the sample rotations, “HighQuality” will.
The thing is… Some env won’t need that high quality to work well
For example here is the path.hdr we have in the sample textures generate
There is literally no difference.
As a reference the old method for this env
So, whenever you generate your light probes and that you find that for a particular env map the lighting looks like crap… you may need to set “HighQuality”. Else you can keep the “Fast” (default) setting.