Jump to content
The Dark Mod Forums

Trying to simulate bounce lighting... the (not so) easy way


MirceaKitsune

Recommended Posts

With actual raytracing being a long time away from even being imaginable in our engine, I've become a growing fan of simulating bounce lighting with the conventional lighting system we have. It's good for realism and because I love that warm soft light emanating beyond walls from one candle in a dimly lit area behind. TDM currently has no global illumination, the only form of estimating GI being a constant light that changes per area based on the amount of lights in that portal zone (great system but not enough).

Today it just occurred to me that for starters, it wouldn't be that hard to attempt a simple yet more effective estimation. Initially I was going to write a script for it before realizing I could just do this via defs alone! The rule is simple: For each normal light, we attach a secondary light of roughly the same radius, textured with a low-intensity ambient light (lights/ambient_biground) to simulate directionless diffusion with minimal impact on performance. I wrote one def for my bounce lights and another to override all of the builtin light types and attach the appropriate one and that was it! Kind of, it's never that simple. Here's my patch in its initial form and a few screenshots of what it achieves, mainly noticeable as a dim light showing through the shadow of the standard one.

tdm_bouncelight_v1.0.pk4

VOm7PCc.jpg

vMXofU4.jpg

68Nxpby.jpg

Gd65EGl.jpg

NxH8zTI.jpg

wvREoKx.jpg

Of course it's not all rainbows and sunshine. As you probably expected, this approach has the fatal flaw of lights shining through walls as the area lamp casts no shadows. This looks horrid from other angles where you see walls being lit out of nowhere by sources on the other side.

9EGvmFN.jpg

WxN3Qto.jpg

That's the result of candles and torches shining through the floor from other rooms... not okay and unfortunately a deal breaker until I found some way to fix it. Apart from this it appears that with a lot of lights in more complex maps, performance takes a considerable hit while even freezes and crashes are being introduced by the extra lights... I find this strange given ambient lights cast no shadows nor do they do per-pixel calculations like specular or normal mapping, and most don't even move so shouldn't they be cached?

I don't know to what extent it would be a waste of time to approach this further: On one side it's a tedious task and my hope of getting it to work with just one extra light is naive... on the other side as you can see from the first batch of screenshots, it can look gorgeous if done right, this gives us a glimpse of what we could have with a proper system. Normally this needs to be coded in the engine to get any sane results anyway, especially as this setup calculates no actual bounces just adds a radial glow to estimate it, surfaces don't colorize the light and there isn't any real bouncing going on in any form. Of course I don't have a fraction of the knowledge to do that, and I'm not gonna be this cruel to @cabalistic and other graphics devs to suggest this after all the other exciting yet difficult ideas I've been bringing up.

What are your thoughts on this? Can you suggest any tricks to fix the lights going through walls when they shouldn't, or perhaps a better approach altogether? Maybe I can define my own light texture to reduce wall leaking but not destroy the immersion otherwise?

Edited by MirceaKitsune
  • Like 3
Link to comment
Share on other sites

  • MirceaKitsune changed the title to Trying to simulate bounce lighting... the (not so) easy way

I use quiet a bit of faked ambient lights and have the same problems. The only work around Ive found is to make a couple generic light textures and falloffs for most situations; square, round, etc. Its not ideal and it’s very tedious to hand place them, but it does look cool!

  • Like 1
Link to comment
Share on other sites

Things look wrong because the added light (let's call it VPL = virtual point light) doesn't cast shadows.

One well-known algorithm for global diffuse illumination is "Instant Radiosity", where 1) there are several randomly generated VPLs, and 2) VPLs do cast shadows. Of course, a lot of work is needed to make it work fast enough.

I'm afraid there is no way around light passing through walls. If you think more about it, there is no way to distinguish between "yes, we allow light to pass through this thing", and "no, this thing should cast shadows", especially if player can more light source. And if he cannot, then let's better discuss lightmaps 😃

Link to comment
Share on other sites

TDM ambient lights do calculate normal and specular shading.

The only performance you save is shadows. ( no free lunch )

 

There are multiple ways to simulate bounce lighting.

The most popular being the use of no-shadows lights with ai_see set to 0  ( see "Sir Talbot's Collateral" ).

 

Spooks showed how to use cubemaps for GI / ambientCubicLight

( We hope to extend that approach with probes in the future. )

 

Finally, if you have very good spacial reasoning, you can use the "Strombine" method:

http://www.lunaran.com/maps/quake4/strombine/

 

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

Yes is unfortunate how idtech 4 lighting has little to no GI capabilities I wonder how Metro games before the raytracing one does it's GI stuff, all lighting on Metro is fully dynamic and still shows plenty of ambient bounce. 

