Как сделать освещение в opengl

Обновлено: 07.07.2024

Подскажите где ошибся:

Скрины прикрепи, со светом и без, взглянуть хочу.

Вот мой самовар со светом, все работает.

Судя по картинке свет в сцене все-таки есть, поскольку уровень света на указанных мною фрагментах разный. Другое дело где находиться источник света по отношению к участку который мы видим, т.е с какой стороны он освещает объект. Есть ли нормали у объекта, нормированы ли они? И в какой системе координат находиться сам источник света. Почитай про последний параметр позиции в книжках по опен гл. Тем более тема уже всплывала, как мне помнится. Поройся в недавних темах - про свет и w компоненту позиции света.

Свет я поставил сверху справа.
Нормали влияют на свет? Просто я свет учил по урокам NEHE и у него без них как то
То что ты указал это не свет) это текстура легла кривовато. Надо переписать

Материалы в OpenGL – это способность полигона реагировать на свет по-своему.
Материал задаётся функцией glMaterialfv(glFace,Param,@array).

  • GL_FRONT – лицевая плоскость;
  • GL_BACK – задняя плоскость;
  • GL_FRONT_AND_BACK – все плоскости.
  • GL_AMBIENT – цвет рассеянного света;
  • GL_SPECULAR – цвет зеркального света;
  • GL_DIFFUSE – цвет диффузного света (смешанного);
  • GL_SHININESS – сила блика;
  • GL_EMISSION - интенсивность излучаемого света.

Но для GL_SHININESS параметрами будет не массив, а одно число от 128 до 0, 0 – это максимальная сила блика, а 128 минимальная. В связи с этим изменится и сама функция с glMaterialfv на glMaterialf. Окончание fv на конце названия функции означает, что параметром будет массив типа PGLfloat – это специальный тип данных в OpenGL, он эквивалентен типу Single. Окончание f означает, что параметром будет не массив, а одно число типа GLfloat. Этот тип данных тоже эквивалентен Single. Есть ещё и окончание i , параметром будет число типа Integer.

Чтобы лучше было понятно зададим все 5 видов материала:
Если мы хотим нарисовать 2 и более примитива с разными материалами, то функцию следует вызывать каждый раз перед рисованием примитива.

С материала мы закончили, теперь перейдём к освещению.

Как создать и добавить источник света на сцену мы знаем из прошлых уроков, а вот как изменять свойства источника света мы узнаем сейчас!

  • GL_SPOT_EXPONENT параметр param должен содержать целое или вещественное число от 0 до 128, задающее распределение интенсивности света. Этот параметр описывает уровень сфокусированности источника света. Значение по умолчанию: 0 (рассеянный свет).
  • GL_SPOT_CUTOFF параметр param должен содержать целое или вещественное число между 0 и 90 или равное 180, которое определяет максимальный угол разброса света. Значение этого параметра есть половина угла в вершине конусовидного светового потока, создаваемого источником. Значение по умолчанию: 180 (рассеянный свет).
  • GL_POSITION параметр params должен содержать четыре целых или вещественных, которые определяют положение источника света. Если значение компоненты w равно 0.0, то источник считается бесконечно удаленным и при расчете освещенности учитывается только направление на точку (x,y,z), в противном случае считается, что источник расположен в точке (x,y,z,w). Значение по умолчанию: (0.0, 0.0, 1.0, 0.0).
  • GL_SPOT_DIRECTION параметр params должен содержать четыре целых или вещественных числа, которые определяют направление света. Значение по умолчанию: (0.0, 0.0, -1.0, 1.0).

В примере к данному уроку изображён чайник и летающий вокруг него источник света. Стрелками 'вверх' и 'вниз' можно изменять силу блика.

Для создания реалистических изображений необходимо определить как свойства самого объекта, так и свойства среды, в которой он находится. Первая группа свойств включает в себя параметры материла, из которого сделан объект, способы нанесения текстуры на его поверхность, степень прозрачности объекта. Ко второй группе можно отнести количество и свойства источников света, уровень прозрачности среды. Все эти свойства можно задавать, используя соответствующие команды OpenGL.

Для задания параметров текущего материала используются команды

С их помощью можно определить рассеянный, диффузный и зеркальный цвета материала, а также цвет степень зеркального отражения и интенсивность излучения света, если объект должен светиться. Какой именно параметр будет определяться значением param, зависит от значения pname:

GL_AMBIENT параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют рассеянный цвет материала (цвет материала в тени).

Значение по умолчанию: (0.2, 0.2, 0.2, 1.0).

GL_DIFFUSE параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет диффузного отражения материала.

Значение по умолчанию:(0.8, 0.8, 0.8, 1.0).

GL_SPECULAR параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет зеркального отражения материала.

Значение по умолчанию: (0.0, 0.0, 0.0, 1.0).

GL_SHININESS параметр params должен содержать одно целое или вещественное значение в диапазоне от 0 до 128, которое определяет степень зеркального отражения материала.

Значение по умолчанию: 0.

GL_EMISSION параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют интенсивность излучаемого света материала.

Значение по умолчанию: (0.0, 0.0, 0.0, 1.0).

