Глазное пространство - это пространство, в которое ваша сцена преобразуется прямо перед тем, как пройти через матрицу проекции. Это то, что ftransform()
удобно переносит (под этим я подразумевал полный путь от пространства модели через пространство глаза (преобразование вида модели) до пространства отсечения (преобразование проекции)).
Матрица вида модели содержит полное преобразование из локального объекта в пространство глаза. Однако ваши огни будут находиться не в (каждом) локальном пространстве объекта, а в мировом пространстве. Итак, мы имеем дело с двумя различными преобразованиями:
- Объект локальный для мира - это модель часть модели
- Мир в глаза - это вид часть
Таким образом, технически было возможно преобразовать как источники света, так и вершины объекта в вершинном шейдере, предоставив разложенный вид модели в качестве модели и вид унифицированных матричных входных данных. Затем вы преобразуете положения света только по части вида, а вершины объекта - по модели, а затем просматриваете часть. Но я рекомендую не делать это таким образом. Вычислительные ресурсы блоков шейдеров должны быть зарезервированы для вычислений, которые имеют разные результаты для каждого входа вершины. Легкие преобразования положения не делают этого.
Вместо этого вы должны предварительно трансформировать свои световые позиции в пространство глаз, прежде чем передавать их шейдеру (униформе). Так как это сделать. Во-первых, я настоятельно рекомендую вам избавиться от старых функций манипулирования матрицей OpenGL (glRotate, glTranslate, glScale, ... и помощников GLU, таких как gluPerspective, ...). Вещи становятся проще без них, плюс они были удалены из более поздних версий OpenGL.
Так как же это сделать тогда? Скажем, у вас есть матричная библиотека, такая как GLM, но любая другая тоже будет работать. Для рендеринга вашей сцены вы должны следовать этой схеме (псевдокод, подобный Python)
render_scene:
projection_matrix = Matrix.Perspective(…)
view_matrix = Matrix.LookAt(…)
light_positions = []
for i, light in enumerate(scene.lights):
if i > MAX_LIGHTS:
break
light_positions.append( view_matrix * light.position )
glUniform3fv(glGetUniformLocation("lPositions"), light_positions)
for object in scene.objects:
obj_modelview = view_matrix * object.transform
# This is using deprecated functionality
glMatrixMode(GL_MODELVIEW); glLoadMatrix(obj_modelview)
object.draw()
Как вы можете видеть, источники света "вручную" преобразуются в пространство глаза с помощью view_matrix, тогда как вершины объекта не затрагиваются графическим процессором, но параметры для шейдера установлены для чертежа.