好吧,我又迷失在大量教程中,这些教程似乎将旧的 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);
用于 phong 照明
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;
}
我是一名优秀的程序员,十分优秀!