我尝试按照http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/
中的教程为我的OpenGLES2应用添加灯光与上面的教程不同,我有FPS摄像机动作。在顶点着色器中,我在世界坐标系中有硬编码摄像机位置(u_LightPos)。但是当我移动摄像机时它给出了奇怪的光照效果。我是否必须改变这个位置使用投影/视图矩阵?
uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;
attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec3 a_Normal;
varying vec4 v_Color;
void main()
{
vec3 u_LightPos=vec3(0,0,-20.0);
vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);
vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));
float distance = length(u_LightPos - modelViewVertex);
// Get a lighting direction vector from the light to the vertex.
vec3 lightVector = normalize(u_LightPos - modelViewVertex);
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
float diffuse = max(dot(modelViewNormal, lightVector), 0.1);
// Attenuate the light based on distance.
diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));
// Multiply the color by the illumination level. It will be interpolated across the triangle.
v_Color = a_Color * diffuse;
// gl_Position is a special variable used to store the final position.
// Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
gl_Position = u_MVPMatrix * a_Position;
}
答案 0 :(得分:1)
对矢量执行算术时,它们必须位于相同的坐标空间中。你从u_LightPos(世界空间)中减去modelViewVertex(视图空间),这会给你一个虚假的结果。
您需要决定是否要在世界空间或视图空间中进行光照计算(或者应该有效),但您必须将所有输入转换为相同的空间。
这意味着要么在世界空间中获取顶点/法线/ lightpos,要么在视图空间中获取顶点/法线/ lightpos。
尝试将你的lightpos乘以视图矩阵(而不是modelview),然后在你的计算中使用它而不是u_Lightpos,我认为它应该有效。