opengl 如何在照明的边缘添加渐变?

rqqzpn5f  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(148)

我目前正在使用一个简单的2D光照算法来创建一个2D聚光灯。下面是一个它目前的样子的例子:

然而,我想在边缘(顶部和底部)添加一个渐变,这样它看起来就像这样:

我目前的照明算法:

vec4 calculateLight(Light light)
{

    vec2 fragDirection = fragmentPosition.xy - light.position.xy;
    float aspectRatio = resolution.x / resolution.y; //amt of width / height
    if (aspectRatio > 1.0)
    {
        fragDirection.x *= aspectRatio;
    }
    else
    {
        fragDirection.x /= aspectRatio;
    }

    float lightDistance = length(fragDirection);
    if (length(fragDirection / light.radius) >= 1.0)
            return vec4(0, 0, 0, 1); //outside of radius make it black

    if (dot(normalize(fragDirection), 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(fragDirection / light.radius)) * light.colour;
}
5hcedyr0

5hcedyr01#

请尝试以下操作作为起点:

顶点:


# version 400 core

in vec2 position;
out vec2 pos;

void main(void)
    {
    pos=position;
    gl_Position = vec4(position.xy,0.0,1.0);
    }

片段:


# version 400 core

in vec2 pos;
out vec3 out_Color;

// light
const float deg=0.01745329251994329576923690768489;
uniform vec2 lpos=vec2(-0.5,0.0); // positon
uniform vec2 ldir=vec2(+1.0,0.0); // directon (unit vector)
uniform float lr1=1.0;            // soft radius
uniform float lr0=0.9;            // hard radius
uniform float la1=cos(25.0*deg);  // soft half angle
uniform float la0=cos(20.0*deg);  // hard half angle

void main(void)
    {
    float a,c,r;
    vec3 col;
    vec2 d;
    col=vec3(1.0,1.0,1.0);
    d=pos-lpos;
    r=length(d);
    d=normalize(d);
    c=0.0;
    // light side strength (angle)
    a=abs(max(0.0,dot(ldir,d)));
         if (a>=la0) c=1.0;                 // hard light
    else if (a>=la1) c=(a-la1)/(la0-la1);   // soft light
    else discard;                           // no light
    // light forward strength (radius)
         if (r<=lr0);                       // hard light
    else if (r<=lr1) c*=(r-lr1)/(lr0-lr1);  // soft light
    else discard;                           // no light
    out_Color = col*c;
    }

它使用线性衰减线在两侧(Angular )和向前(半径)只需改变光均匀到光结构你使用...

此处预览:

现在你可以玩不同类型的衰减,只要改变线性插值为二次,指数或任何...顺便说一句,我乘以光强度c从Angular 和半径在一起,你可能会改变为最小或最大,而不是实现不同的边缘连接
在稍微处理了一下常量和方程之后:

片段:


# version 400 core

in vec2 pos;
out vec3 out_Color;

// light
const float deg=0.01745329251994329576923690768489;
uniform vec2 lpos=vec2(-0.5,+0.0);// positon
uniform vec2 ldir=vec2(+0.7,-0.7);// directon (unit vector)
uniform float lr1=1.00;           // soft radius
uniform float lr0=0.25;           // hard radius
uniform float la1=cos(30.0*deg);  // soft half angle
uniform float la0=cos(15.0*deg);  // hard half angle

void main(void)
    {
    float a,r,c0,c1;
    vec3 col;
    vec2 d;
    col=vec3(1.0,1.0,1.0);
    d=pos-lpos;
    r=length(d);
    d=normalize(d);
    // light side strength (angle)
    a=abs(max(0.0,dot(ldir,d)));
         if (a>=la0) c0=1.0;                // hard light
    else if (a>=la1) c0=(a-la1)/(la0-la1);  // soft light
    else discard;                           // no light
    // light forward strength (radius)
         if (r<=lr0) c1=1.0;                // hard light
    else if (r<=lr1) c1=(r-lr1)/(lr0-lr1);  // soft light
    else discard;                           // no light
    a=c0*c1;
    out_Color = col*pow(a,2.5);
    }

相关问题