Open Try opened 1 year ago
Added probe-caching; continue cleaning-up lightingcode:
~3k probes are recalculated each frame ~27k in total No SSAO/Bent-normal integration (yet?)
Need to refine caching scheme: cache ray-hit instead of irradicance
Some more screenshoots:
Rework for probe-grid lod:
Now probes do have almost consistent distribution in screen-space with similar budget
Still working on secondary bounces. More screenshots:
black-and-white version
Wanted to play with RT for ages and never found a FOSS implementation i liked. Following your work here, and very thankful to read your notes and results.
Metal backend also works now:
Not much FPS on M1, yet still happy that Metal-backed now has less bugs :)
Updated albedo-fetch heuristics:
Notes: albedo-fetch is a horrible hack that enables usage photo-texture of vanilla game, and attempts to extract usable color information
Working on narrowing down, what is not working. When similar view-angle rendered with albedo=0.9
image look correct:
Still tuning textures/color-bleeding.
GI:
No-GI:
Going thru https://physicallybased.info
Sun (above atmosphere): 143'000.f -> 128'000.f Sun (on land): engine results in ~100.000f, matches real world observation Sky (median) was ~3% of sun-light (too low), after changing ground albedo factor (0.1 -> 0.3), becomes ~4.7% (correct)
Uniform-ambient is estimated as:
~sun * transmissioni * ang * p * 0.5 * 2pi
~ - bunch of hacks; TODO.
After many adjustment:
The latest screenshot looks more and less physically correct at the same time. The intensity of direct sunlight looks less clipped, but the GI deep inside the building looks gone, allowing that ghastly blueish fake GI they did to show through. 🤔
upd. Though, on a second thought, there wouldn't be enough energy for indirect sunlight to bounce so many times and color everything orange... Anyways, some AO feeding on your GI implementation is also needed. Removing the effects of these blue-tinted light probes would do wonders for the general aesthetics.
Main issue with GI (or lighting in general), when it comes to gothic, are materials. Or should I say - lack there of.
GI (and diffuse lighting) needs albedo data, but only thing we have in assets is a "photo-texture". For the sake of rendering I have heuristics here:
photo_texture = gamma(tonemapping(exposure*pbr(material)))
exposure * pbr(material)
exposure * (1/PI) * dot(N,L) * albedo
dot(N,L)=1.0
, simplify and we have C * albedo
, where C
is some constantThis is path one. Part 2: this heuristic has to be symmetrical with engine lighting.
gamma(tonemapping((engine_lighting(albedo))) ~= photo_texture
- this is formal way to say image should be similar to vanilla,C
, to be something close to 1.0Part 3. Due to the way inverse-tonemapping works, acesTonemapInv(1.0/*white*/) = inf
acesTonemapInv
, resulting in this abomination:
vec3 textureAlbedo(vec3 rgb) {
const vec3 linear = srgbDecode(rgb);
return acesTonemapInv(linear*0.78+0.001)*5.0; // adjusted to have 'realistic' albedo values
}
... and now it violate P2, to avoid inf
Anyways, some AO feeding on your GI implementation is also needed
I do simply multiply GI by AO (what is not correct, but give at least some detail). Here is AO
Probably it would be better to use output bent-normal, from AO pass and use it intead
Is it possible to further adjust AO so that it would work not only by seeking intersecting geometry but also volumetrically, with respect to how your GI works by gradually shading the whole interior?
Sorry, I don't know what do you mean. If AO is by definition ratio of ray-hit/ray-miss, and if shader checking not only intersection - than it's not AO
gradually shading the whole interior?
Scene above is not interior:
When it comes to castle wall, it expected to be split 50:50, between ray-misses (samples sky-color) and hit on street floor. Street-floor has no direct component (it's in shadow), and indirect is also sky*albedo
2k shadowmap unfortunately not good enough to take care of shadow-term. Also secondary-bounces are disabled, as I'm debugging atm.
almost like lumen:
Debug view of ray-hits (needed to evaluate solution for secondary bounces):
Been evaluating different approaches for iradiance cache and secondary bounces. Unlike Lumen, in OpenGothic we cannot do offline baking, and have to have runtime solution for gi-scene.
Here example of hash-map of primitives that been touched by rays:
Every colored triangle is a single cache-entry and small primitives are also tessellated by bird-curve, to improve resolution a bit. Still not OK unfortunately: too much memory (~200+MB) and too low res
Concept
First prototype (branch: https://github.com/Try/OpenGothic/tree/gi-rendering)
and probes(~30k):![изображение](https://github.com/Try/OpenGothic/assets/122894/2e197177-f855-4f5e-8145-2e95e5047082)
Reference materials:
Lumen: https://advances.realtimerendering.com/s2022/SIGGRAPH2022-Advances-Lumen-Wright%20et%20al.pdf![изображение](https://github.com/Try/OpenGothic/assets/122894/b4a8923a-af0a-4e70-aa15-83ee08842347)
Combination of screen-space probes and world-space cache, for HW-RT part. In paper there is a lot about SDF and software ray-tracing, yet we wont do it, as so requires precomputational part in asset-pipeline
EA-surfels: https://www.youtube.com/watch?v=h1ocYFrtsM4![изображение](https://github.com/Try/OpenGothic/assets/122894/08c41866-576f-4a3b-a431-df47bd9e981a)
PRT probes: http://mrakobes.com/Nikolay.Stefanov.GDC.2016.pdf![изображение](https://github.com/Try/OpenGothic/assets/122894/0c977aa4-970a-4780-8130-fe78f91f1d44)
Personally prefer this workflow (except we will have to do ray-casting in runtime)
Good summary on light-leaks : https://handmade.network/p/75/monter/blog/p/7288-engine_work__global_illumination_with_irradiance_probes
Nice open-source project with multiple techniques implemented: https://github.com/EmbarkStudios/kajiya/blob/main/docs/gi-overview.md