Array ( )
Вход:




Главная | OpenGL | GLSL | AI | Сеть | Примеры | Библиотека

GLSL: Практика: Toon-шейдер - Версия III






Прежде, чем закончить эти уроки, сделаем ещё одну вещь: используем свет OpenGL
вместо переменной lightDir. Таким образом мы сможем обьявлять свет в OpenGL
и использовать его направление в шейдерах. Учтите, включать освещение в OpenGL
функцией glEnable нет необходимости, так как мы не будем использовать глобальное
освещение OpenGL.

Мы обьявим первый источник света в OpenGL (GL_LIGHT0) как направленный свет.

GLSL предоставляет доступ к части функционала OpenGL, в том числе - к параметрам
освещения. В GLSL обьявлена структура для данных света, и массив для хранения
структур всех источников света.


struct gl_LightSourceParameters {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 position;
...
};

uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];



Это значит, что у нас есть доступ к направлению света (поле position для направленного
источника) в вершинном шейдере. Опять же, направление света должно быть нормализовано в
приложении OpenGL.

Спецификация OpenGL указывает, что когда инициализируется источник света, его позиция
автоматически устанавливается в позицию нашего "глаза" - камеры. При этом вектор его
направления нормализован (если мы остаемся в ортогональной матрице 3х3, а при использовании
gluLookAt() это мы в ней, пока не используем glScalef() и другие scalers).

Нам нужно конвертировать нормаль в координаты нашего "взгляда", чтобы вычислить
dot product и др.

Чтобы трансформировать нормаль в координаты "взгляда", мы используем заранее обьявленную
uniform-переменную mat3 gl_NormalMatrix. Эта матрица - результат инвертирования 3x3 право-верхней
саб-матрицы из матрицы моделей. Сделаем трансформацию нормалей на каждую вершину. Таким
образом вершинный шейдер получится таким:

Файл toon.vert
    varying vec3 normal;
   
    void main()
    {

        normal = gl_NormalMatrix * gl_Normal;
   
        gl_Position = ftransform();
    }


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

Файл toon.frag:
    varying vec3 normal;
   
    void main()
    {
        float intensity;
        vec4 color;
        vec3 n = normalize(normal);
       
        intensity = dot(vec3(gl_LightSource[0].position),n);
       
        if (intensity > 0.95)
            color = vec4(1.0,0.5,0.5,1.0);
        else if (intensity > 0.5)
            color = vec4(0.6,0.3,0.3,1.0);
        else if (intensity > 0.25)
            color = vec4(0.4,0.2,0.2,1.0);
        else
            color = vec4(0.2,0.1,0.1,1.0);
       
        gl_FragColor = color;
    }







Ну а теперь перейдём к коду программы. Возьмите его из первого практического урока.
Файл main.cpp:
// В самом начале добавим поддержку библиотеки glut:
#pragma comment(lib, "glut32.lib")
#include <gl/glut.h>

// Инициализируем переменные:
GLuint v,f,f2,p;        // Дескрипторы программ и шейдеров
float lpos[4] = {1,0.5,1,0};    // Позиция источника света
float a = 0;            // Хранит угол вращения



///////////////////////////////////////////////////
// В функции setShaders() изменим, название файлов шейдеров:
    vs = textFileRead("toon.vert");
    fs = textFileRead("toon.frag");

// Теперь в функцию RenderScene() добавим создание чайника:
    glutSolidTeapot(1);


Всё, компилируем и смотрим результат.
Скачайте и посмотрите исходники, если что-то пойдет не так.





Исходные коды к уроку




Комментарии:

Войдите, чтобы оставить комментарий:












Яндекс.Метрика
 Яндекс цитирования.