Opengl 聚光灯的着色器

Opengl 聚光灯的着色器,opengl,glsl,Opengl,Glsl,如何使该着色器在聚光灯上具有平滑边而不是硬边?此外,着色器必须处理可变值GL_SPOT_CUTOFF。请注意,并非所有灯光都是聚光灯——GL_LIGHT0是点光源 varying vec3 N; varying vec3 v; #define MAX_LIGHTS 2 void main (void) { vec4 finalColour; float spotEffect; for (int i=0; i<MAX_LIGHTS; i++) {

如何使该着色器在聚光灯上具有平滑边而不是硬边?此外,着色器必须处理可变值GL_SPOT_CUTOFF。请注意,并非所有灯光都是聚光灯——GL_LIGHT0是点光源

varying vec3 N;
varying vec3 v;
#define MAX_LIGHTS 2 
void main (void)  
{  
    vec4 finalColour;
    float spotEffect;

    for (int i=0; i<MAX_LIGHTS; i++)
    {
        vec3 L = normalize(gl_LightSource[i].position.xyz - v);   
        vec3 E = normalize(-v);
        vec3 R = normalize(-reflect(L,N));

        spotEffect = dot(normalize(gl_LightSource[i].spotDirection), 
                         normalize(-L));
        if (spotEffect > gl_LightSource[i].spotCosCutoff) {
            vec4 Iamb = gl_FrontLightProduct[i].ambient;    
            vec4 Idiff = gl_FrontLightProduct[i].diffuse * max(dot(N,L), 0.0);
            Idiff = clamp(Idiff, 0.0, 1.0);     
            vec4 Ispec = gl_FrontLightProduct[i].specular 
                         * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess);
            Ispec = clamp(Ispec, 0.0, 1.0);
            finalColour += Iamb + Idiff + Ispec;
        }
    }
    gl_FragColor = gl_FrontLightModelProduct.sceneColor + finalColour;
可变向量3n;
可变电压3伏;
#定义最大灯光2
真空总管(真空)
{  
vec4最终颜色;
浮子效应;
对于(int i=0;i gl_光源[i]。SpotcosCupton){
vec4 Iamb=gl_FrontLightProduct[i]。环境光;
vec4 Idiff=gl_FrontLightProduct[i]。漫反射*max(点(N,L),0.0);
Idiff=夹具(Idiff,0.0,1.0);
vec4 Ispec=gl_FrontLightProduct[i]。镜面反射
*功率(最大值(点(R,E),0.0),0.3*gl_正面材料光泽度);
Ispec=夹具(Ispec,0.0,1.0);
最终颜色+=Iamb+Idiff+Ispec;
}
}
gl_FragColor=gl_FrontLightModelProduct.sceneColor+FinalColor;
}

场景如下所示:

此着色器从生成指向您所追求的聚光灯的软边

[Pixel_Shader]

varying vec3 normal, lightDir, eyeVec;

const float cos_outer_cone_angle = 0.8; // 36 degrees

void main (void)
{
    vec4 final_color =
    (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
    (gl_LightSource[0].ambient * gl_FrontMaterial.ambient);

    vec3 L = normalize(lightDir);
    vec3 D = normalize(gl_LightSource[0].spotDirection);

    float cos_cur_angle = dot(-L, D);

    float cos_inner_cone_angle = gl_LightSource[0].spotCosCutoff;

    float cos_inner_minus_outer_angle = 
          cos_inner_cone_angle - cos_outer_cone_angle;

    //****************************************************
    // Don't need dynamic branching at all, precompute 
    // falloff(i will call it spot)
    float spot = 0.0;
    spot = clamp((cos_cur_angle - cos_outer_cone_angle) / 
           cos_inner_minus_outer_angle, 0.0, 1.0);
    //****************************************************

    vec3 N = normalize(normal);

    float lambertTerm = max( dot(N,L), 0.0);
    if(lambertTerm > 0.0)
    {
        final_color += gl_LightSource[0].diffuse *
            gl_FrontMaterial.diffuse *
            lambertTerm * spot;

        vec3 E = normalize(eyeVec);
        vec3 R = reflect(-L, N);

        float specular = pow( max(dot(R, E), 0.0),
            gl_FrontMaterial.shininess );

        final_color += gl_LightSource[0].specular *
            gl_FrontMaterial.specular *
            specular * spot;
    }
    gl_FragColor = final_color;
此着色器从生成指向您要跟踪的聚光灯的软边

[Pixel_Shader]

varying vec3 normal, lightDir, eyeVec;

const float cos_outer_cone_angle = 0.8; // 36 degrees

void main (void)
{
    vec4 final_color =
    (gl_FrontLightModelProduct.sceneColor * gl_FrontMaterial.ambient) +
    (gl_LightSource[0].ambient * gl_FrontMaterial.ambient);

    vec3 L = normalize(lightDir);
    vec3 D = normalize(gl_LightSource[0].spotDirection);

    float cos_cur_angle = dot(-L, D);

    float cos_inner_cone_angle = gl_LightSource[0].spotCosCutoff;

    float cos_inner_minus_outer_angle = 
          cos_inner_cone_angle - cos_outer_cone_angle;

    //****************************************************
    // Don't need dynamic branching at all, precompute 
    // falloff(i will call it spot)
    float spot = 0.0;
    spot = clamp((cos_cur_angle - cos_outer_cone_angle) / 
           cos_inner_minus_outer_angle, 0.0, 1.0);
    //****************************************************

    vec3 N = normalize(normal);

    float lambertTerm = max( dot(N,L), 0.0);
    if(lambertTerm > 0.0)
    {
        final_color += gl_LightSource[0].diffuse *
            gl_FrontMaterial.diffuse *
            lambertTerm * spot;

        vec3 E = normalize(eyeVec);
        vec3 R = reflect(-L, N);

        float specular = pow( max(dot(R, E), 0.0),
            gl_FrontMaterial.shininess );

        final_color += gl_LightSource[0].specular *
            gl_FrontMaterial.specular *
            specular * spot;
    }
    gl_FragColor = final_color;

你说的是衰减,光的强度随着离中心越远而降低吗?如果是这样的话,那么这看起来像是一个很好的教程:你是在谈论衰减,即光线的强度随着离中心越远而降低吗?如果是这样的话,那么这看起来是一个非常好的教程:遗憾的是,这不适用于变量GL_SPOT_CUTOFF变量。问题更新了。我不太清楚你的意思。通过上面的着色器,可以设置外锥角(即聚光灯的边缘)和内锥角(即聚光灯的完全照明部分的边缘),该内锥角源自gl_光源[0]。SpotCosCupton。这意味着着色器会处理GL_SPOT_截断值尝试过的所有内容,并且仅适用于较小的GL_SPOT_截断。如果该角度太大(>60),则着色器反转:只有外部被照亮。遗憾的是,这无法处理变量GL_SPOT_CUTOFF变量。问题更新了。我不太清楚你的意思。通过上面的着色器,可以设置外锥角(即聚光灯的边缘)和内锥角(即聚光灯的完全照明部分的边缘),该内锥角源自gl_光源[0]。SpotCosCupton。这意味着着色器会处理GL_SPOT_截断值尝试过的所有内容,并且仅适用于较小的GL_SPOT_截断。如果该角度太大(>60),则着色器反转:仅外部被照亮。