Cryengine for example uses a special voxel system for GI and all its lighting is also fully dynamic, no lightmap baking on that engine.

About the extra lights shining through walls, perhaps you turn them off, when the player is out of the zone/room they are in? This will need a script but imo is doable.  Do lights still shine even if they are on a room where the portal zone they are in is closed? 

Btw don't think this will solve the light leak but if you really want a "free" light, don't use the ambient light materials, use a light with a light material with the "blendLight" keyword in it.

Blend Lights are just very simple additive lights, used mostly in Doom 3 to simulate fake shadow maps, they do no interactions with surfaces, so afaik no real lighting, no shadows and no specular/normal maps. 

Edited by HMart
Link to comment
Share on other sites

Something I should better clarify just in case: I'm not working on implementing this for a FM, which would be easier (albeit very tedious) if you know where to place your bounce lights. What I want to achieve is a global mod that works with all FM's automatically, by playing with the defs and perhaps using a script to generate them.

To make matters worse in a good way, I want it to work for moving lights as well not just static ones, meaning a candle moved in a dark room should produce the same soft lighting around obstacles. For performance this will be even harder as you couldn't get away with tracing at map start but must do so each frame, albeit you can define a position resolution so it's only redone when the light moves by a certain amount. The scripting system has an ability to trace lines and see when they hit a surface, not sure how that can be used to achieve anything sound in this case.

The threat you linked @nbohr1more is very useful and insightful! makeIrradiance() seems to be a method of baking a light texture from the skybox... not exactly what I want but it could have its uses. What has my attention most is a keyword indicating you can bake a cubemap in realtime from the perspective of any entity... is that correct, and how much can you customize what it captures? I wonder if then I could attach one light to the player to capture irradiance from their perspective each frame... might not work since for this you need to catch lights hidden behind walls too.

Then I'm wondering if maybe just maybe we could do this all in GLSL as is right. I found discussion of people managing to estimate irradiance with shaders, but obviously it depends on the information said shaders have access to: In our engine can it see all of the geometry including light sources behind walls or the camera? This approach would be great not just for being more consistent, but it would be done on the GPU which is faster and better at such stuff. The person in this video from 2016 confirms they're using GLSL, not Vulkan or anything fancy we don't have yet... I understand it's for their own engine which may have different access to triangle and texture data, but it's a promising idea.

 

Link to comment
Share on other sites

So far the only salvation for achieving it this route appears to be realtime cubemaps, with a newer cubiclight implementation which seems to be intended precisely for supporting irradiance in a basic form. It depends on what I can actually get it to do in realtime, namely if I can paint the "voxel" points on it accordingly to get estimative bouncing.

https://wiki.thedarkmod.com/index.php?title=Light_Properties

I also just discovered fx files and the func_fx entity with this occasion, wasn't aware that was being used to simulate lightning. Wonder if that would make this easier to do so a script can be avoided.

Link to comment
Share on other sites

One thing Cabalistic clarified me on: We do not have and likely never will have deferred rendering. So any shader method we use must not rely on that in particular.

Something else I just noticed and wasn't aware of: You can apparently put custom shaders on materials, not sure if just ARB or also GLSL ones. You can find for lines like "vertexProgram whatever.vfp" in materials such as tdm_bloom_afx.mtr. Can anyone better explain what those can be made to do please, without requiring changes to the engine of course?

Another question: Can a script use the startFx(foo/bar.fx) command on worldspawn to create a global light, or have a fx spawn on its own at map start some other way? I'm thinking of using the fx system as an alternative to scripting, especially with the multi-addon conflict issue still being unworkable around.

Link to comment
Share on other sites

At the moment I feel pretty stuck: Engine changes may be needed in the end, even for a cheap estimation that can do the minimal thing of not leaking through walls it can't physically travel past.

My last hope was to try modifying the default ambient light material and turn it into a cube, knowing every map has one of these surrounding it so it would automatically work on most. At the moment darkmod/tdm_textures_base01.pk4/materials/tdm_light_textures.mtr/lights/ambientlightnfo looks like this:

lights/ambientlightnfo
{
	ambientLight

	lightFalloffImage makeintensity( textures/lights/ambientlightnfo)

	{
		forceHighQuality
		map textures/lights/ambientlightnfo_amb
		colored
		zeroClamp
	}
}

With my idea it would probably be something like this... correct any obvious mistakes there.

