【问题标题】:How do I adjust the my GLSL code to add additional light sources?如何调整我的 GLSL 代码以添加额外的光源?
【发布时间】:2020-09-14 23:02:20
【问题描述】:

在下面的代码中,我试图为 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 中你可以使用数组和循环。将数据存储在Shader Storage Buffer Object
  • 但这对我有什么帮助?我不确定我是否跟随。如果我要添加更多的光源,我是不是只需要添加更多的光照变量,比如 light_position_world?
  • 是的,但是使用结构数组。 ssbo 可以更轻松地更新变量
  • 你能举个例子说明如何实现吗?

标签: opengl glsl shader fragment-shader light


【解决方案1】:

在 glsl 中,您可以使用数组和结构。定义一个光源数组。见Array constructorsStruct 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-28
    • 1970-01-01
    • 2017-07-06
    相关资源
    最近更新 更多