2010-12-06 3 views
1

Я знаю, что этот вопрос задавали много, но я все еще не могу сделать это правильно.Glsl phong shader and camera

Итак, в моем вершинном шейдере мне нужно получить легкие постуки и положение глаз. Вот мой код:

void main(void) 
{ 
    vec3 p = vec3  (gl_ModelViewMatrix * gl_Vertex); 

    l = normalize (vec3 (gl_LightSource[0].position)); 
    v = normalize (vec3 (eyePos) - p); 
    n = normalize (gl_NormalMatrix * gl_Normal); 

    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

В результате свет движется с движением камеры. Что именно мне нужно сделать здесь? Возможно, без использования неопренг-матриц.

Есть ли пример освещения glsl с правильным управлением камерой?

* UPDATE *

Благодаря Кос, мне удалось "огни двигаться с камерой" проблема, но вот еще один:

У меня есть

glLightfv(GL_LIGHT0, GL_POSITION, light_position); 
glEnable(GL_LIGHT0); 
ctLight -> enable(); 

glPushMatrix(); 
    glTranslatef(0, 0, 0); 
    glRotatef(angle, 0, 1, 0); 
    glutSolidTeapot(2.0); 
glPopMatrix(); 

glPushMatrix(); 
    glTranslatef(0, 0, 8); 
    glRotatef(angle, 0, 1, 0); 
    glutSolidTeapot(2.0); 
glPopMatrix(); 

ctLight -> disable(); 
glDisable(GL_LIGHT0); 

Теперь второй чайник загорается так же, как и в (0, 0, 0). Как это исправить?

Vertex код шейдера в случае:

void main(void) 
{ 
    vec3 p = vec3 (gl_ModelViewMatrix * gl_Vertex);   // transformed point to world space 

    l = normalize (vec3 (gl_LightSource[0].position)); 
    v = normalize (- p); 

    h = normalize (l + v); 
    n = normalize (gl_NormalMatrix * gl_Normal);     // transformed n 

    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

ответ

3

Я не помню о «старых» освещения функций в OpenGL, но я считаю, что ваша проблема, имеющие некорректное значение в gl_LightSource[0].position.

Как вы указываете положение света (glLightParameterfv(GL_LIGHT_POSITION, ...);)? Самое главное, каково состояние матрицы модельного представления, когда вы укажете их?

Если матрица вида модели является тождественной, вы указываете светлые позиции в пространства для глаз, что создает впечатление, что они перемещаются вместе с камерой (хорошо, помните, что камера находится в положении (0,0,0)) всегда, и это мир, который движется).

Для правильного результата, я считаю, что вы должны указывать огни в пространстве мира, то есть после выполнения преобразований камеры на матрице вида модели, но перед выполнением каких-либо других операций над ним.

Светлое положение умножается на матрицу модели в момент спецификации, поэтому ваш шейдер всегда будет получать значение в пространстве глаз, что полезно - вам больше не нужно его изменять, поскольку вычисления освещения выполняются в пространстве глаза. Это также означает, что в ваших расчетах должно быть eyePos, что составляет v, равное normalize(-p).

Кроме того, для достижения наилучших результатов эти вычисления выполняются в фрагментном шейдере, а не в вершинном шейдере. :)

Надеюсь, что это поможет.

+0

что я сделал: 1. переехал "glLightfv (GL_LIGHT0, GL_POSITION, light_position);" справа после функции render(), которая устанавливает матрицу просмотра модели с gluLookAt. 2. изменен v, чтобы нормализовать (p), как вы посоветовали. теперь задняя сторона моего чайника выглядит темным, как и должно быть, но если я осматриваюсь на светлой стороне, то яркое пятно все еще движется. не так ли? Я не уверен – spacevillain 2010-12-07 17:02:49