我如何调整我的GLSL代码以增加额外的光源?[英] How do I adjust the my GLSL code to add additional light sources?

本文是小编为大家收集整理的关于我如何调整我的GLSL代码以增加额外的光源?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在下面的代码中,我正在尝试为 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 中你可以使用数组和结构.定义一个光源数组.请参阅 数组构造函数结构构造函数:

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 反射模型):

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);
}

本文地址:https://www.itbaoku.cn/post/2091096.html

问题描述

In the code below I am trying to implement a fragment shader program for 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);

}

I have two questions:

  1. How do I add 2 additional directional light sources to my code? Do I simply add more vec3 Ld variables to my light setup or is there something else I must do?
  2. How do I set the Phong exponent high enough to produce sharp and bright highlights?

推荐答案

In glsl you can use arrays and structures. Define an array of light sources. See 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)
);

User a for loop to iterate through the light sources and sum up the light color for ambient, diffuse and specular light (e.g 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);
}