AGK HDR lightmapping

Started by GaborD, January 18, 2019, 10:43:49

Previous topic - Next topic

GaborD

I have to make some demos and got tired of slow noisy Blender lightmaps and all the conversion steps to get the HDR data to AGK, so I dug up some old test code and started implementing a quick own lightmapping solution in AGK.

Supports HDRi / image based lighting (could light up the whole scene just with a sky HDRi without mixing in a realtime sun), up to 4 precalced realtime lights per surface, each with correct soft shadows and accordingly attentuated speculars, auto-padding, adjustable blurring of the result, an extreme range (from a billionth to about a million brightness, if we assume full LDR range to be 0 to 1), dual lightmapping and correct mixing of dynamic shadows with the soft precalced ones, a controllable light-bounce count, full support for emissive and translucent surfaces and contact hardening soft penumbras (light sizes can be set for each light).

The system can also produce directional lightmaps if needed so that normalmaps correctly work with the bouncelight (the direct light is already realtime, so that works anyway), it will also create all the corresponding PBR probes and I also want to implement an idea for reflections on planar and bigger surfaces (which are hard to get to look right with just probes) that doesn't rely on constant flipped cam renders or slowpoke pathtracing for SSR (That said, I will probably port my NB SSR solution as an option for surfaces where it's a good fit).

So basically all the hassle of creating a fully lit PBR scene with semi decent quality HDR lighting simplified and condensed down to a button press. Will make life so much easier haha. 
Will see how it goes. Quality is not too bad for a first rough implementation but can still be improved a lot.
It's a pretty bruteforce unbiased solution, should produce mostly reasonable results, but bounce and direct light strength can be also adjusted independently at runtime for a more artistic approach and effects.

Lightmap resolutions and also the sample counts are flexible on a per object or group basis, it's also possible to use different map resolutions for the shadows and the bouncelight (bounces usually don't need high rez), so there is full flexibility for speed vs quality and quick lighting tests.
Simple and directional lightmaps can also be mixed in the scene and will match up correctly.
Later I plan to add outdoor rendering focussed features too. But that's for a later day, don't need it for my planned demos.

The test-scene is admittedly very simple, but made to be a worst case scenario with big totally flat surfaces that have smooth lighting gradients and also some pretty saturated colors (always prone to banding and causing weird lighting).

Here are some test screens directly from AGK, just the diffuse lighting on the smooth untextured sufaces. (textured surfaces would ofcourse bounce correctly colored light based on their texture, same for emissive and translucent surfaces)
Click the thumbs to open them in a new tab and click again to enlarge, the images are pretty big.
AA could be better, didn't port my whole post chain over yet. Lazy.
So much to do...

   

 

Madjack

Aww yeh! Gabor's back, back in the shader hoouse!!!  :D

Steve Elliott

Win11 64Gb 12th Gen Intel i9 12900K 3.2Ghz Nvidia RTX 3070Ti 8Gb
Win11 16Gb 12th Gen Intel i5 12450H 2Ghz Nvidia RTX 2050 8Gb
Win11  Pro 8Gb Celeron Intel UHD Graphics 600
Win10/Linux Mint 16Gb 4th Gen Intel i5 4570 3.2GHz, Nvidia GeForce GTX 1050 2Gb
macOS 32Gb Apple M2Max
pi5 8Gb
Spectrum Next 2Mb

Rick Nasher

Nice beginning. Can't wait to see the next development given your previous work.

I'm guessing you are using a high spec system?

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Qube

Very nice :) - You should make your own AGK shader pack for sale.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

GaborD

Thanks for the comments!
I am really having fun with this.
Once all the PBR shenanigans are in I'll make a vid with a better scene. Have some fun ideas for effects and whatnot.
I want to push this until I have a full openworld RPG system with modern graphics. 


Quote from: Qube on January 18, 2019, 18:40:48
Very nice :) - You should make your own AGK shader pack for sale.

I have some things planned. Last year was unfortunately a big mess and life got in the way, but this year will hopefully be better. :)
My idea is to keep working on the RPG system and maybe make packs and tutorials out of the stuff I develop on the way.
I used to have PBR tutorials on the NB and some other forums, didn't get much feedback (other than one guy flaming me because I put something he considered to be a "code snippet" into the "tutorials" section... thing is, there was no "code snippet" section, so yeah, whatever. I still remember that one lol) but I hope it helped some people none the less. Would love to do stuff like that again for AGK users, just need to find the time for it.
In my opinion AGK is very underrated because people just see the stock stuff. It can do much more with a bit of effort.


