OpenGLES2 Shader: Положение освещения и движение камеры?

Я попытался добавить освещение в свое приложение OpenGLES2, следуя инструкциям на http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/

В отличие от предыдущего урока, у меня есть движения камеры FPS. В вершинном шейдере я жестко закодировал положение камеры (u_LightPos) в мире coodinates. Но это дает странные световые эффекты при перемещении камеры. Мне нужно преобразовать эту позицию, используя проекцию / посмотреть матрицу?

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;                         
}  

1 ответ

Решение

При выполнении арифметики над векторами они должны находиться в одном координатном пространстве. Вы вычитаете modelViewVertex (пространство просмотра) из u_LightPos (пространство мира), что даст вам фиктивный результат.

Вам нужно решить, хотите ли вы выполнять расчеты освещения в мировом пространстве или просматривать пространство (либо должно быть допустимым), но вы должны преобразовать все входные данные в одно и то же пространство.

Это означает либо получение вершины / нормального /lightpos в мировом пространстве, либо получение вершины / нормального /lightpos в пространстве обзора.

Попробуйте умножить ваш lightpos на матрицу вида (не на модель), а затем использовать это в своих вычислениях вместо u_Lightpos, я думаю, это должно сработать.

Другие вопросы по тегам