Is there any way to detect if a pawn is being lit?

Hi.

I got an idea to my project that would be easily implemented “IF” I could detect if a skeletal mesh is being lit (receiving direct light from sources on the map).

Another way I thought would be get some material node that does expose the light contribution (float?) on the actual shader result.

Does someone has any tip about where could I start?

Thank you.

You should be able to detect if the light volume intersects with the mesh. If it’s a sphere, detect if it’s within the radius. If it’s a spotlight, do some additional cone checks or build a rough cone shaped convex mesh. You can use UWorld overlap test functions. You’d still have to do some ray casts of some sort to see if it’s in shadow.

It’s most likely using deferred shading very heavily so the lighting is most likely strongly decoupled from the actual material itself, so it may be very hard to expose that in the shader unless you force the material to be forward shaded. Either way, trying to do that in shader wouldn’t work too well since it’ll really complicate everything. You’d have to use some kind of texture or query object to return the results from the GPU back to the CPU, and either allow the results to come back in later frames or incur a huge performance drop by blocking until the results come back.

Short of using a compute shader to read the lighting buffer at a specific point on screen, there isn’t really a perfect way to go about it, for dynamic lighting anyway.

Thanks by the ideas guys, well, let me share some thoughts…

Unless U4 don’t uses HLSL, the light intensity, color and position from all materials are being considered on some stage from pixel shader outputs, so a MAX( , ) or a <= would not be this way heavy to proccess.

I bet these “variables” are protected in some way being either pre-added or post-fixed each time we choose the Material Domains, Blending Modes or Shading Models.

I don’t know if they changed this, but on the old UDK docs Epic explained light environment on pawns with some “planes” floating in the air and Marcus from GoW intersecting with them, and by what I got these “planes” adds or removes light intensity from final results.

I’m just asking to avoid dissecting the entire render code, should be amazing get a simplest “read there!”. LOL

From the top of my head, a very low tech solution could be this, based on the same principles that illYay brought up:

  1. Most light sources have a distance attribute.
    1.1 Do a distance squared check to all sources to see which light could potentially hit the skeletal mesh. (if the skeletal mesh is outside the radius, ignore that light source)
    1.2 … or use overlap volumes that mimic the light radius and check if the actor overlaps with it.

  2. Using the potential sources. Do a line trace from the center of the light source to each joint on the skeletal mesh. If no collision happened, the light source reached the mesh. Collision would mean the bone is in “shadow”.
    2.1 For parallel lights, trace backwards from each bone towards the parallel direction for a fixed length (to the sky). No collision means clear path to the “sun” or whatever source you have.

Doing a solution like this would not give you “full precision”, so if the edge of a mesh is lit and there is no bone there, you can’t detect if it’s lit. I guess that it is still good enough for a low resolution test. You can of course go crazy with this solution and trace against every vertex, or filter out those that face the light source.

Another solution could be to use 4-6 render targets, one for each side of the mesh. (low res, maybe 16x16 or 32x32) Set the target to only capture skeletal meshes with a reasonable max view distance. Then use the render targets to see if there is enough color information to see if the mesh is being “lit”.

So many ways to solve this. :smiley:

Thanks again guys.

All these ideas with volumes made me thought about an “in the dark volume” that is the way I thought Eidos’ Thief works.

It’s not “exactly” what I’m looking for (the engine should already have this information somewhere), but instead of try to “runtime process” each volume/light per frame after do the light build I could study the level and watch the areas where the character should render black placing these volumes there, my only trouble should be for dynamic movable lights, to this, I’ll need to combine per volume light technique you’ve described above.

I think I have enough to start, thank you by your advice. :smiley:

Many ways exist such as.

  • Querying Light Source Raycast
  • Checking the poing on the screen getting a snapshot and comparing pixel value
  • Getting a snapshot from rendertarget and comparing brightest pixel (in link)