Quote from: Rick Nasher on January 18, 2019, 16:36:34
I'm guessing you are using a high spec system?

I'd call it upper midrange, it's a GTX1070.



RemiD

#6
woaw ! nice  8)


so, with your shader wizardry, can you blend dynamic (real time) per pixel shadows (of animated characters) with static (precalculated) per texel shadows (of the environment) ? ( tricky question, that only the enlightened ones understand ;D )

GaborD

Yes, exactly.
Besides the better static shadow quality this allows, it's also a really nice speed boost for dynamic shadows with only the dynamic objects needing to be rendered into the map.

Rick Nasher

Wow. RemiD, you just called me enlightened!  :P
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

RemiD

#9
Quote
Wow. RemiD, you just called me enlightened!
we are that cool :P


@Gabor>> so how do you know when to add (or not) a dynamic shadow color to the (pixel) of an area of scene, since from my limited understanding of shader, you use per pixel data, and not per texel datas ? (a texel can have a dark color because of its material / texture, but not necessarily because of a (precalculated) (texel) shadow).

GaborD

#10
Quote from: RemiD on January 19, 2019, 20:56:23
so how do you know when to add (or not) a dynamic shadow color to the (pixel) of an area of scene, since from my limited understanding of shader, you use per pixel data, and not per texel datas ? (a texel can have a dark color because of its material / texture, but not necessarily because of a (precalculated) (texel) shadow).

The two shadows are multiplicative, so you can just combine them to one shadow value and then use that to attentuate the sunlight.
The material color of the surface is not in play at this point.
You only multiply it in after you have the combined incoming diffuse lighting. (direct lighting + GI)

So basically (for non-metals): combinedDiffuseLight * surfaceAlbedo + reflections.
(reflections don't get influenced by the surface color. They just get added on top)

For metals it's much easier, because you don't have any diffuse lighting (their albedo is black), so for metals you can skip the entire diffuse stuff.
But, the metal's specular color tints the reflections, which non-metals as seen above don't do (their spec color is essentially white), so that has to be taken into account.

This is why in order to get somewhat realistic looking metals, you kinda have to move towards PBR. You need the reflections, because that's all they are.
The big difference is, diffuse light is static (if the object and the light are both static) no matter which direction you look at it from. Reflections on the other hand are ofcourse view dependent and will shift around if the camera moves.

edit: I went off on a tangent, sorry for that lol.

RemiD

#11
@Gabor>>i am quite ignorant about how per pixel shadows are made, so my question was more : in your procedure, how do you determine if a pixel (on screen) of a shadow of a turning moving shape, must be colored in the shadow color (because the environment does not have a shaded area / shadow at this place (texel)) or not (because the environment already has a shaded area / shadow at this place (texel)) ?
Do you start from the surface -> triangle -> texel -> corresponding 3d world position, of the shadow / light map, then convert it to the pixel screen position, then decide, depending on the color of the pixel (determined by the "rendering" of the shadow / light map) if the pixel is already a shaded area / shadow or not, and if there is a need to color it with the shadow color or not (because of the "dynamic" shadow of a turning moving shape projected to this same area)

i hope this is clear ;D

GaborD

#12
Yes correct, the dynamic shadowmap lookup uv is calculated in the pixel shader from the 3D position (which is coming from the vertex shader instances of the 3 parent vertices.)
The static smooth shadow factor is just a texture lookup based on the second object UV set. (so just like the lightmap for GI)

I just fetch both shadow values and multiply them together to have the overall shadowing factor for the light they belong to. (will always be between 0 for full shadow and 1 for no shadow, so that we can just simply multiply the light color with it)
I don't think of it in terms of screen position or pixel/texel or "drawing shadows" at all. It's just an occlusion factor for a single light.

In a pixel shader, I generally don't think of screen positions.
The screen position can't be changed anyway, the pixel shader instance runs for some pixel position somewhere on the screen, I don't need to know which one. The texture lookups will be based on object UVs anyway. (even in Post while doing fullscreen effects, I'm just drawing an UV'd 3D object. It just happens to be a quad aligned to the cam, but that's irrelevant in the pixel shader.)
That said, you can look up the screen position with gl_FragCoord.xy, it's just almost never necessary. (there are exceptions ofcourse, like planar flipped cam reflections being drawn directly in non-screenquad object shaders, but those are barely used anymore these days, everyone loves SSR so much haha. I don't. :P Time to bring back oldschool!)