如何创建二维聚光灯?

How to create a 2D spotlight?

是否可以修改我当前的向各个方向辐射光的照明算法,例如:

这是我在片段着色器中计算光线的方法:

uniform struct Light
{
    vec4 colour;
    vec3 position;
    vec2 radius;
    float intensity;
} allLights[MAX_LIGHTS];

vec4 calculateLight(Light light)
{
    float aspectRatio = resolution.x / resolution.y; //amt of width / height
    if (aspectRatio > 1.0)
        light.radius.x /= aspectRatio;
    else
        light.radius.x /= aspectRatio;

    vec2 lightDir = fragmentPosition.xy - light.position.xy;
    float lightDistance = length(lightDir);
    if (length(lightDir / light.radius) >= 1.0)
        return vec4(0, 0, 0, 1); //outside of radius make it black

    return light.intensity * (1 - length(lightDir / light.radius)) * light.colour;
}

一个解决方案是为 spotDir、spotAngle(以弧度为单位)传入一个统一变量,并将着色器修改为:

vec4 calculateLight(Light light)
{
    float aspectRatio = resolution.x / resolution.y; //amt of width / height
    if (aspectRatio > 1.0)
        light.radius.x /= aspectRatio;
    else
        light.radius.x /= aspectRatio;

    vec2 lightDir = fragmentPosition.xy - light.position.xy;
    float lightDistance = length(lightDir);
    if (length(lightDir / light.radius) >= 1.0)
            return vec4(0, 0, 0, 1); //outside of radius make it black

    if (dot(normalize(lightDir), normalize(light.spotDir.xy)) < cos(light.spotAngle/2))
        return vec4(0, 0, 0, 1); //outside of radius make it black

    return light.intensity * (1 - length(lightDir / light.radius)) * light.colour;
}