2-5投光物

59 阅读1分钟

将光投射到物体的光源叫做投光物,其中分为平行光,点光源和聚光

平行光:光源处于无限远处,即为定向光(太阳),当然也不需要位置

struct Light 
{
vec3 direction;//需要取反
vec3 ambient;
vec3 diffuse;
vec3 specular; 
};

点光源:处于世界中某一位置,向所有位置发光,光线随着距离而衰减

struct Light 
{
vec3 position; 
vec3 ambient;
vec3 diffuse; 
vec3 specular;
float constant;//常数项
float linear; //一次项
float quadratic; //二次项
};

衰减公式:

float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));

最后再将环境,漫反射,镜面反射分别乘以attenuation即可

聚光:处于特定位置,向特定方向照射光线,只有在特定半径内的物体会被照亮

struct Light 
{ 
vec3 position; 
vec3 direction;
float cutOff; //切光角
};

接下来计算物体是否在光内

float theta = dot(lightDir, normalize(-light.direction));
if(theta > light.cutOff)
{
// 执行光照计算 
}

当我们模拟时,这样计算周围会出现一圈硬边,为了使边缘平滑,我们只需要再定义一个余弦值来代表聚光方向向量和外圆锥向量的夹角。然后,如果一个片段处于内外圆锥之间,将会给它计算出一个0.0到1.0之间的强度值

float theta = dot(lightDir, normalize(-light.direction)); 
float epsilon = light.cutOff - light.outerCutOff;
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
diffuse *= intensity; 
specular *= intensity;