So I have a fully functional system, already pretty polished with a good number of people testing and whatnot, and I’m in the phase of just adding a few things players have really been requesting.
This system is a 3D virtual tabletop. Has the works you’d expect, from map making to hosting sessions. Each player can place avatars that are automatically assigned to that player. An avatar has a certain degree of dark vision based on their stats/race/whatever. Only the owning player of that avatar can see the avatar’s vision, represented by a rectangle light they can toggle.
I chose the rectangle light because I can easily scale it to match the tile grid. Size 2 means 2 tiles out for example, which is 10 in-game feet. This works fine.
The issue is that there is distinct bleeding of light. I have indirect light set to zero. My guess is that the rect light, given the size, is just going right through objects and continuing to cast light within it’s bounds. I mean, makes sense. But I can’t figure out how to stop it upon reaching solid objects, or work around 'em. I don’t even know if this is possible. I considered making a collision box that scaled to the setting for the light, then using overlap hit points to redraw the rect light, but I doubt this is even possible and I’d probably need to rewrite the whole rect light as a new object via code for it to be an option. I’m okay with code, about 50% of my system is just c++, but the lighting stuff I’m shabby with.
I’ve asked every place I could think of, various dev friends, nobody has an answer.
If you’re using Lumen, the answer is no you can’t do that (at least not without disabling screen traces)
If you are using dynamic lighting without Lumen then its pretty trivial… just keep extending the barn door length all the way down:
I would note, disabling screen traces only works so long as you also have indirect lighting intensity set to 0, and you will need to do that for all (or most) lights which means you may as well just disable Lumen.
This isn’t really a good way to achieve this effect though… you should be looking at a fog-of-war style effect handled in either materials or a post process…
I do have lumen turned off and indirect lighting set to zero, with the barn doors extended all the way down and well past the avatar feet. But for some reason I’m still getting this odd effect. I have also ensured that it’s happening with totally solid objects that are fully connected, with no gaps between them.
I’ve considered fog of war but I haven’t yet figured out a good way to go about it with this system. Since the camera isn’t set to a certain angle and the player can zoom in and out and also see from the vantage of the avatars. Any suggestions?
I tried this as well, but it still has the issue that it just goes right through any walls so long as they’re within range of the light bounds. I like the shape that the rectangle light gives, but my issue is that I need it to abruptly stop when it hits walls. Any ideas on that issue?
Not sure why that would matter? Just write the visibility to a 2D render target and color everything outside the visible area to black. Doesn’t matter what angle or distance the camera is at.
Well, honestly the only info I’ve been able to find on fow is either relying on overhead angles for RTS type games, or using actual particle effect fog (which is way too intensive for this system, since it’s designed to be very light-weight).
BUT. Could you expand a bit on using a 2d render target? I’ve really only used them for stuff like character creation screens, but I’m down to try anything!
The objects themselves attach together at points and most of them are basic voxel shapes, and fairly simple. I had initially thought the base walls are too thin, but when I use it with the blocks themselves, it still seems to go right through them. I assumed the rectangle light was basically bypassing getting blocked because of the size expanding behind the objects in the way. Is that not the case though?
It’s just a texture that you can write to, your world is a grid of tiles right? Meaning if you can map the world coordinates to a texture you could represent each tile with a texel in the texture, every time the visibility needs to be updated you write to the texture.
For example if you had a 32x32 world, with a character that could see 1 tile away + 1 tile at half brightness, your texture might look like this:
Where the white pixels represent the fully visible tiles, gray pixels represent the partially visible tiles, and the black pixels represent the tiles that aren’t visible.
When you go to do your pixel shading (or post processing) you would use the XY world position of the pixel to sample your render target and then just multiply the albedo/emissive/whatever by the sampled color.
This isn’t really a beginner topic, but Chris Murphy made a tutorial a long time that did almost exactly what I just described, except he used it for a laser instead of visibility: https://www.youtube.com/watch?v=67z5u8ZcEcw
OH! I see, okay! I’ve used this sort of masking in post processing before, I think I just didn’t get what you meant at first. That’s actually a clever idea. Hm… Okay, this helps a lot! Thank you so much!
Hey quick question! I put together a post processing material and that does work really well for what I want to do, but do you know if there’s a way for certain actor lights to ignore it? For example, if I have a lamp post in the scene, can I set the light for the lamp post to still show? I thought maybe custom depth pass, but that doesn’t appear to be an option for lights.
If you have a lamp that has an emissive mesh, you can write that to custom depth, but for lightsources… probably not.
If you use a higher resolution render target you could write the lights location to the render target as well so that only a small area around the lamp will be lit up, but the quality of the falloff will be determined by the resolution of the RT which isnt ideal.
Right, that makes sense. I was playing around with it a bit and trying to add/remove from the post processing mask using the stencil value of the lamppost, but that only really allows the mesh itself to show. The objects cast their own light and are integral to the map designing… hrm.
I really don’t want to have to drop the post processing method because it DOES take care of the issue with seeing through walls and behind objects. Ugh.