glLightfv GL_POSITION GL_LINEAR_ATTENUATION glsl OpenGL3或Ope

glLightfv GL_POSITION GL_LINEAR_ATTENUATION glsl OpenGL3 or OpenGL4 (positional light)

本文关键字:GL OpenGL3 Ope glsl LINEAR POSITION glLightfv ATTENUATION      更新时间:2023-10-16

好吧,我又迷失在大量的教程中,这些教程似乎把旧的GL版本与GL3和4混淆了。大多数教程都使用废弃的代码,我正在寻找一个合适的OpenGL3,或者甚至更好的OpenGL4替代这个伪代码:

GLfloat LightRadius=0.5f; //or whatever value.
glLightf(NumLights, GL_LINEAR_ATTENUATION, LightRadius);
GLfloat light_position[] = { LightLoc.X,LightLoc.Y, LightLoc.Z, 1 }; //World space location
glLightfv(NumLights, GL_POSITION, light_position);

for phong lighting

vs可以像这样:

#version 330
layout (location = 0) in vec3 Position;
layout (location = 1) in vec3 PositionNormals;
uniform mat4 projMat;
uniform mat4 viewMat;
uniform mat4 modelMat;
out vec3 vposition;
out vec3 vnormal;
out mat4 vprojMat;
out mat4 vviewMat;
out mat4 vmodelMat;
void main(void)
{
    vprojMat    = projMat; // from what I understood I need those in the fs as well..?
    vviewMat    = viewMat;
    vmodelMat   = modelMat;
    vposition   = vec3(viewMat * modelMat * vec4 (Position, 1.0));
    vnormal     = vec3(viewMat * modelMat * vec4 (PositionNormals, 0.0));
    gl_Position     = projMat * vec4(vposition_eye, 1.0);
}

和fs:

in vec3 vposition;
in vec3 vnormal;
in mat4 vprojMat;
in mat4 vviewMat;
in mat4 vmodelMat;
struct LightInfo                                                           
{  
    vec3 LightLocation;                                                                   
    vec3 DiffuseLightColor;
    vec3 AmbientLightColor;
    vec3 SpecularLightColor;
    float AmbientLightIntensity;
    float SpecularLightIntensity;
    float LightRadius;
};
uniform LightInfo gLight;                                         
out vec4 FragColor; 
void main (void)  
{  
    //Diffuse Lighting
    // and here I am lost. Was trying to do in eyespace, but the light seems to float more somewhere instead of having a fixed position.
    vec3 light_position = ??? gLight.LightLocation; // probably normalized?
    float dot_prod = ??? 
    dot_prod = max (dot_prod, 0.0);
    vec3 diffuse_intensity = gLight.DiffuseLightColor * dot_prod; // final diffuse intensity

    FragColor=diffuse_intensity;
}

这个想法很简单,只是房间里的一盏灯照向各个方向(像太阳一样),根据任意半径有一个给定的衰减。我就是搞不懂它背后的数学原理。如果这是一个愚蠢的问题,请原谅我,但我读得越多,我就越困惑。我知道我需要计算漫射光的点,表面的朝向(法线)和从表面到光的方向,但是我不能把它们放在一起。

你应该有所有的顶点和光数据在同一个坐标系。如果你在世界坐标中发送光的位置,你也应该与世界空间中的法线做点积。在性能方面,最好将光线发送到眼睛/相机空间。要实现这一点,你应该像这样调用glLightfv:

// The 4th component of the light position should be 1, because it's a position, not a direction
GLfloat light_position[] = { LightLoc.X,LightLoc.Y, LightLoc.Z, 1 }; //World space location
// TODO: Change to eye space multiplying by the inverse of the modelView matrix
Matrix4 invModelView;
inverseOrtho(viewMatrix * modelMatrix, invModelView);
transformVector4(light_position, invModelView);
glLightfv(NumLights, GL_POSITION, light_position);    // Send light in eye space

如果你在眼空间中有灯光,像素着色器比在世界空间中计算所有灯光更简单。

void main (void)  
{  
    //Diffuse Lighting
    vec3 light_position = gLight.LightLocation;    // Light position in eye space
    // calculate the light direction from the light to the vertex being iluminated
    float dot_prod = dot((vposition - light_position).normalize(), vnormal);
    dot_prod = max (dot_prod, 0.0);
    vec3 diffuse_intensity = gLight.DiffuseLightColor * dot_prod; // final diffuse intensity
    FragColor=diffuse_intensity;
}