如何调整我的 GLSL 代码以添加额外的光源?

How do I adjust the my GLSL code to add additional light sources?

在下面的代码中,我试图为 Phong 实现片段着色器程序:

// Inputs from application.
// Generally, "in" like the position and normal vectors for things that change frequently,
// and "uniform" for things that change less often (think scene versus vertices).  

in vec3 position_cam, normal_cam;
uniform mat4 view_mat;

// This light setup would usually be passed in from the application.

vec3 light_position_world  = vec3 (10.0, 25.0, 10.0);
vec3 Ls = vec3 (1.0, 1.0, 1.0);    // neutral, full specular color of light
vec3 Ld = vec3 (0.8, 0.8, 0.8);    // neutral, lessened diffuse light color of light
vec3 La = vec3 (0.12, 0.12, 0.12); // ambient color of light - just a bit more than dk gray    bg

// Surface reflectance properties for Phong model below.

vec3 Ks = vec3 (1.0, 1.0, 1.0);    // fully reflect specular light
vec3 Kd = vec3 (0.32, 0.18, 0.5);  // purple diffuse surface reflectance
vec3 Ka = vec3 (1.0, 1.0, 1.0);    // fully reflect ambient light

float specular_exponent = 400.0;   // specular 'power' -- controls "roll-off"

// Shader programs can also designate outputs.
out vec4 fragment_color;           // color of surface to draw in this case

void main () 
{

    fragment_color = vec4 (Kd, 1.0);

}

我有两个问题:

  1. 如何在我的代码中添加 2 个额外的定向光源?我是简单地在我的灯光设置中添加更多 vec3 Ld 变量,还是我必须做其他事情?
  2. 如何将 Phong 指数设置得足够高以产生清晰明亮的高光?

在 glsl 中,您可以使用数组和结构。定义光源阵列。见 Array constructors and Struct constructors:

const int no_of_lights = 2;

struct TLightSource
{
   vec3 lightPos;
   vec3 Ls; 
   vec3 Ld;
   vec3 La;
   float shininess;
};

TLightSource lightSources[no_of_lights] = TLightSource[no_of_lights](
    TLightSource(vec3(10.0, 25.0, 10.0), vec3(1.0, 1.0, 1.0), vec3(0.8, 0.8, 0.8), vec3(0.12, 0.12, 0.12), 10.0),
    TLightSource(vec3(-10.0, 25.0, 10.0), vec3(1.0, 0.0, 0.0), vec3(0.8, 0.0, 0.0), vec3(0.12, 0.0, 0.0), 10.0)
);

使用 for 循环遍历光源并总结环境光、漫射光和镜面光的光色(例如 Phong reflection model):

void main()
{
    vec3 normalInterp;
    vec3 vertPos;

    vec3 normal = normalize(normalInterp);
    
    vec3 color = vec3(0.0);
    for (int i=0; i < no_of_lights; i++)
    {
        color += Ka * lightSources[i].La;

        vec3 lightDir = normalize(lightSources[i].lightPos - vertPos);
        float lambertian = max(dot(lightDir, normal), 0.0); 
        color += lambertian * lightSources[i].Ld;

        if (lambertian > 0.0) 
        {   
            vec3 viewDir = normalize(-vertPos);
            vec3 reflectDir = reflect(-lightDir, normal);
            float RdotV = max(dot(reflectDir, viewDir), 0.0); 
            float specular = pow(RdotV, lightSources[i].shininess/4.0);
            color += specular * lightSources[i].Ls;
        }
    }

    frag_color = vec4(color, 1.0);
}