Как остановить позиционный свет, движущийся с камерой - PullRequest
1 голос
/ 15 мая 2019

Когда я вращаю и / или перемещаю камеру в моем проекте openGL, это почти как если бы прожектор двигался вместе с ним, однако я настроил мой свет gl на позиционное положение и присвоил ему статическое положение.

void Lighting::Display()
{
    glPushMatrix();

    glTranslatef(0.f, yoffset, 0.f); // move to start
    glTranslatef(0.f, ceilHeight * scale[0], 0.f);
    DrawLight();

    glDisable(GL_LIGHTING);

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    // Match colour of sphere to diffuse colour of light
    glColor4fv(specular);
    glTranslatef(0.f, -10.0f * scale[1], 0.f);
    glutSolidSphere(5.0f * scale[0], 25, 25);

    glPopAttrib();
    glPopMatrix();
    // Re-enable lighting after light source has been drawn
    glEnable(GL_LIGHTING);

    // Set properties GL_LIGHT0
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
    //glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0001f);

    GLfloat pos[4] = { 0.f, 950.f, 0.f, 1.f };
    glLightfv(GL_LIGHT0, GL_POSITION, pos);

    // enable GL_LIGHT0 with these defined properties
    glEnable(GL_LIGHT0);
}

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

Вот изображение, демонстрирующее проблему:

Как видите, излучается странная линия света.

Ответы [ 2 ]

2 голосов
/ 15 мая 2019

Если положение источника света установлено на glLightfv(GL_LIGHT0, GL_POSITION, pos), тогда pos умножается на матрицу вида текущей модели.

Интенсивность окружающего света (Ia), рассеянного света (Id) и зеркального света (Is) модели отражения Блинна-Фонга рассчитывается какследует:

N  ... norlmal vector 
L  ... light vector (from the vertex position to the light) 
V  ... view vector (from the vertex position to the eye)
sh ... shininess

H     = normalize(V + L)
NdotH = max(dot(N, H), 0.0)

Ia    = 1
Id    = max(dot(N, L), 0.0)
Is    = pow(NdotH, sh)

Таким образом, окружающий свет (GL_AMBIENT) не зависит от какого-либо направления.

Рассеянный свет (GL_DIFFUSE) зависит от вектора нормали поверхности (N) и направления падающего света (L).Он остается постоянным на освещенной поверхности, независимо от точки зрения.

Зеркальный свет (GL_SPECULAR) зависит от вектора нормали поверхности (N), направления света (L).и направление просмотра (V).Это приводит к тому, что зеркальные блики меняются, когда вы перемещаетесь в сцене, потому что изменяется направление просмотра на освещенные поверхности.

Далее обратите внимание, что вычисления света в устаревшей модели освещения с фиксированной функцией OpenGL выполняются для каждой вершины ( Gouraud Shading ).Рассчитанный свет интерполируется по площади, между углами примитивов. современная реализация будет заключаться в расчете освещения для каждого фрагмента ( Phong shading ).Затенение Гуро вызывает пятнистый вид зеркальных бликов на потолке и может увеличить неожиданный вид.Оптимизация областей в меньших количествах может улучшить это, но лучшим решением будет переключиться на современный OpenGL, написать шейдер и реализовать модель освещения для каждого фрагмента для ваших нужд.

0 голосов
/ 15 мая 2019

Перед тем, как установить положение освещения, вы можете вставить свою матрицу. В результате ваше положение вашего света всегда является тем, что вы устанавливаете. Затем вы умножаете все остальное на вашу матрицу представления, которую я предполагаю. Матрица просмотра существенно превращает мир в вид из камеры. По сути, камера не движется, мир движется вокруг камеры. Поскольку свет не умножается на эту матрицу вида, ТАКЖЕ вы получаете свет, который, по-видимому, поддерживает постоянное положение относительно камеры.

...