I want to see how well-lit the player character is in an environment so that my AI can react (or not) to the player when he or she is visible.

Currently I am doing this by reading back the color data of the final render target and computing the brightness of the player's region. It seems expensive and taxing, so I was wondering if there is a better way to approach this?

  • \$\begingroup\$ have you tried rendering to a texture? maybe with a custom shader? \$\endgroup\$ – Ali1S232 Jul 20 '13 at 20:49
  • \$\begingroup\$ I already render to a texture, I need to be able to send color data from the shader back to c# \$\endgroup\$ – okkk Jul 20 '13 at 21:13
  • 3
    \$\begingroup\$ You're never going to be able to do that both efficiently and in a timely manner, since any kind of readback from the GPU requires a synchronization. \$\endgroup\$ – Maximus Minimus Jul 20 '13 at 21:56
  • \$\begingroup\$ Why even do you want ot read back the brightness? Maybe you simply don't explain what you want to to. \$\endgroup\$ – 0xBADF00D Jul 29 '13 at 12:05
  • \$\begingroup\$ I want to use calculate the brightness of the character in order to set whether or not the AI of the game can "see" the character. \$\endgroup\$ – okkk Jul 30 '13 at 1:07

It can seem attractive to handle this kind of problem by reading back the brightness data -- after all, you're already rendering that information and so it will already be there, available, and up-to-date.

Unfortunately, it's probably not the best way to do it. Reading back data from the GPU isn't particularly fast or well-suited to this kind of operation. You are better off solving the visibility problem entirely on the CPU and basing it entirely off game data instead of graphics data.

You already know where all your lights are in the game world, and where the player is (since you're currently rendering them). A much more efficient approach to determining if the player is visible is to:

  • Collect all the lights within a reasonable distance to the player (everything close enough to possibly illuminate the player). You can optimize this with some form of spatial partitioning of your game data, but if you have few enough lights per level you can also just brute-force it.
  • For every light, apply the light's attenuated value to the player's total "lit" value.
  • If the total "lit" value of the player exceeds some threshold, the player is visible. Otherwise the player is hidden in the shadows.

Not only will this be much more straightforward and faster than doing a read-back, it will allow you to tie in line-of-sight visibility checks if you want, as well.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.