lights/ambientlightnfo
{
	ambientCubicLight

	lightFalloffImage makeintensity(textures/lights/ambientlightnfo)

	{
		forceHighQuality
		map textures/lights/ambientlightnfo_amb
		colored
		zeroClamp
	}

	{
		forceHighQuality
		cameraCubeMap	env/my_realtime_cubemap
		colored
		zeroClamp
	}

	sort postProcess
	{	
		vertexProgram 	bounce.vfp
		fragmentProgram	bounce.vfp

		fragmentMap 0 _currentRender
		fragmentMap 1 _fsfx_input
	}
}

If bounce.vfp doesn't know the geometry and lights in the area however, there's not much I can do then. Hoped I was onto something but any approach has a lot of complexity attached to it.

Link to comment
Share on other sites

If that 2nd stage even worked (Hint AMD drivers have never allowed it in the past and the current backend does not blindly execute shader operations the way that Doom 3 native did), the programs would execute against the 2D inputs without respect to the surface position and projection direction.

Also, sort postProcess is something you do when you are forcing the whole scene to render before you perform your own render operation. It is meant for things like bloom, toon shaders, and some transparency effects where you are using a full screen overlay.

Also, if this is for the ambient world then you are running on some sort of assumption that the ambient world can possibly know anything about other lights in the map. Currently, it cannot. There was a proposal to have the dynamic location script query the lights in an area and generate an average color for the local ambient but nobody has worked on it yet.

https://bugs.thedarkmod.com/view.php?id=2354

Though this won't magically improve visuals. Mappers can already tune the location based ambient to match the expected ambient color for the lights in an area. The only additional benefit besides being an "easy button" for choosing the right ambient color is that it could be dynamic so that extinguished lights would alter the ambient baseline.

I guess one approach would be to blend a blurred output of the fullscreen ( _currentRender ) to the final ambient light result since it would at least provide some color matching and might give some localization to the lighting too but it would probably not look too hot without artist tuning ( it would aggravate Duzenko ...)

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

On 9/25/2021 at 5:48 AM, MirceaKitsune said:

Of course it's not all rainbows and sunshine. As you probably expected, this approach has the fatal flaw of lights shining through walls as the area lamp casts no shadows. This looks horrid from other angles where you see walls being lit out of nowhere by sources on the other side.

9EGvmFN.jpg

 

 

Not sure whether I fully understand the problem.

However, Dragofer provided me with the following property/values for the lights when I had a similar same problem with electric lamps in HHTLC:

"areaLock" "origin" -> ties the entity's visibility to the visleaf in which the origin lies

"areaLock" "center" -> ties the entity's visibility to the visleaf in which the center of its dimensions lies

Might be worth a try.

 

  • Like 2
Link to comment
Share on other sites

6 hours ago, JackFarmer said:

Not sure whether I fully understand the problem.

However, Dragofer provided me with the following property/values for the lights when I had a similar same problem with electric lamps in HHTLC:

"areaLock" "origin" -> ties the entity's visibility to the visleaf in which the origin lies

"areaLock" "center" -> ties the entity's visibility to the visleaf in which the center of its dimensions lies

Might be worth a try.

Very useful, thank you! Vis leaf meaning to that portal room, restricted independently of whether the room is being hidden or shown? This might be able to save my original setup; It will still go through plain walls, but at least not between whole rooms and buildings which was the real issue. On the downside, you'll likely see inexplicable lines where the light cuts off in front of doors and around some walls... of course it's a case of the lesser evil here will be better for sure.

I wanted to ask something else while at it, please let me know: Is it possible to have one light material that combines diffuse light with am ambient light? Or can lights only be one of the two at a time? Something like:

lights/fire_fireplace
{    
	{
		forceHighQuality
		map		lights/biground1
		colored
		zeroClamp
		red		((.2 * torchtable [(time * ( 2 + Parm3 ) + ( parm4 / 10 ) )]) +.6) * Parm0
		green	((.2 * torchtable [(time * ( 2 + Parm3 ) + ( parm4 / 10 ) )]) +.6) * Parm1
		blue	((.2 * torchtable [(time * ( 2 + Parm3 ) + ( parm4 / 10 ) )]) +.6) * Parm2
	}

	ambientLight
	lightFalloffImage	makeintensity( textures/lights/brightround )
	{
		forceHighQuality
		map	textures/lights/brightround_amb
		colored
		zeroClamp
	}
}

If these two be mixed in the same place, I could try dumping even the extra lights and implement estimative irradiance by messing with the materials alone. Since there's also the issue of the new lights not only hammering performance but even crashing or freezing the engine in a larger FM for me, odd as it is for a mere ambient light to do that.

Link to comment
Share on other sites