GL_AMBIENT_AND_DIFFUSE эквивалентно двум вызовам команды glMaterial…() со значением pname GL_AMBIENT и GL_DIFFUSE и одинаковыми значениями params.

Из этого следует, что вызов команды glMaterial[i f]() возможен только для установки степени зеркального отражения материала. В большинстве моделей учитывается диффузный и зеркальный отраженный свет; первый определяет естественный цвет объекта, а второй - размер и форму бликов на его поверхности.

Параметр face определяет тип граней, для которых задается этот материал и может принимать значения GL_FRONT, GL_BACK или GL_FRONT_AND_BACK.

Если в сцене материалы объектов различаются лишь одним параметром, рекомендуется сначала установить нужный режим, вызвав glEnable() c параметром GL_COLOR_MATERIAL, а затем использовать команду

void glColorMaterial(GLenum face, GLenum pname)

где параметр face имеет аналогичный смысл, а параметр pname может принимать все перечисленные значения. После этого, значения выбранного с помощью pname свойства материала для конкретного объекта (или вершины) устанавливается вызовом команды glColor…(), что позволяет избежать вызовов более ресурсоемкой команды glMaterial…() и повышает эффективность программы.

Добавить в сцену источник света можно с помощью команд

Параметр light однозначно определяет источник,и выбирается из набора специальных символических имен вида GL_LIGHTi, где i должно лежать в диапазоне от 0 до GL_MAX_LIGHT, которое не превосходит восьми.

Оставшиеся два параметра имеют аналогичный смысл, что и в команде glMaterial…(). Рассмотрим их назначение (вначале описываются параметры для первой команды, затем для второй):

GL_SPOT_EXPONENT параметр param должен содержать целое или вещественное число от 0 до 128, задающее распределение интенсивности света. Этот параметр описывает уровень сфокусированности источника света.

Значение по умолчанию: 0 (рассеянный свет).

GL_SPOT_CUTOFF параметр param должен содержать целое или вещественное число между 0 и 90 или равное 180, которое определяет максимальный угол разброса света. Значение этого параметра есть половина угла в вершине конусовидного светового потока, создаваемого источником.

Значение по умолчанию: 180 (рассеянный свет).

GL_AMBIENT параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет фонового освещения.

Значение по умолчанию: (0.0, 0.0, 0.0, 1.0).

GL_DIFFUSE параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет диффузного освещения.

Значение по умолчанию: (1.0, 1.0, 1.0, 1.0)для LIGHT0 и (0.0, 0.0, 0.0, 1.0) для остальных.

GL_SPECULAR параметр params должен содержать четыре целых или вещественных значения цветов RGBA, которые определяют цвет зеркального отражения.

Значение по умолчанию: (1.0, 1.0, 1.0, 1.0)для LIGHT0 и (0.0, 0.0, 0.0, 1.0) для остальных.

GL_POSITION параметр params должен содержать четыре целых или вещественных, которые определяют положение источника света. Если значение компоненты w равно 0.0, то источник считается бесконечно удаленным и при расчете освещенности учитывается только направление на точку (x,y,z), в противном случае считается, что источник расположен в точке (x,y,z,w).

Значение по умолчанию: (0.0, 0.0, 1.0, 0.0).

GL_SPOT_DIRECTION параметр params должен содержать четыре целых или вещественных числа, которые определяют направление света.

Значение по умолчанию: (0.0, 0.0, -1.0, 1.0).

При изменении положения источника света следует учитывать следующие факты: если положение задается командой glLight…() перед определением ориентации взгляда (командой glLookAt()), то будет считаться, что источник находится в точке наблюдения. Если положение устанавливается между заданием ориентации и преобразованиями видовой матрицы, то оно фиксируется и не зависит от видовых преобразований. В последнем случае, когда положение задано после ориентации и видовой матрицы, его положение можно менять, устанавливая как новую ориентацию наблюдателя, так и меняя видовую матрицу.

Для использования освещения сначала надо установить соответствующий режим вызовом команды glEnable (GL_LIGHTNING), а затем включить нужный источник командой glEnable(GL_LIGHTn).

В OpenGL используется модель освещения Фонга, в соответствии с которой цвет точки определяется несколькими факторами: свойствами материала и текстуры, величиной нормали в этой точке, а также положением источника света и наблюдателя. Для корректного расчета освещенности в точке надо использовать единичные нормали, однако команды типа glScale…(), могут изменять длину нормалей. Чтобы это учитывать, используется уже упоминавшийся режим нормализации нормалей, который включается вызовом команды glEnable(GL_NORMALIZE).

Для задания глобальных параметров освещения используются команды

Аргумент pname определяет, какой параметр модели освещения будет настраиваться и может принимать следующие значения:

GL_LIGHT_MODEL_LOCAL_VIEWER параметр param должен быть булевским и задает положение наблюдателя. Если он равен FALSE, то направление обзора считается параллельным оси -z, вне зависимости от положения в видовыx координатах. Если же он равен TRUE, то наблюдатель находится в начале видовой системы координат. Это может улучшить качество освещения, но усложняет его расчет.

