📜 ⬆️ ⬇️

Unity3D: how to know the degree of illumination of the point of the scene?

Greetings

I know, and you know deep down, what your card games or “three in a row” games are missing. Stealth systems!

And of course, any self-respecting stealth system must be able to take into account the ambient light around the player. I was amazed to dig up the topic and find an abnormally small amount of information. Therefore, I hasten to share the fruits.
')
Today we will not develop a full-fledged system of secrecy for the player, consider purely interaction with lighting.

Method 1: colliders


Simple and not very resource-intensive way.

To each light source we add a spherical collider. Making it a trigger. We set the dimensions approximately equal to the radius of light.

The rest is clear as a shadow. We write a simple script, where in OnTriggerEnter () we place the activation of the calculation of illumination (so that the light sources do not work "idle" when there is no player nearby).

The light calculation itself will be located in Update (). In fact, this is the usual Physics.Raycast (). If it hits the player, the player is in the light zone. If it doesn't, then the player is behind the obstacles and, therefore, in the shadows.

Also here you can add the calculation of the distance between the player and the light source. Thus, to determine the illumination we will have a simple float, which will vary depending on the distance to the light sources. And you can use it where your heart desires.

Example

At point 1, the illumination is close to the maximum. At point 2, the illumination is minimal - between the light and the point of the obstacle. At point 3, the illumination is average.

And that's not it! You can add trigger colliders to various “shadow zones” where the player must hide. In the best traditions of Manhunt. Similarly, you can mark bright zones with a collider, simulating, for example, a spotlight.

Benefits:



Disadvantages:



Method 2: RenderTexture


What are we doing here? In fact, we get a “screenshot” from the camera, and not necessarily from the main camera. And then analyze the color of the screenshot to find out how bright the light falls on the subject.

First we need an object from which we will “read” the light. Create a normal sphere or plane, make a small one (scale 0.1), place it close to the floor, make it white, remove the collider:

Hidden text


Add a camera (be sure to remove the audio listener and check that the MainCamera tag is not worth it). Bind it to our object. We put it a little higher, we direct it down. We set in the settings not the main display. Whether to make it orthographic is to your taste.

At the end we position it so that it looks at our object and only at it.

Hidden text


At the end, we set up the Culling mask of the main and secondary cameras so that the main one does not display our “light” objects, and the secondary ones only see them without being littered with anything else.

And here the most interesting begins. We tie a script to the camera:

public Camera cam; //   RenderTexture tex; Texture2D _tex; void Start () { //    "". // ,       -   . // Depth   0   -   . tex = new RenderTexture (1, 1, 8); // RenderTexture "" , //   ,    . _tex = new Texture2D (1, 1, TextureFormat.RGB24, false); } void Update () { //   ""  cam.targetTexture = tex; cam.Render (); //     RenderTexture.active = tex; //   Texture2D _tex.ReadPixels (new Rect (0, 0, 1, 1), 0, 0); _tex.Apply (); Color col = _tex.GetPixel (0, 0); float vis = (col.r + col.g + col.b) / 3; } 

At the output, we obtain a float vis, which, in essence, is a numerical representation of the level of illumination falling on our object. If the source is close - the object is white - vis is 1. If it is dark - the object is black - vis is ~ 0.

We do not need to perform the above operation every frame, so we embed a small second timer:

 float interval = 0; void Update () { interval += Time.deltaTime; if (interval < 1) return; interval = 0; //   } 

Next, we tie our entire system to the player so that it moves with it. And our vis variable automatically provides the illumination around the player!

This system can be used not only in conjunction with the player. You can place it anywhere and in any way, creating a kind of light sensors. As a rule, there are more effective ways to implement them, but is it always nice to have alternatives?

The advantages are obvious, let's talk about the disadvantages.

disadvantages


Source: https://habr.com/ru/post/417135/


All Articles