Web编程技术营地
研究、演示、创新

聚光

撰写时间:2026-07-25

修订时间:2026-07-26

概述

聚光 (spot light) 是从一个点射向特定目标的光源,并且光线被束缚在一个顶部位于光源位置的圆锥体的范围内。此外,聚光也存在衰减的情况。常见的聚光如手电筒、车灯、探照灯等所射出的光线。

在为其建模时,聚光除了具备点光uLightPos, uLightAttenuation, uLightColor, uLightIntensity等属性之外,还需要uSpotConeDir属性, 代表聚光所照向的方向,以及uInnerCutoff, uOuterCutoff的属性,分别代表内锥角外锥角的余弦值。其中,内锥角区域内的光线完全覆盖,而外锥角区域内的光线从中心向四周逐渐平滑地衰减0

在着色器中实现功能

顶点着色器的代码无需改变。

片断着色器中,先添加相应的uniform属性:

然后在calcDirectLightings函数中,在之前已经计算出衰减因子attenuation的基础上,先计算聚光射向表面的光线与聚光射向目标的光线之间的夹角(余弦值):

注意这里的向量方向,之前的光线方向均是从表面指向光源的向量,而与之不同的是,这里却要求从光源分别指向表面及目标的向量

代码vec3 SL = uSpotConeDir;暗示着该变量在客户端须已经过归一化处理,因此在片断着色器中无需再进行归一化。

接着,根据外锥角内锥角的值,将cosTheta钳制在此范围内。

然后,将spotFactorattenuation相乘,并将结果存储为finalAttenuation

最后,将finalAttenuation应用到directLightings上面,并返回后者的值。

相应完整代码

客户端:

聚光的修改完全集中于片断着色器calcDirectLightings函数中。

运行应用

一盏聚光灯从左上角照下来,场景中所有网络物体均或多或少地落在光照范围内。因聚光灯是斜照,因此被照亮部分显示为一个椭圆形。若修改代码,让聚光灯垂直照向地板,则被照亮部分显示为一个正圆。

参考资源

Specifications

  1. WebGL 1.0 Specification
  2. WebGL 2.0 Specification
  3. OpenGL ES 3.0 Reference Pages

JS Libraries

  1. glMatrix.net

Scientific Papers

  1. Sampling the GGX Distribution of Visible Normals
  2. HAL: Open Science