Значение по умолчанию: FALSE.

GL_LIGHT_MODEL_TWO_SIDE параметр param должен быть булевским и управляет режимом расчета освещенности как для лицевых, так и для обратных граней. Если он равен FALSE, то освещенность рассчитывается только для лицевых граней. Если же он равен TRUE, расчет проводится и для обратных граней. Значение по умолчанию: FALSE.

GL_LIGHT_MODEL_AMBIENT параметр params должен содержать четыре целых или вещественных числа, которые определяют цвет фонового освещения даже в случае отсутствия определенных источников света.

Здравствуйте. Я новичок в OpenGL, и мне в университете дали задание обработать программу таким образом, чтобы был объект, источник света и тень. Проблема в том, что источник света себя ведет не совсем так как я хотел бы. Если я рисую сферу, (эта функция родная), то свет падает правильно. Но когда программа рисует объект из полигонов, типа космического корабля, то есть уже не родная функция OpenGL'а, то свет ведет себя уже совсем иначе. Помогите пожалуйста. Я скину архив с exe и немного кода, отвечающего за прорисовку и за функцию освещения. Когда откроете программу, будет два объекта, корабль и сфера, чтобы лучше было видно, нажмите на клавиатуре кнопку "P", тогда программа будет обрабатывать корабль точечно, и сферу будет лучше видно. Чтобы обрабатывать корабль полыми треугольниками нажмите "L", а полными -"T". В архиве есть нужные библиотеки, поэтому, если у вас нету VS, то все равно exe запустится. Вот код:

Освещение OpenGL
Добрый вечер! Создала в OpenGL пирамиду, которая вращается по нажатию клавиш, и пытаюсь сделать ей.

OpenGL: освещение
Как на OpenGL сделать освещение (в т. ч. и тени)? Пробовал много способов, в большинстве случаев.

OpenGl. (Delphi). Освещение
Помогите, плиииизз. не очень поняла освещение. как сделать включить освещение наподобие солнца.

Освещение обьекта в OpenGL
Решил сделать что-то вроде модели солнечной системы. Внезапно возникли такие проблемы: 1) Свет.

Да, но там 6925 точек и 9653 полигонов. Посоветуйте пожалуйста как указать правильно нормаль к каждой из них.

Сделал вот так, работает). Но есть другая проблема: Как сделать так, чтобы свет не вращался вместе с объектом?

GL_POSITION

The params parameter contains four floating-point values that specify the position of the light in homogeneous object coordinates. Both integer and floating-point values are mapped directly. Neither integer nor floating-point values are clamped.

The position is transformed by the modelview matrix when glLightfv is called (just as if it were a point), and it is stored in eye coordinates. If the w component of the position is 0.0, the light is treated as a directional source. Diffuse and specular lighting calculations take the light's direction, but not its actual position, into account, and attenuation is disabled. Otherwise, diffuse and specular lighting calculations are based on the actual location of the light in eye coordinates, and attenuation is enabled. The default position is (0,0,1,0); thus, the default light source is directional, parallel to, and in the direction of the -z axis.

что бы свет не вращался с моделью нужно задавать позицию источника света до трансформации

Сделал вот так, работает). Но есть другая проблема: Как сделать так, чтобы свет не вращался вместе с объектом?

Увидев такую реализацию хочется немедленно удавиться Ладно, технику программирования не обсуждаем, по вертексным нормалям:

- Ваш вариант рассчитывает нормали для сферы с центром в начале координат, для любой др модели это неверно

- в большинстве случаев вертексные нормали хранятся в файле модели и должны быть оттуда прочитаны.

- только если нет данных, нормали к вертексам рассчитываются как среднее нормалей полигонов содержащих вертекс. Этот вариант хуже предыдущего т.к. осредненные нормали могут быть совсем не так точны. Если модель не имеет информации shared/unshared (напр кубик из 8 вертексов), то должен быть задан "shared angle" (по умолчанию 60 градусов)

считать нормаль как векторное произведение (v[2] - v[1]) ^ (v[0] - v[1]) где v[0] v[1] v[2] - вершины относящиеся к одной треугольной грани. нормаль получится внешней если вершины упорядочены таким образом что обход грани по вершинам 0 1 2 идет против часовой стрелки если смотреть на грань с лицевой стороны

считать нормаль как векторное произведение (v[2] - v[1]) ^ (v[0] - v[1]) где v[0] v[1] v[2] - вершины относящиеся к одной треугольной грани. нормаль получится внешней если вершины упорядочены таким образом что обход грани по вершинам 0 1 2 идет против часовой стрелки если смотреть на грань с лицевой стороны

Это называется "wind order". Только одним треугольником не отделаться, т.к. получится тот же flat shading. Нужна сумма по всем полигонам в которые этот вертекс входит. А если модель не расшарена - то там еще геморрой "по всем или каким". И не надо с ложечки кормить векторным произведением - пусть тренируется, а то размахнулся тут с copy/paste

Спасибо большое. Буду изучать. Я сделал еще вот так вот кстати пару дней назад. Но что-то мне подсказывает, что тоже неправильно.

Этот способ верный?

Читайте также: