Tutorial: Cocos Creator: searchlight effects with shaders

Tutorial: Cocos Creator: searchlight effects with shaders

Introduction

The searchlight effect means that the entire scene or picture is black, and only the place illuminated by a light is bright. There are many ways to implement it but for this tutorial we use use a shader. The main reason to use a shader is to achieve higher efficiency, better effects, and increased scalability. Example:

Searchlight

Principles of Illumination

Developers know that the color in the program is determined by the three values of RGB. For example, the RGB value of red is (255, 0, 0), but the maximum value of the color in the GLSL language is 1.0, and it is usually represented by a vec4 data type. Red in GLSL is: vec4(1.0, 0.0, 0.0, 1.0);. The fourth parameter is the alpha value. In this example it is set to 1.

In reality, objects have all kinds of colors, not that they are the color themselves, but the color of the light it can reflect. Sunlight contains all colors of light. The color of light that an object can reflect is related to the particle characteristics of the object itself. This determines the wavelength range of light that it can reflect, while other ranges of light are absorbed. This results in see objects of various colors. Example:

Using this principle, we can use a shader to control the color display of the target to simulate lighting. For example, white light is set by using: vec4(1.0, 1.0, 1.0, 1.0). This vector is multiplied by the color in the fragment shader, because each value is 1, the color of the object does not change. When we set the red light to vec4 (1.0, 0.0, 0.0, 1.0), the object will be red.

We then control the range of light to be a circle, then it is called a searchlight effect.

Shader implementation

  • The following is the implementation process of a shader, not the complete code, only code snippets, developers who are familiar with the GLSL language should be able to understand, developers who do not understand can go to the end of the article to get the complete code and come back to learn.

  • The first is the light range logic, which judges whether it is within the light range based on the distance between the two points and the light center point. The points within the light range are the target color, and the points outside the range are set to black:

    Example when running:

  • A general lighting range effect is available, but it is not natural, there is no transition at the edge of the light, and there are jagged edges, let’s add the transition effect to the edge of the light through interpolation:

  • The smoothstep() function, in the above image, receives three parameters, the first is the minimum value of the range, the second is the maximum value of the range, and the third parameter is the target value x that needs to be calculated. If x is less than the minimum value, it returns 0, and if it is greater than the maximum value, it returns 1, and the rest return 0 to 1 interpolation. The range in the above code is the light radius and the radius plus 0.1 to perform interpolation to achieve the transition effect of the light edge. Look at it after the modification, the effect is already good. Example:

  • Finally, we can notice the movement of the light source by setting the light_center parameter through code:

Note:- if your scene or target picture is not a square, then the range of illumination may not be a perfect circle, but an ellipse. This is because the coordinate range in Open GL is from -1 to 1, but the width and height are not necessarily proportional. So when developers calculate the range of the circle, pass in the aspect ratio of the scene or picture, and then correct it when calculating the range of the circle:

Advanced Optimizations

Diffusing Ambient Light

  • Everyone knows that no matter how dark a room is, we can always vaguely see the outline of the object, which is caused by the diffusely reflected ambient light. The surface of the object is not smooth, but rather is uneven. It will always reflect the light of the light source in all directions. After receiving the reflected light, other objects will reflect again and repeat the cycle. This is diffuse reflection, which is also called ambient light. This is why we can see things in a room without a light source. The principle of diffuse reflection is as follows:

  • In our example, the place where the light does not shine is completely dark, and sometimes we also need some ambient light caused by diffuse reflection. The real diffuse reflection algorithm is very complicated. It needs to be calculated by the normal vector. Here we are just a 2D texture map, so we just set the ambient light to an average constant, and add the environment to the logic where the light is not illuminated. Optical logic:

    Can you see? The running effect is basically the same as the effect at the beginning of the tutorial.

Light intensity and light source color

  • In the previous process, we did not intervene in the target color within the illumination range, ensuring the inherent color of the target. However, sometimes we also need to change something. For example, the ambient light is mentioned above. The place with no light is not completely dark. Then, conversely, the place with light must be bright? Sometimes we also need to adjust the brightness and color of the light.

  • Look at the brightness of the light first. This is relatively simple. The logic is the same as the intensity of the ambient light. We then define a parameter of the light source intensity:

  • Multiply the lighting part and the transition part of the lighting edge involved in the interpolation operation by the light intensity to achieve our target effect. (However, one issue that needs to be noted here is what effect will the light intensity result be less than ambient_strength? You can try it out and try to modify it.)

  • Next, Add support for the color of the light source. According to the lighting principle mentioned at the beginning of the tutorial, developers can directly multiply the target color in our previous example by a light source color. For the light source color, developers should use the red light mentioned above:

Running result:

Conclusion

This tutorial was contributed by Ituuz. Thank you Ituuz!. Visit their personal blog to learn more and find more interesting tutorials.

You can download the complete code for this tutorial on GitHub.

4 Likes