GLSL/OpenGL 2.1:使用制服的镜面照明

GLSL/OpenGL 2.1:使用制服的镜面照明,opengl,glsl,shader,specular,Opengl,Glsl,Shader,Specular,因此,我开始寻求在不使用OpenGL的照明系统的情况下实现出色的照明。我已经成功地实现了Phong漫反射照明。镜面反射给我带来了麻烦 我需要知道我使用的OpenGL常量占用了哪些空间,因为它们似乎被错误地转换了,这会导致照明故障 我已经确认,通过成功加载和运行Phan-漫着色,我的C++代码没有问题。然而,C++代码可能会将无效数据传递给着色器,这是我担心的事情之一。我将用注释来粘贴着色器,以及直接与着色器相关的所有C++代码(虽然我确信90%是问题在着色器中)。 在这些图像中,光源是大的点,并

因此,我开始寻求在不使用OpenGL的照明系统的情况下实现出色的照明。我已经成功地实现了Phong漫反射照明。镜面反射给我带来了麻烦

我需要知道我使用的OpenGL常量占用了哪些空间,因为它们似乎被错误地转换了,这会导致照明故障

<>我已经确认,通过成功加载和运行Phan-漫着色,我的C++代码没有问题。然而,C++代码可能会将无效数据传递给着色器,这是我担心的事情之一。我将用注释来粘贴着色器,以及直接与着色器相关的所有C++代码(虽然我确信90%是问题在着色器中)。 在这些图像中,光源是大的点,并且显示了轴。 灯光以y=0的速度围绕图标球体旋转

这是漫反射,所以你知道模型是什么。。。 注意,我还没有完成每像素

这是菲涅耳照明,如来源所示。。。 请注意被照亮的面是如何面对灯光的,而不是灯光和相机之间的某个位置

这是Blinn Phong,我必须乘以30。。。 请再次注意,照亮的面如何指向光源,以及我必须将镜面反射因子乘以30才能实现这一点

顶点着色器源(从“dirlight.vs”加载)

从C++主初始化中摘录…

//class program manages shaders
Program shaders = Program();
//attach a vertex shader, compiled from source in dirlight.vs
shaders.addShaderFile(GL_VERTEX_SHADER, "dirlight.vs");
//attach a fragment shader compiled from source in dirlight.fs
shaders.addShaderFile(GL_FRAGMENT_SHADER, "dirlight.fs");
//link program
shaders.link();
//use program
shaders.use();

//Program::getUniformLoc(const char* name) grabs the location
//of the uniform specified
GLint sTime = shaders.getUniformLoc("time");
GLint lightcount = shaders.getUniformLoc("lightcount");
GLint lightdir = shaders.getUniformLoc("lightdirs");
GLint lightdif = shaders.getUniformLoc("lightdifs");
GLint lightamb = shaders.getUniformLoc("lightambs");
GLint lightpos = shaders.getUniformLoc("lightposs");
GLint justcolor = shaders.getUniformLoc("justcolor");

glUniform1i(justcolor, 0);
glUniform1i(lightcount, 2);
//diffuse light colors
GLfloat lightdifs[] = {1.f, 1.f, 1.f, 1.f,
                      1.f, 1.f, 1.f, 1.f};
glUniform4fv(lightdif, 2, lightdifs);
glUniform4f(lightamb, 0.4f, 0.4f, 0.4f, 1.f);

从C++主循环中摘录…< / P>

//My lights rotate around the origin, where I have placed an icosphere
GLfloat lightposs[] = {-4 * sinf(newTime), lighth, -4 * cosf(newTime), 0.0f,
                       -4 * sinf(newTime + M_PI), lighth, -4 * cosf(newTime + M_PI), 0.0f};
glUniform4fv(lightpos, 2, lightposs);

代码中缺少一些重要的东西。首先,您应该将顶点位置和法线变换为眼睛空间。那里的照明计算最简单。顶点位置变换使用模型视图矩阵,法线变换使用模型视图的转置逆。通常灯光位置在世界坐标中,因此提供一个从世界坐标到眼睛坐标的附加矩阵是有意义的。

代码中缺少一些重要的东西。首先,您应该将顶点位置和法线变换为眼睛空间。那里的照明计算最简单。顶点位置变换使用模型视图矩阵,法线变换使用模型视图的转置逆。通常灯光位置在世界坐标中,因此提供一个从世界坐标到眼睛坐标的附加矩阵是有意义的。

从技术上讲,您应该在片段着色器而不是顶点着色器中进行照明计算;这是片段着色器的关键用途之一:实现每个片段的照明模型。我将首先在顶点着色器中实现它,这样我就可以将所有内容都放在同一个位置。稍后我将移动到每像素。我不想在它们之间留有错误的空间,除非这是我唯一要处理的事情;这是片段着色器的关键用途之一:实现每个片段的照明模型。我将首先在顶点着色器中实现它,这样我就可以将所有内容都放在同一个位置。稍后我将移动到每像素。我不想在它们之间留有错误的空间,除非这是我唯一要处理的事情。我所处理的一切都是在世界空间吗?(在上面的源代码中)@MilesRufat Latre:No.它是模型局部空间(gl_顶点,gl_法线)、一些未定义的空间(lightpos,lightdir)和眼睛空间(gl_位置=fttransform())的混合体;就像我已经告诉过你的:只使用顶点着色器将事物带入公共空间,即眼睛空间,然后在片段着色器中进行照明计算要容易得多。要离开局部模型空间并转到全局,我会用gl_ModelView的倒数乘以模型局部变量吗?投影矩阵和模型视图矩阵是如何相互关联的?您可以将顶点位置与模型视图相乘以获得眼睛空间,法线与模型视图的逆转置相乘。灯光通常在世界空间,你们也必须把它们带到眼睛空间。只要看看任何解释转换管道的教程,无论是使用着色器还是固定函数。成功你的回答让我意识到我需要知道什么,所以我去寻找关于矩阵和空间如何相互关联的信息。镜面照明效果很好。我在世界空间处理的一切都好吗?(在上面的源代码中)@MilesRufat Latre:No.它是模型局部空间(gl_顶点,gl_法线)、一些未定义的空间(lightpos,lightdir)和眼睛空间(gl_位置=fttransform())的混合体;就像我已经告诉过你的:只使用顶点着色器将事物带入公共空间,即眼睛空间,然后在片段着色器中进行照明计算要容易得多。要离开局部模型空间并转到全局,我会用gl_ModelView的倒数乘以模型局部变量吗?投影矩阵和模型视图矩阵是如何相互关联的?您可以将顶点位置与模型视图相乘以获得眼睛空间,法线与模型视图的逆转置相乘。灯光通常在世界空间,你们也必须把它们带到眼睛空间。只要看看任何解释转换管道的教程,无论是使用着色器还是固定函数。成功你的回答让我意识到我需要知道什么,所以我去寻找关于矩阵和空间如何相互关联的信息。镜面照明效果很好。
//class program manages shaders
Program shaders = Program();
//attach a vertex shader, compiled from source in dirlight.vs
shaders.addShaderFile(GL_VERTEX_SHADER, "dirlight.vs");
//attach a fragment shader compiled from source in dirlight.fs
shaders.addShaderFile(GL_FRAGMENT_SHADER, "dirlight.fs");
//link program
shaders.link();
//use program
shaders.use();

//Program::getUniformLoc(const char* name) grabs the location
//of the uniform specified
GLint sTime = shaders.getUniformLoc("time");
GLint lightcount = shaders.getUniformLoc("lightcount");
GLint lightdir = shaders.getUniformLoc("lightdirs");
GLint lightdif = shaders.getUniformLoc("lightdifs");
GLint lightamb = shaders.getUniformLoc("lightambs");
GLint lightpos = shaders.getUniformLoc("lightposs");
GLint justcolor = shaders.getUniformLoc("justcolor");

glUniform1i(justcolor, 0);
glUniform1i(lightcount, 2);
//diffuse light colors
GLfloat lightdifs[] = {1.f, 1.f, 1.f, 1.f,
                      1.f, 1.f, 1.f, 1.f};
glUniform4fv(lightdif, 2, lightdifs);
glUniform4f(lightamb, 0.4f, 0.4f, 0.4f, 1.f);
//My lights rotate around the origin, where I have placed an icosphere
GLfloat lightposs[] = {-4 * sinf(newTime), lighth, -4 * cosf(newTime), 0.0f,
                       -4 * sinf(newTime + M_PI), lighth, -4 * cosf(newTime + M_PI), 0.0f};
glUniform4fv(lightpos, 2, lightposs);