我的场景中有一个点光源。我认为它工作正常,直到我用相机从不同角度观察被点亮的物体进行测试,发现光区域在网格上移动(在我的情况下是简单的平面)。我正在使用典型的ADS Phong照明方法。我将光位置转换为客户端的相机空间,然后使用模型视图矩阵转换顶点着色器中的插值顶点。
我的顶点着色器看起来像这样:
#version 420
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 uvs;
layout(location = 2) in vec3 normal;
uniform mat4 MVP_MATRIX;
uniform mat4 MODEL_VIEW_MATRIX;
uniform mat4 VIEW_MATRIX;
uniform mat3 NORMAL_MATRIX;
uniform vec4 DIFFUSE_COLOR;
//======= OUTS ============//
out smooth vec2 uvsOut;
out flat vec4 diffuseOut;
out vec3 Position;
out smooth vec3 Normal;
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
uvsOut = uvs;
diffuseOut = DIFFUSE_COLOR;
Normal = normal;
Position = vec3(MODEL_VIEW_MATRIX * position);
gl_Position = MVP_MATRIX * position;
}
片段着色器:
//==================== Uniforms ===============================
struct LightInfo{
vec4 Lp;///light position
vec3 Li;///light intensity
vec3 Lc;///light color
int Lt;///light type
};
const int MAX_LIGHTS=5;
uniform LightInfo lights[1];
// material props:
uniform vec3 KD;
uniform vec3 KA;
uniform vec3 KS;
uniform float SHININESS;
uniform int num_lights;
////ADS lighting method :
vec3 pointlightType( int lightIndex,vec3 position , vec3 normal) {
vec3 n = normalize(normal);
vec4 lMVPos = lights[0].Lp ; //
vec3 s = normalize(vec3(lMVPos.xyz) - position); //surf to light
vec3 v = normalize(vec3(-position)); //
vec3 r = normalize(- reflect(s , n));
vec3 h = normalize(v+s);
float sDotN = max( 0.0 , dot(s, n) );
vec3 diff = KD * lights[0].Lc * sDotN ;
diff = clamp(diff ,0.0 ,1.0);
vec3 spec = vec3(0,0,0);
if (sDotN > 0.0) {
spec = KS * pow( max( 0.0 ,dot(n,h) ) , SHININESS);
spec = clamp(spec ,0.0 ,1.0);
}
return lights[0].Li * ( spec+diff);
}
我已经研究了很多教程,但是当涉及到变换空间时,没有一个对整个过程进行彻底的解释。我怀疑它与相机空间有关,我将光和顶点位置转换成。在我的情况下使用
创建视图矩阵 glm::lookAt()
总是否定“眼睛”矢量的因此我的着色器中的视图矩阵否定了翻译部分。我应该是那样的吗?有人可以详细解释如何在可编程管道中以正确的方式完成它吗?我的着色器是根据书“OpenGL 4.0着色语言食谱”实现的。作者似乎也使用了相机空间。但它不能正常工作,除非它应该工作的方式。
我只是将计算移动到了世界空间。现在点光源仍然在现场。但我如何使用相机空间实现相同的效果呢?
答案 0 :(得分:1)
我确定了这个错误并且它非常愚蠢。但是对于那些太多而且数学友好的人来说,它可能会有所帮助。 。着色器中的光线位置用vec3定义。现在,在客户端用vec4表示。每次用视图矩阵转换之前,我都有效地将vec4的.w分量设置为等于零。这样做,我相信,光位置矢量没有被正确转换,并且由此所有光位置问题都出现在着色器中。解决方案是保持光位置矢量的w分量始终等于1.