Honestly it would have been cool if NVidia had taken TDM and made an RTX version like they did with Quake 2. It might have had more appeal to the mainstream.

 

But remember that if someone just slapped full path-tracing onto TDM tomorrow, it would cause all sorts of missions to fundamentally be changed, since they were not designed with that in mind, and unlike in most games, light plays a critical role here.

 

But still, since TDM is all open source, path tracing is probably closer than you think. As in, at least it is possible that we will see it one day.

As for approximating things, take a look at this interesting addition to Blender Eevee, the new real-time engine.

Edited by kano
Link to comment
Share on other sites

4 minutes ago, kano said:

But still, since TDM is all open source, path tracing is probably closer than you think. As in, at least it is possible that we will see it one day.

No, I can assure you it is quite far away. OpenGL has no support for ray tracing, so you'd first need to write a Vulkan renderer for it. And that is most certainly a very daunting undertaking.

I mean, one day we'll migrate to Vulkan, sure, but that's not close in any meaningful sense of the word, I'd say :)

Link to comment
Share on other sites

2 minutes ago, kano said:

Honestly it would have been cool if NVidia had taken TDM and made an RTX version like they did with Quake 2. It might have had more appeal to the mainstream.

But remember that if someone just slapped full path-tracing onto TDM tomorrow, it would cause all sorts of missions to fundamentally be changed, since they were not designed with that in mind, and unlike in most games, light plays a critical role here.

But still, since TDM is all open source, path tracing is probably closer than you think. As in, at least it is possible that we will see it one day.

If it was that easy I'd be suggesting it instead, and believe me I'd love TDM with RTX as much as anyone else 😁 Realtime raytracing is still in early stages and only attempted as an experiment so far: Few graphics cards support it, when they do the drivers need to have it too (not just for Windows but also Linux and iOS), and needless to say it's painfully slow so you're saying goodbye to any decent FPS. For our engine, especially at this point in time, the easiest solution is to use estimations... they can be pretty good when you don't need absolute precision, only problem is we don't have even those in places.

As far as bounce lighting goes, Godot is a great example of someone finding a way to achieve that efficiently. Particularly the upcoming 4.0 which will have realtime global illumination without any probes required, I'd look up its SDF system! Don't know how they do it technically and if it requires bigger changes our engine can't undertake.

There's also Tesseract (Cube engine fork used by Red Eclipse) as an example. That has bounce lighting... only for the sky I believe, but you can set a daytime and the scene automatically bakes light bounces from the sun.

I just recently discovered that even Xonotic with its Darkplaces engine has this! It's hidden in a dark corner of the cvar list but is there: In the console you need to enable r_shadow_bouncegrid and play with the r_shadow_bouncegrid_* cvars, I actually made a custom config for that which looks very decent. It's not perfect but does a pretty good job I must say! As it's a fellow quake engine perhaps someone could snatch that code and integrate it? Here's what I managed to do there just by playing with those settings in the console, everything in realtime obviously:
 

Spoiler

lZu4cpq.jpg

fiz1XaX.jpg

q9SMtAh.jpg

2rc6x7y.jpg

eSWXz4r.jpg

w5MGSQP.jpg

 

Link to comment
Share on other sites

33 minutes ago, MirceaKitsune said:

Very useful, thank you! Vis leaf meaning to that portal room, restricted independently of whether the room is being hidden or shown? This might be able to save my original setup; It will still go through plain walls, but at least not between whole rooms and buildings which was the real issue. On the downside, you'll likely see inexplicable lines where the light cuts off in front of doors and around some walls... of course it's a case of the lesser evil here will be better for sure.

I wanted to ask something else while at it, please let me know: Is it possible to have one light material that combines diffuse light with am ambient light? Or can lights only be one of the two at a time? Something like:

lights/fire_fireplace
{    
	{
		forceHighQuality
		map		lights/biground1
		colored
		zeroClamp
		red		((.2 * torchtable [(time * ( 2 + Parm3 ) + ( parm4 / 10 ) )]) +.6) * Parm0
		green	((.2 * torchtable [(time * ( 2 + Parm3 ) + ( parm4 / 10 ) )]) +.6) * Parm1
		blue	((.2 * torchtable [(time * ( 2 + Parm3 ) + ( parm4 / 10 ) )]) +.6) * Parm2
	}

	ambientLight
	lightFalloffImage	makeintensity( textures/lights/brightround )
	{
		forceHighQuality
		map	textures/lights/brightround_amb
		colored
		zeroClamp
	}
}

If these two be mixed in the same place, I could try dumping even the extra lights and implement estimative irradiance by messing with the materials alone. Since there's also the issue of the new lights not only hammering performance but even crashing or freezing the engine in a larger FM for me, odd as it is for a mere ambient light to do that.

You cannot mix ambient light and standard light defs. ambientLight is a global property and so is noshadows. You can add multiple projection images but doing so is more expensive than simply merging them in photoshop. Adding this capability would offer some performance advantages though since you could re-use geometry cache.

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

On 9/25/2021 at 10:20 PM, MirceaKitsune said:

Something I should better clarify just in case: I'm not working on implementing this for a FM, which would be easier (albeit very tedious) if you know where to place your bounce lights. What I want to achieve is a global mod that works with all FM's automatically, by playing with the defs and perhaps using a script to generate them.

Well, I'm almost certain you won't be able to do that.

Of course, I'm known to be quite pessimistic...

7 hours ago, JackFarmer said:

"areaLock" "origin" -> ties the entity's visibility to the visleaf in which the origin lies

"areaLock" "center" -> ties the entity's visibility to the visleaf in which the center of its dimensions lies

It is useless for dynamic situation.
As soon as player mover light source close to doorway, everything breaks.

And for static situation, precomputed stuff is much more realistic, and probably easier to achieve.

Link to comment
Share on other sites

Thanks again for your suggestion @JackFarmer that areaLock spawnarg was a godsend! Tried it out and it fixes my setup much better than I expected. All wall leaks are gone and I get just the desired soft lighting! This is amazing :)

HDRzE5g.jpg

x4BORv3.jpg

b2Qpb6S.jpg

nkgpSAr.jpg

Other FM I'm working on, more complex outdoor examples:

owhykIL.jpg

B5kjefl.jpg

fAG47Qj.jpg

masbjQj.jpg

Performance has obviously improved as well, still slower but noticeably better. The crashes I was getting in this later area, likely caused by all the glowing mushrooms which have this too, appear to be gone for now.

The light cutoff at portals is almost unnoticeable and shouldn't bother anyone. In part because the bounce light is very low-intensity, and on top of that it's usually covered by the original light source when it's not in a shadowed area. Here's an example when you can barely notice it if you take a close look and want to look for it.

FRjqRpQ.jpg

Only thing I'm still unhappy with is that the extra lights can't follow and adjust themselves to the color as well as radius of the normal light. Each bounce light is already tailored to the light it's representing, but if a mapper makes changes to say an electric lamp the glare won't automatically adapt as well, they'll need to define their own version of its bounce and override my def_attach1 with it.

I want to tweak the color and radius again before posting a new version of my pk4, but the coming one should be safe to use and play with. In this form I think the idea of including this mod in vanilla TDM behind a disabled cvar might just be imaginable ;)

  • Like 1
Link to comment
Share on other sites

Another thing I must point out: In spite of the arguments I had with someone over that during the summer, this is one situation where hide_distance for lights finally being supported is going to be very helpful and should fix the performance issues I've been getting here! Given how subtle they are, those lights only need to be seen up close and you shouldn't notice when they disappear at a distance. Will give it a try a bit later and see what difference it makes but I'm sure it will help without any visual disturbance. So yes, despite certain opposition it was very much worth it when I least expected 😁

Until I finish up and prepare the next update possibly tonight: Let me know if there are other spawnargs you advice me setting up on those lights, to ensure they don't do anything more than they need to and minimize their impact.

Link to comment
Share on other sites

1 hour ago, MirceaKitsune said:

Thanks again for your suggestion @JackFarmer that areaLock spawnarg was a godsend! Tried it out and it fixes my setup much better than I expected. All wall leaks are gone and I get just the desired soft lighting! This is amazing :)

 

 

Good!

Can't wait to see your next mission releases, looks very cool.

  • Like 1
Link to comment
Share on other sites

Cheers. For now here are a few comparison images, taken with hide_distance set low for testing purposes (now 4x bigger so you'll barely ever notice the toggle): You can see the difference from almost the exact same angle, with as well as without the bounce (look at them in fullscreen to properly compare).

F5nIVoi.jpg

vU4ldJC.jpg

GP57XuO.jpg

mSJxWKl.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • Petike the Taffer  »  DeTeEff

      I've updated the articles for your FMs and your author category at the wiki. Your newer nickname (DeTeEff) now comes first, and the one in parentheses is your older nickname (Fieldmedic). Just to avoid confusing people who played your FMs years ago and remember your older nickname. I've added a wiki article for your latest FM, Who Watches the Watcher?, as part of my current updating efforts. Unless I overlooked something, you have five different FMs so far.
      · 0 replies
    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
×
×
  • Create New...