Введение в использование шейдеров opengl

108
Введение в использование шейдеров OpenGL Компьютерная графика. Лекция 7

Upload: edie

Post on 24-Feb-2016

178 views

Category:

Documents


1 download

DESCRIPTION

Компьютерная графика. Лекция 7. Введение в использование шейдеров OpenGL. Необходимость программирования графических адаптеров. Компьютерная графика. Лекция 7. Программируемое графическое аппаратное обеспечение существует почти столько же времени, сколько и обычное. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Введение в использование шейдеров  OpenGL

Введение в использование шейдеров OpenGL

Компьютерная графика. Лекция 7

Page 2: Введение в использование шейдеров  OpenGL

Программируемое графическое аппаратное обеспечение существует почти столько же времени, сколько и обычное. Акселераторы разрабатываются несколько лет, а устаревают за год. Единственный способ гарантировать поддержу современных API – внести программируемость

НЕОБХОДИМОСТЬ ПРОГРАММИРОВАНИЯ ГРАФИЧЕСКИХ АДАПТЕРОВ

Компьютерная графика. Лекция 7

Page 3: Введение в использование шейдеров  OpenGL

Несмотря на поддержу программируемости на уровне аппаратуры ей нельзя было воспользоваться, т.к. ни один графический API ее не поддерживал!

Раскрытие возможностей программируемости требовало дорогостоящего обучения разработчиков и поддержки пользователей

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

ПРОБЛЕМЫ ПРОГРАММИРОВАНИЯ ГРАФИЧЕСКИХ АДАПТЕРОВ

Компьютерная графика. Лекция 7

Page 4: Введение в использование шейдеров  OpenGL

Одновременно с совершенствованием графической аппаратуры совершенствовались графические API.

Первоначально разработчикам были доступны подобные ассемблеру языки для обработки графики, однако со временем появились удобные и надежные языки высокого уровня.

Сегодня GPU стали универсальными процессорами для параллельной обработки чисел с плавающей запятой и могут быть использованы для решения огромного числа задач, даже не имеющих прямого отношения к графике

Компьютерная графика. Лекция 7

РАЗВИТИЕ ГРАФИЧЕСКИХ API

Page 5: Введение в использование шейдеров  OpenGL

Интерактивные шейдерные языки стали доступны всем!

Для желающего воспользоваться программируемостью графического аппаратного обеспечения существует множество вариантов:HLSL (Microsoft)Cg (NVidia)GLSL (ARB)

Компьютерная графика. Лекция 7

ЯЗЫКИ ДЛЯ РАЗРАБОТКИ ШЕЙДЕРОВ

Page 6: Введение в использование шейдеров  OpenGL

ЧТО ТАКОЕ ШЕЙДЕР? Шейдер (англ. – shader) – целостный кусок

кода на языке шейдеров, предназначенный для выполнения на одном из программируемых процессоров

В OpenGL 2.0 введены два типа шейдеров Вершинные шейдеры Фрагментные шейдеры

Компьютерная графика. Лекция 7

Page 7: Введение в использование шейдеров  OpenGL

ДЛЯ ЧЕГО НУЖНЫ ШЕЙДЕРЫ? OpenGL предоставляет программистам

гибкий, но статический интерфейс для рисования графики Шейдеры позволяют приложению

переопределить стандартный способ обработки графики на некоторых этапах рендеринга

С помощью шейдеров стало возможным применение продвинутых технологий рендеринга в реальном времени

Компьютерная графика. Лекция 7

Page 8: Введение в использование шейдеров  OpenGL

ЯЗЫК ШЕЙДЕРОВ В OPEN GL 2.0 В 2004 году опубликован OpenGL2.0, основное

нововведение – высокоуровневой язык шейдеров GLSL (OpenGL Shading Language), предоставляющих приложениям возможность реализации собственных механизмов рендеринга при помощи замены стандартных обработчиков вершин и фрагментов

Отличительная особенность GLSL в том, что он тщательно анализировался и оценивался многими производителями аппаратного обеспечения. Основная цель при его создании – достижение кроссплатформенности, надежности и стандартизации

Компьютерная графика. Лекция 7

Page 9: Введение в использование шейдеров  OpenGL

ОТЛИЧИТЕЛЬНЫЕ ОСОБЕННОСТИ GLSL Тесная интеграция с OpenGL API

GLSL был спроектирован для совместного использования с OpenGL. Специально предусмотрено, чтобы приложения можно было легко модифицировать для поддержки шейдеров. GLSL имеет встроенные возможности доступа к состоянию OpenGL

Открытый межплатформенный стандартЗа исключением языка шейдеров OpenGL,

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

Компьютерная графика. Лекция 7

Page 10: Введение в использование шейдеров  OpenGL

ОТЛИЧИТЕЛЬНЫЕ ОСОБЕННОСТИ GLSL Компиляция во время выполнения

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

Независимость от языка ассемблера различных производителейПроектировщики аппаратуры не

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

Компьютерная графика. Лекция 7

Page 11: Введение в использование шейдеров  OpenGL

ОТЛИЧИТЕЛЬНЫЕ ОСОБЕННОСТИ GLSL Неограниченные возможности по

оптимизации компилятора под различные платформыУсовершенствовать компиляторы можно с

каждой новой версией драйвера OpenGL и приложения не придется модифицировать или перекомпилировать

Отсутствие дополнительных библиотек и программВсе необходимое – язык шейдеров,

компилятор и компоновщик – определены как часть OpenGL

Компьютерная графика. Лекция 7

Page 12: Введение в использование шейдеров  OpenGL

РАЗЛИЧИЕ МЕЖДУ ЯЗЫКАМИ OPENGL И HLSL: Код на языке GLSL компилируется в

машинный код непосредственно внутри драйвера графического ускорителяКод на HLSL транслируется в язык

ассемблера внутри DirectX, а затем переводится в машинный код внутри драйвера

Компьютерная графика. Лекция 7

Шейдер HLSL

Транслятор HLSL

Программа D3D

Драйвер Direct3D

Аппаратура

Ассемблер

Шейдер GLSL

Драйвер OpenGL

Аппаратура

Компилятор GLSL

ЯВУ

Page 13: Введение в использование шейдеров  OpenGL

КОНВЕЙЕР ОПЕРАЦИЙ OPENGL Вплоть до версии 2.0 OpenGL предоставлял

программистам статичный или фиксированный интерфейс для рисования графики

На функционирование OpenGL можно смотреть как на стандартную последовательность операций, применяемую к геометрическим данным для вывода их на экран

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

Рассмотрим стандартный конвейер операций OpenGL подробнее

Компьютерная графика. Лекция 7

Page 14: Введение в использование шейдеров  OpenGL

ДИАГРАММА РАБОТЫ СТАНДАРТНОГО КОНВЕЙЕРА OPENGL

Основные этапы работы стандартного графического конвейера OpenGLОбработка вершин

Трансформация вершин и нормалей Расчет освещения в вершинах Генерирование текстурных координат

Обработка примитивов Сборка примитивов Отсечение Проецирование вершин

Обработка фрагментов Растеризация примитивов, наложение текстур Операции над пикселями

Компьютерная графика. Лекция 7

Page 15: Введение в использование шейдеров  OpenGL

КОНВЕЙЕР ОПЕРАЦИЙ OPENGLКомпьютерная графика. Лекция 7

Page 16: Введение в использование шейдеров  OpenGL

ПРОГРАММИРУЕМАЯ ФУНКЦИОНАЛЬНОСТЬ Самое большое изменение OpenGL со времени его

создания – внедрение программируемых вершинных и фрагментных процессоров

С введением программируемости, если она используется приложением, стандартная (или фиксированная) функциональность выключается

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

Рассмотрим конвейер операций с программируемыми процессорами

Компьютерная графика. Лекция 7

Page 17: Введение в использование шейдеров  OpenGL

КОНВЕЙЕР ОПЕРАЦИЙ OPENGLКомпьютерная графика. Лекция 7

Page 18: Введение в использование шейдеров  OpenGL

ВЕРШИННЫЙ ПРОЦЕССОР Это программируемый модуль, который

выполняет операции над входными значениями вершин и другими связанными с ними данными.

Вершинный процессор выполняет: Преобразование вершин Преобразование и нормализация нормалей Генерирование и преобразование текстурных

координат Настройка освещения Наложение цвета на материалШейдеры, предназначенные для выполнения на этом процессоре, называются вершинными

Компьютерная графика. Лекция 7

Page 19: Введение в использование шейдеров  OpenGL

ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ ВЕРШИННОГО ПРОЦЕССОРА

Вершинный

процессор

Встроенные переменные атрибутов:

gl_Color, gl_Normal, gl_Vertex, gl_MultiTexCoord0 и др.

Определенные пользователем

переменные атрибутов:StartColor, Velocity, Elevation, Tangent и т.п.

Определенные пользователем uniform-

переменые:Time, EyePosition, LightPosition и т.п.

Встроенные uniform-переменые:

gl_ModelViewMatrix, gl_FrontMaterial, gl_LightSource[0..n], gl_Fog и т.п.

Встроенные varying-переменные:

gl_FrontColor, gl_BackColor, gl_FogFragCoord и др.

Специальные выходные переменные:

gl_Position, gl_PointSize, gl_ClipVertex

Определенные пользователем varying-

переменные:Normal, ModelCoord, RefractionIndex, Density и т.п.

Карты текстур

Компьютерная графика. Лекция 7

Page 20: Введение в использование шейдеров  OpenGL

КВАЛИФИКАТОРЫ ТИПОВ Для управления входными и выходными

данными вершинного шейдера используются квалификаторы типов, определенные как часть языка шейдеров OpenGL:Переменные-атрибуты (attribute) Однообразные переменные (uniform)Разнообразные переменные (varying)

Компьютерная графика. Лекция 7

Page 21: Введение в использование шейдеров  OpenGL

ATTRIBUTE-ПЕРЕМЕННЫЕ ВЕРШИННОГО ШЕЙДЕРА Представляют собой данные, передаваемые

вершинному шейдеру от приложения Могут задавать значения атрибутов либо

между glBegin()/glEnd(), либо при помощи функций, работающих с вершинными массивами

OpenGL поддерживает как встроенные, так и определенные пользователем attribute-переменные gl_Normal, gl_Vertex, gl_Color

Компьютерная графика. Лекция 7

Page 22: Введение в использование шейдеров  OpenGL

UNIFORM-ПЕРЕМЕННЫЕ Используются для передачи редко

изменяемых данных как вершинному, так и фрагментному шейдеруUniform-переменные не могут задаваться

между вызовами glBegin() и glEnd()OpenGL поддерживает как встроенные, так и

определенные пользователем uniform-переменные

Для передачи значения uniform-переменной приложение должно сначала определить расположение данной переменной (индекс) по имени

Компьютерная графика. Лекция 7

Page 23: Введение в использование шейдеров  OpenGL

VARYING-ПЕРЕМЕННЫЕ Данные в varying-переменных передаются из

вершинного шейдера в фрагментный Бывают как встроенными, так и

определенными пользователем Для каждой вершины значение

соответствующей varying-переменной будет своим В процессе растеризации происходит

интерполяция значений varying-переменных с учетом перспективы

Компьютерная графика. Лекция 7

Page 24: Введение в использование шейдеров  OpenGL

ФРАГМЕНТНЫЙ ПРОЦЕССОР Это программируемый модуль,

выполняющий операции над фрагментами и другими связанными с ними данными

ФП выполняет следующие стандартные операции: Операции над интерполируемыми значениями Доступ к текстурам Наложение текстур Создание эффекта тумана Смешивание цветовШейдеры, предназначенные для выполнения на этом процессоре, называются фрагментными

Компьютерная графика. Лекция 7

Page 25: Введение в использование шейдеров  OpenGL

ВХОДНЫЕ И ВЫХОДНЫЕ ДАННЫЕ ФРАГМЕНТНОГО ПРОЦЕССОРА

Фрагментный процессор

Встроенные varying-переменные:

gl_Color, gl_SecondaryColor, gl_TexCoord[0..n],gl_FogFragCoord

Специальные входные переменные:

gl_FragCoordgl_FrontFacing

Определенные пользователем varying-

переменные:Normal, ModelCoord, RefractionIndex, Density и т.п.

Специальные выходные переменные:

gl_FragColorgl_FragDepth

Определенные пользователем uniform-

переменные:ModelScaleFactor, AnimationPhase, WeightingFactor и т.п.

Карты текстурВстроенные uniform-

переменые:gl_ModelViewMatrix, gl_FrontMaterial, gl_LightSource[0..n], gl_Fog и т.п.

Page 26: Введение в использование шейдеров  OpenGL

ФРАГМЕНТНЫЙ ПРОЦЕССОР НЕ ЗАМЕНЯЕТ СЛЕДУЮЩИЕ ОПЕРАЦИИ: Покрытие Проверка на видимость Отсечение по прямоугольнику (scissors test) Тест трафарета Тест прозрачности Тест глубины Отсечение по трафарету Смешивание цветов Логические операции Dithering Определение видимости плоскостей

Компьютерная графика. Лекция 7

Page 27: Введение в использование шейдеров  OpenGL

ВХОДНЫЕ ДАННЫЕ ФРАГМЕНТНОГО ПРОЦЕССОРА

Встроенные varying-переменные Определенные разработчиком varying-

переменные Имена и типы должны совпадать с именами

varying-переменных, определенных в вершинном шейдере

Встроенные uniform-переменные Определенные разработчиком uniform-

переменные

Компьютерная графика. Лекция 7

Page 28: Введение в использование шейдеров  OpenGL

ЯЗЫК ПРОГРАММИРОВАНИЯ ШЕЙДЕРОВ GLSL

Page 29: Введение в использование шейдеров  OpenGL

ЦЕЛИ, ПРЕСЛЕДУЕМЫЕ ЯЗЫКОМ ШЕЙДЕРОВ OPENGL Обеспечение хорошей совместимости с

OpenGL Использование гибкости графических

ускорителей ближайшего будущего Предоставление независимости от

графического ускорителя Увеличение производительности Легкость использования Обеспечение актуальности языка в будущем Невмешательство в более высокие уровни

параллельной обработки Легкость разработки программ

Компьютерная графика. Лекция 7

Page 30: Введение в использование шейдеров  OpenGL

СОВМЕСТИМОСТЬ С OPENGL Язык GLSL разработан для использования

совместно с OpenGL Предоставляются программируемые

альтернативы стандартной функциональности OpenGL

Язык и программируемые им процессоры имеют как минимум ту же функциональность, какую они заменяют

Доступ к текущим состояниям OpenGL

Компьютерная графика. Лекция 7

Page 31: Введение в использование шейдеров  OpenGL

ИСПОЛЬЗОВАНИЕ ГИБКОСТИ АКСЕЛЕРАТОРОВ БЛИЖАЙШЕГО БУДУЩЕГО

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

Поддержка большого количества операций над скалярными и векторными величинами

Исчезла необходимость развитие частичных расширений функциональности OpenGL

Компьютерная графика. Лекция 7

Page 32: Введение в использование шейдеров  OpenGL

НЕЗАВИСИМОСТЬ ОТ ГРАФИЧЕСКОГО УСКОРИТЕЛЯ Предшествующие расширения

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

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

Производители ускорителей используют гибкость языка для внедрения новейших архитектур и технологий компиляции

Компьютерная графика. Лекция 7

Page 33: Введение в использование шейдеров  OpenGL

УВЕЛИЧЕНИЕ ПРОИЗВОДИТЕЛЬНОСТИ Современные компиляторы

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

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

потребоваться переписывание кода

Компьютерная графика. Лекция 7

Page 34: Введение в использование шейдеров  OpenGL

ЛЕГКОСТЬ ИСПОЛЬЗОВАНИЯ Легкость освоения языка

программистами, знакомыми с Си и Си++ Язык для программируемых процессоров

(в т.ч. и будущих) должен быть один и очень простой

Компьютерная графика. Лекция 7

Page 35: Введение в использование шейдеров  OpenGL

АКТУАЛЬНОСТЬ ЯЗЫКА В БУДУЩЕМ

При разработке GLSL были приняты во внимание особенности ранее созданных языков, таких как C и RenderMan

Язык тщательно стандартизован Ожидается, что ранее написанные программы

будут актуальны и через 10 лет

Компьютерная графика. Лекция 7

Page 36: Введение в использование шейдеров  OpenGL

НЕВМЕШАТЕЛЬСТВО В БОЛЕЕ ВЫСОКИЕ УРОВНИ ПАРАЛЛЕЛЬНОЙ ОБРАБОТКИ

Современные графические ускорители выполняют параллельную обработку вершин и фрагментов

Язык проектировался с учетом возможного распараллеливания обработки на более высоких уровнях

Компьютерная графика. Лекция 7

Page 37: Введение в использование шейдеров  OpenGL

ЛЕГКОСТЬ РАЗРАБОТКИ ПРОГРАММ

Язык шейдеров GLSL не поддерживает указатели и ссылки, параметры передаются по значению Нет проблемы с алиасингом Облегчается работа оптимизирующего

компилятора

Компьютерная графика. Лекция 7

Page 38: Введение в использование шейдеров  OpenGL

СВЯЗЬ С ЯЗЫКОМ C Точка входа в шейдерную программу –

функция void main(), с кодом внутри фигурных скобок

Константы, идентификаторы, операторы, выражения и предложения имеют много общего с языком C

Циклы, ветвление, вызовы функций также аналогичны с языком C

Многострочные комментарии

Компьютерная графика. Лекция 7

Page 39: Введение в использование шейдеров  OpenGL

ДОПОЛНЕНИЕ К ЯЗЫКУ C Векторные типы данных для чисел с

плавающей запятой, целых и булевых значений 2-х, 3-х и 4-х мерные векторы

Матричные типы данных для чисел с плавающей запятой Матрицы 2x2, 3x3 и 4x4

Дискретизаторы (sampler-ы) для доступа к текстурам

Спецификаторы attribute, uniform и varying входных и выходных переменных

Встроенные переменные состояния OpenGL Начинаются с префикса gl_- gl_FragColor, gl_Position

Множество встроенных функций

Компьютерная графика. Лекция 7

Page 40: Введение в использование шейдеров  OpenGL

ДОПОЛНЕНИЯ К ЯЗЫКУ ИЗ C++ Перегрузка функций Конструкторы Объявление переменных в произвольном

месте программы, а не только в начале блока

Тип bool Однострочные комментарии Функции должны быть объявлены до их

первого использования одним из следующих способовОпределением тела функцииОбъявлением прототипа

Компьютерная графика. Лекция 7

Page 41: Введение в использование шейдеров  OpenGL

НЕ ПОДДЕРЖИВАЕМЫЕ ВОЗМОЖНОСТИ C Отсутствие неявного приведения типов

float f = 0; // ошибкаfloat f = 0.0; // правильно

Нет поддержки указателей, строк, символов и операций над ними

Нет чисел с плавающей запятой двойной точности

Нет коротких, длинных и беззнаковых целых Нет union, enum и побитовых операторов Язык не файловый

Нет директив типа #include и других ссылок на имена файлов

Компьютерная графика. Лекция 7

Page 42: Введение в использование шейдеров  OpenGL

ПРОЧИЕ ОТЛИЧИЯ Вместо операторов приведения типов

используются конструкторы Входные и выходные параметры функций

передаются по значению Входные параметры функции обозначаются in Выходные параметры – out Входные и выходные одновременно – inout

Компьютерная графика. Лекция 7

Page 43: Введение в использование шейдеров  OpenGL

ПРИМЕР ПРОСТЕЙШЕГО ВЕРШИННОГО ШЕЙДЕРА

void main(){ /* то же самое, что и gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; но обеспечивает инвариантность преобразования координат */ gl_Position = ftransform(); gl_FrontColor = gl_Color;}

Компьютерная графика. Лекция 7

Page 44: Введение в использование шейдеров  OpenGL

ПРИМЕР ПРОСТЕЙШЕГО ФРАГМЕНТНОГО ШЕЙДЕРА

void main(){ gl_FragColor = gl_Color;}

Компьютерная графика. Лекция 7

Page 45: Введение в использование шейдеров  OpenGL

ЗАГРУЗКА, КОМПИЛЯЦИЯ И КОМПОНОВКА ШЕЙДЕРНЫХ ПРОГРАММ

Page 46: Введение в использование шейдеров  OpenGL

МОДЕЛЬ ПОДГОТОВКИ OPENGL-ШЕЙДЕРОВ

Приложение Исходный код шейдера

Компилятор

Объектный код шейдера

Компоновщик

Объектный код программы

Графический ускоритель

OpenGL API

Компьютерная графика. Лекция 7

Page 47: Введение в использование шейдеров  OpenGL

ШАГ 1 – СОЗДАНИЕ ШЕЙДЕРНОГО ОБЪЕКТА Для начала необходимо создать

шейдерный объект (структура данных драйвера OpenGL для работы с шейдером)

Для создания шейдерного объекта служит функция glCreateShaderObjectARB

Возвращенный данной функцией объект имеет тип GLhandleARB и используется приложением для дальнейшей работы с шейдерным объектом

Компьютерная графика. Лекция 7

Page 48: Введение в использование шейдеров  OpenGL

ПРИМЕР СОЗДАНИЯ ШЕЙДЕРА// создание вершинного шейдераGLhandleARB vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);

// создание фрагментного шейдераGLhandleARB fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

Компьютерная графика. Лекция 7

Page 49: Введение в использование шейдеров  OpenGL

ШАГ 2 – ЗАГРУЗКА ИСХОДНОГО КОДА ШЕЙДЕРА В ШЕЙДЕРНЫЙ ОБЪЕКТ Исходный код шейдера – массив строк,

состоящих из символов Каждая строка может состоять из нескольких

обычных строк, разделенных символом конца строки

Для передачи исходного кода приложение должно передать массив строк в OpenGL при помощи glShaderSourceARB

Компьютерная графика. Лекция 7

Page 50: Введение в использование шейдеров  OpenGL

ПРИМЕР ЗАГРУЗКИ ИСХОДНОГО КОДА В ШЕЙДЕРНЫЙ ОБЪЕКТ

const GLcharARB shaderSource1[] = “исходный код шейдера - начало”;const GLcharARB shaderSource2[] = “исходный код шейдера - окончание”;

GLcharARB const * shaderSources[] = {

shaderSource1,shaderSource2

};

glShaderSourceARB(vertexShader, 2, shaderSources, NULL);

const GLcharARB shaderSource1[] = “исходный код шейдера - начало”;const GLcharARB** pShaderSource = &shaderSource;

glShaderSourceARB(vertexShader, 1, pShaderSource, NULL);

В случае, когда исходный код находится в одной строке, задача слегка упрощается:

Компьютерная графика. Лекция 7

Page 51: Введение в использование шейдеров  OpenGL

ШАГ 3 – КОМПИЛЯЦИЯ ШЕЙДЕРНОГО ОБЪЕКТА

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

Скомпилированные шейдерные объекты могут быть в дальнейшем связаны с программным объектом, для ее дальнейшей компоновки

Компиляция шейдерного объекта осуществляется при помощи функции glCompileShaderARB

Компьютерная графика. Лекция 7

Page 52: Введение в использование шейдеров  OpenGL

ПРИМЕР КОМПИЛЯЦИИ ШЕЙДЕРНОГО ОБЪЕКТА

glCompileShaderARB(shader);

// проверяем успешность компиляцииGLint compileStatus;glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compileStatus);if (compileStatus != GL_TRUE){ printf(“Shader compilation error”); return 0;}

Компьютерная графика. Лекция 7

Page 53: Введение в использование шейдеров  OpenGL

ШАГ 4 – СОЗДАНИЕ ПРОГРАММНОГО ОБЪЕКТА Программный объект включает в себя

один или более шейдеров и заменяет собой часть стандартной функциональности OpenGL

Программный объект создается при помощи функции glCreateProgramObjectARB

Возвращенный данной функцией программный объект имеет тип GLhandleARB и может быть использован для дальнейшей работы с программным объектом

Компьютерная графика. Лекция 7

Page 54: Введение в использование шейдеров  OpenGL

ПРИМЕР СОЗДАНИЯ ПРОГРАММНОГО ОБЪЕКТА

GLhandleARB program = glCreateProgramObjectARB();

Компьютерная графика. Лекция 7

Page 55: Введение в использование шейдеров  OpenGL

ШАГ 5 – СВЯЗЫВАНИЕ ШЕЙДЕРНЫХ ОБЪЕКТОВ С ПРОГРАММНЫМ ОБЪЕКТОМ Приложение может использовать

несколько программных объектов, собранных из разных шейдеров

Для указания OpenGL, какие шейдеры с данной программой используются, служит функция glAttachObjectARB, выполняющая присоединение шейдерного объекта к программному объекту

Компьютерная графика. Лекция 7

Page 56: Введение в использование шейдеров  OpenGL

ПРИМЕР СВЯЗЫВАНИЯ ШЕЙДЕРНЫХ ОБЪЕКТОВ С ШЕЙДЕРНОЙ ПРОГРАММОЙ

GLhandleARB program;GLhandleARB vertexShader;GLhandleARB fragmentShader;

// …

glAttachObjectARB(program, vertexShader);

glAttachObjectARB(program, fragmentShader);

Компьютерная графика. Лекция 7

Page 57: Введение в использование шейдеров  OpenGL

ШАГ 6 – КОМПОНОВКА ШЕЙДЕРНОЙ ПРОГРАММЫ После связывания скомпилированных

шейдерных объектов с программным объектом программу необходимо скомпоновать

Скомпонованный программный объект можно использовать для включения в процесс рендеринга

Компоновка программы осуществляется при помощи функции glLinkProgramARB

Компьютерная графика. Лекция 7

Page 58: Введение в использование шейдеров  OpenGL

ПРИМЕР КОМПОНОВКИ ПРОГРАММНОГО ОБЪЕКТА

glLinkProgramARB(program);

GLint linkStatus;glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linkStatus);

if (linkStatus != GL_TRUE){ printf(“Program linking error”);}

Компьютерная графика. Лекция 7

Page 59: Введение в использование шейдеров  OpenGL

ШАГ 7 – ВАЛИДАЦИЯ ПРОГРАММНОГО ОБЪЕКТА Необязательный шаг, позволяющий

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

причинах неэффективной работы шейдерной программы

Проверка корректности скомпонованной программы осуществляется при помощи функции glValidateProgramARB

Компьютерная графика. Лекция 7

Page 60: Введение в использование шейдеров  OpenGL

ПРИМЕР ВАЛИДАЦИИ ШЕЙДЕРНОЙ ПРОГРАММЫ

void Validate(){ // ...

glValidateProgramARB(program);

GLint validationStatus; glGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &validationStatus);

PrintInfoLog(program)

if (validationStatus != GL_TRUE) { return; }

// ...}

void PrintInfoLog(GLhandleARB object){ GLcharARB buffer[10000]; GLsizei length; glGetInfoLogARB(object, sizeof(buffer) - 1, &length, buffer); printf(“%s”, buffer);}

Компьютерная графика. Лекция 7

Page 61: Введение в использование шейдеров  OpenGL

ШАГ 8 – УСТАНОВКА ШЕЙДЕРНОЙ ПРОГРАММЫ КАК ЧАСТЬ ТЕКУЩЕГО СОСТОЯНИЯ OPENGL Приложение может скомпоновать одну

или несколько шейдерных программ Каждая программа может реализовывать тот

или иной способ рендеринга Данные программы могут быть

установлены в текущее состояние для рендеринга при помощи функции glUseProgramObjectARB При этом стандартные механизмы

рендеринга вершин и/или фрагментов будут заменены на определенные пользователем

Компьютерная графика. Лекция 7

Page 62: Введение в использование шейдеров  OpenGL

ПРИМЕР УСТАНОВКИ ПРОГРАММНОГО ОБЪЕКТА

// делаем программный объект активнымglUseProgramObjectARB(program);

// выполняем настройку программного объекта и рендеринг объектов// ...

// переключаемся на стандартный механизм рендерингаglUseProgramObjectARB(NULL);

Компьютерная графика. Лекция 7

Page 63: Введение в использование шейдеров  OpenGL

УДАЛЕНИЕ ПРОГРАММ И ШЕЙДЕРОВ Ставшие ненужными шейдерные и

программные объекты необходимо удалить при помощи функции glDeleteObjectARB Шейдерные объекты, с помощью которых

была скомпонована шейдерная программа можно удалять – программный объект при этом сохранит работоспособность

Компьютерная графика. Лекция 7

Page 64: Введение в использование шейдеров  OpenGL

ПРИМЕР УДАЛЕНИЯ ШЕЙДЕРНЫХ И ПРОГРАММНЫХ ОБЪЕКТОВ

glDeleteObjectARB(program);glDeleteObjectARB(vertexShader);glDeleteObjectARB(fragmentShader);

Компьютерная графика. Лекция 7

Page 65: Введение в использование шейдеров  OpenGL

ПЕРЕДАЧА ПАРАМЕТРОВ В ШЕЙДЕРНУЮ ПРОГРАММУ

Page 66: Введение в использование шейдеров  OpenGL

ПЕРЕДАЧА ЗНАЧЕНИЙ UNIFORM-ПЕРЕМЕННЫХ В ШЕЙДЕРНУЮ ПРОГРАММУ Приложение может задать значение

uniform-переменной программного объекта с заданным расположением при помощи функции glUniformARB Программный объект должен быть

предварительно сделан активным Расположение uniform-переменной по ее

имени можно получить при помощи функции glGetUniformLocationARB

Компьютерная графика. Лекция 7

Page 67: Введение в использование шейдеров  OpenGL

ПРИМЕР ПЕРЕДАЧИ UNIFORM-ПЕРЕМЕННОЙ В ШЕЙДЕР

// делаем программный объект активнымglUseProgramObjectARB(program);

// получаем расположение uniform-переменной phase (предполагается, что данная переменная объявлена в одном из шейдеров с квалификатором uniform)GLint phaseLocation = glGetUniformLocationARB(program, "phase");

// задаем значение данной переменной (предполагается, что переменная имеет тип float (суффикс 1f в имени функции glUniform*ARB)glUniform1fARB(phaseLocation, 0.8f);

// деактивируем шейдерную программуglUseProgramObjectARB(NULL);

Компьютерная графика. Лекция 7

Page 68: Введение в использование шейдеров  OpenGL

ПЕРЕДАЧА ATTRIBUTE-ПЕРЕМЕННЫХ ШЕЙДЕРНОЙ ПРОГРАММЕ Значение attribute-переменной с

известным расположением может быть передано шейдеру при помощи функции glVertexAttrib*ARB внутри glBegin()/glEnd() перед вызовом glVertex()

Целый массив атрибутов вершин может быть передан вершинному шейдеру при помощи функции glVertexAttribPointerARB

Узнать расположение attribute-переменной можно при помощи функции glGetAttribLocationARB

Компьютерная графика. Лекция 7

Page 69: Введение в использование шейдеров  OpenGL

ПРИМЕР ПЕРЕДАЧИ ЗНАЧЕНИЯ ATTRIBUTE-ПЕРЕМЕННОЙ ОТДЕЛЬНО ВЗЯТОЙ ВЕРШИНЫ

// получаем расположение атрибута vertex2GLint vertex2Location = glGetAttribLocationARB(program, "vertex2");

// делаем программный объект активнымglUseProgramObjectARB(program);

glBegin(GL_TRIANGLES); // задаем значение attribute-переменной vertex2, объявленной как vec3 glVertexAttrib3fARB(vertex2Location, 0, 0.5f, 1); glVertex3f(0, 0, 0);

glVertexAttrib3fARB(vertex2Location, 2, 0.5f, 1); glVertex3f(0, 1, 0);

glVertexAttrib3fARB(vertex2Location, 3, 0.5f, 1); glVertex3f(0, 0, 1);glEnd();glUseProgramObjectARB(NULL);

Компьютерная графика. Лекция 7

Page 70: Введение в использование шейдеров  OpenGL

ПРИМЕР ПЕРЕДАЧИ МАССИВА ATTRIBUTE-ПЕРЕМЕННЫХ ШЕЙДЕРУ

// получаем расположение атрибута vertex2GLint vertex2Location = glGetAttribLocationARB(program, "vertex2");

// делаем программный объект активнымglUseProgramObjectARB(program);

// задаем параметры массива атрибутов и массива вершин (в данном случае attribute-переменная vertex2 объявлена как vec3)glVertexAttribPointerARB(vertex2Location, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &g_shapeVertices[0].x1);glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &g_shapeVertices[0]);

// разрешаем доступ к массивам вершин и атрибутовglEnableVertexAttribArrayARB(vertex2Attribute);glEnableClientState(GL_VERTEX_ARRAY);

// рисуем массив примитивовglDrawArrays(GL_LINE_LOOP, 0, NUMBER_OF_VERTICES);

// запрещаем доступ к массивам вершин и атрибутовglDisableVertexAttribArrayARB(vertex2Attribute);glDisableClientState(GL_VERTEX_ARRAY);

// делаем программу неактивнойglUseProgramObjectARB(NULL);

Компьютерная графика. Лекция 7

Page 71: Введение в использование шейдеров  OpenGL

ОСНОВЫ ЯЗЫКА ПРОГРАММИРОВАНИЯ ШЕЙДЕРОВ OPENGL

Page 72: Введение в использование шейдеров  OpenGL

ТИПЫ ДАННЫХ GLSL поддерживает следующие типы

данных Скалярные типы Векторы Матрицы Дискретизаторы (samplers) Структуры Массивы Тип void

Компьютерная графика. Лекция 7

Page 73: Введение в использование шейдеров  OpenGL

СКАЛЯРНЫЕ ТИПЫ ДАННЫХ float – целое число с плавающей запятой

float f; float g, h = 2.4; float scale = 3.0;

int – целое число (как минимум 16 разрядов) int i = 0x18; int numberOfTextures = 5; Особенности: нет побитовых операций, не происходит

переполнения или исчезновения значащих разрядов bool – булева переменная

bool pointIsOutsideThePlane; bool overflow; Конструкции if-else принимают только булевы значения

Компьютерная графика. Лекция 7

Page 74: Введение в использование шейдеров  OpenGL

ВЕКТОРНЫЕ ТИПЫ ДАННЫХ Векторы чисел c плавающей запятой

vec2, vec3, vec4 vec3 normal; vec4 color = vec4(0.3, 0.1, 0.2, 1.0);

Векторы целых чисел ivec2, ivec3, ivec4

ivec3 v(3, 2, 1); Векторы булевых значений

bvec2, bvec3, bvec4 bvec2 usage(true, false); bvec3 intersectionFlags;

Компьютерная графика. Лекция 7

Page 75: Введение в использование шейдеров  OpenGL

АДРЕСАЦИЯ ЭЛЕМЕНТОВ ВЕКТОРА По индексам

pos[3] = 5.0; По именам

Вектор рассматривается как координаты или направление: x, y, z, w position.z -= 1.0;

Вектор рассматривается как значение цвета: r, g, b, a gl_Color.g = 0.1;

Вектор рассматривается как координаты текстуры: s, t, p, q gl_TexCoord[1].s = 0.4;

Компьютерная графика. Лекция 7

Page 76: Введение в использование шейдеров  OpenGL

МАТРИЦЫ В GLSL поддерживаются встроенные

матрицы из чисел с плавающей запятой mat2 mat3 mat4

Матрицу можно рассматривать как массив столбцов векторов mat4 transform;

vec4 col2 = transform[2]; // третий столбец матрицы

Компьютерная графика. Лекция 7

Page 77: Введение в использование шейдеров  OpenGL

ДИСКРЕТИЗАТОРЫ В стандарте OpenGL не определено, в каком

виде будут реализованы текстурные модули

Доступ к текстурному объекту (выборка из текстуры) осуществляется при помощи дискретизатора (sampler)

Типы дискретизаторовsampler1Dsampler2Dsampler3DsamplerCubesampler1DShadowsampler2DShadow

Компьютерная графика. Лекция 7

Page 78: Введение в использование шейдеров  OpenGL

СТРУКТУРЫ Объявление структуры похоже на их

объявление в языке Cstruct LightSource

{ vec3 position; vec3 color;};

LightSource light1; Структуры могут быть объявлены внутри

других структур В состав структур могут входить массивы Битовые поля не поддерживаются

Компьютерная графика. Лекция 7

Page 79: Введение в использование шейдеров  OpenGL

МАССИВЫ Язык допускает создание массивов любых

типов vec4 points[10]; // массив из 10 элементов

(индексы от 0 до 9)points[3].x = 3.0; // ссылка на четвертый элемент

Компьютерная графика. Лекция 7

Page 80: Введение в использование шейдеров  OpenGL

ОБЪЯВЛЕНИЕ МАССИВОВ БЕЗ УКАЗАНИЯ РАЗМЕРОВ Допускается объявлять массивы без указания

размера, если выполняется одно из условий:Перед ссылкой на массив он объявлен еще раз с

указанием размера того же типа vec4 points[]; // размер неизвестен

vec4 points[10]; // размер 10 элементовvec4 points[]; // ошибка – размер уже определенvec4 points[20]; // ошибка – размер уже определен

Индексы, ссылающиеся на массив – константы времени компиляции vec4 points[]; // размер неизвестен

points[3].z = 0.3; // размер – 4 элементаpoints[5].y = 3.4; // размер – 6 элементов

Компьютерная графика. Лекция 7

Page 81: Введение в использование шейдеров  OpenGL

ТИП VOID Используется для указания, что функция

не возвращает никакого значения void main()

{…}

Компьютерная графика. Лекция 7

Page 82: Введение в использование шейдеров  OpenGL

ОБЪЯВЛЕНИЯ И ОБЛАСТЬ ВИДИМОСТИ Переменные могут объявляться по мере

необходимости (как в C++), а не в начале блока

Область видимости ограничена блоком, в котором переменная была объявлена Исключение – нельзя объявлять переменные

внутри оператора if Область видимости переменной, объявленной

в операторе for заканчивается в конце тела цикла

Компьютерная графика. Лекция 7

Page 83: Введение в использование шейдеров  OpenGL

СОГЛАСОВАНИЕ И ПРЕОБРАЗОВАНИЕ ТИПОВ Язык GLSL строго типизирован

Типы аргументов, передаваемых в функцию, должны соответствовать типу формальных параметров

Типы аргументов операторов должны соответствовать требованиям конкретного оператора

Строгая типизация позволяет избежать неоднозначностей при использовании перегруженных функций

Компьютерная графика. Лекция 7

Page 84: Введение в использование шейдеров  OpenGL

ИНИЦИАЛИЗАТОРЫ Инициализация может быть совмещена

вместе с объявлением переменнойfloat a, b = 3.0, c;

Константные переменные должны быть обязательно инициализированыconst int size = 4;

Attribute, uniform и varying-переменные при объявлении нельзя инициализироватьattribute float temparature;uniform int size;varying float transparency;

Компьютерная графика. Лекция 7

Page 85: Введение в использование шейдеров  OpenGL

ИНИЦИАЛИЗАЦИЯ СОСТАВНЫХ ТИПОВ Для инициализации составных типов

используются конструкторыvec4 v = vec4(1.0, 2.0, 3.0, 4.0);vec4 v;

v = vec4(1.0, 2.0, 3.0, 4.0);mat2 m(1.0, 2.0, 3.0, 4.0); // элементы матрицы

перечисляются по столбцам Дискретизаторы не имеют конструкторов Возможно инициализация структур с

помощью конструкторовЭлементы перечисляются в порядке их

объявления в структуре

Компьютерная графика. Лекция 7

Page 86: Введение в использование шейдеров  OpenGL

СПЕЦИФИКАТОРЫ ПЕРЕМЕННЫХ attribute

Используется для объявления переменной-атрибута вершины, значение которой задается приложением для каждой отдельно взятой вершины

uniform Используется для объявления переменной, значение

которой задается приложением для группы примитивов varying

Используется для объявления переменной, посредством которой вершинный шейдер передает результаты вычислений фрагментному шейдеру

const Константы времени компиляции, не видимые вне

шейдера, в котором объявлены

Компьютерная графика. Лекция 7

Page 87: Введение в использование шейдеров  OpenGL

ПЕРЕМЕННЫЕ БЕЗ СПЕЦИФИКАТОРОВ Переменные в глобальной области

видимости, объявленные без спецификаторов могут использоваться совместно шейдерами одного типа, скомпонованными в одну программу

Время существования таких переменных ограничено одним запуском шейдера

Понятие «статических переменных» отсутствует Сохранение значения переменной между

запусками шейдера препятствовало бы параллельной обработке вершин и фгагментов

Компьютерная графика. Лекция 7

Page 88: Введение в использование шейдеров  OpenGL

ПОСЛЕДОВАТЕЛЬНОЕ ВЫПОЛНЕНИЕ Программа на языке шейдеров OpenGL

выполняется последовательно Точка входа в шейдер – функция void main()

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

Операторы for, while, do-while огранизуют циклическое выполнение

Условное выполнение обеспечивается операторами if-else и оператором ?: В операторе ?: типы 2-го и 3-го операндов должны

совпадать Оператор discard может запретить запись

фрагмента в кадровый буфер Операторы goto и switch отсутствуют

Компьютерная графика. Лекция 7

Page 89: Введение в использование шейдеров  OpenGL

ФУНКЦИИ, ОПРЕДЕЛЯЕМЫЕ ПОЛЬЗОВАТЕЛЕМ Функции объявляются аналогично C++ Допускается перегрузка функций Более строгий контроль над типами входных и

выходных параметров Запрещен явный или косвенный рекурсивный вызов

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

спецификаторы in – аргумент копируется при входе out – аргумент копируется при выходе inout – аргумент копируется как при входе, так и при

выходе К аргументам может применяться спецификатор const

не применим к out и inout-параметрам

Компьютерная графика. Лекция 7

Page 90: Введение в использование шейдеров  OpenGL

ПРИМЕРЫ ОБЪЯВЛЕНИЯ ФУНКЦИЙvoid ComputeCoord(in vec3 normal, vec3 tangent, inout vec3 coord);vec3 ComputeCoord(const vec3 normal, vec3 tangent, in vec3 coord);

Компьютерная графика. Лекция 7

Page 91: Введение в использование шейдеров  OpenGL

ВСТРОЕННЫЕ ФУНКЦИИ В языке GLSL есть обширный набор

встроенных функций Полный набор встроенных функций можно

найти в спецификации языка Любая из встроенных функций может

быть переопределена в шейдере

Компьютерная графика. Лекция 7

Page 92: Введение в использование шейдеров  OpenGL

ОПЕРАЦИИ Операции в основном объявляются

аналогично операциям в языке C Отсутствуют побитовые операции Многие операции применимы как к

скалярным, так и к векторным операндам

Компьютерная графика. Лекция 7

Page 93: Введение в использование шейдеров  OpenGL

ОБРАЩЕНИЕ К КОМПОНЕНТАМ ВЕКТОРОВ И SWIZZLING

При обращении к элементам векторов можно перечислять компоненты, к которым проводится обращение vec4 v4;

vec4 v41 = v4.rgba;vec3 v3 = v4.rgb;v4.b = 4.3;v4.yx = v4.xy;v4.xy = v3.rr;

Компьютерная графика. Лекция 7

Page 94: Введение в использование шейдеров  OpenGL

ПОКОМПОНЕНТНЫЕ ОПЕРАЦИИ Если к вектору применяется какой-либо

оператор, операция выполняется так же, как если бы она выполнялась над каждым компонентом вектора в отдельностиvec3 v, u;

float f;v = u + f; // v.x = u.x + f; v.y = u.y + f; v.z = u.z + f;

vec2 v, y, w;v = y + w; // v.x = y.x + w.x; v.y = y.y + w.y;

Исключение – умножение вектора на матрицу или матрицы на вектор производит математическое, а не покомпонентное умножение

Компьютерная графика. Лекция 7

Page 95: Введение в использование шейдеров  OpenGL

ПРЕПРОЦЕССОР Поддерживаются директивы

препроцессора #define, #undef, #if, #ifdef, #ifndef, #else,

#elif, #defined, #error, #line, #pragma Имеется набор встроенных макросов

__LINE__, __FILE__, __VERSION__

Компьютерная графика. Лекция 7

Page 96: Введение в использование шейдеров  OpenGL

ОБРАБОТКА ОШИБОК Некоторые ошибки в процессе

компиляции могут быть не замечены Невозможен полный контроль над

использованием неинициализированных переменных

Программы, содержащие такие ошибки по-разному могут выполняться на разных платформах Спецификация языка не гарантирует

корректное выполнение программ, в которых присутствует обращение к неинициализированным переменным

Компьютерная графика. Лекция 7

Page 97: Введение в использование шейдеров  OpenGL

ПРАКТИЧЕСКОЕ ИСПОЛЬЗОВАНИЕ ШЕЙДЕРОВ

Page 98: Введение в использование шейдеров  OpenGL

ПРОСТЕЙШИЙ ПРИМЕР ИСПОЛЬЗОВАНИЯ ШЕЙДЕРОВ Разработаем вершинный и фрагментный

шейдеры, выполняющие базовые преобразования вершин и фрагментов

Простейший вершинный шейдер будет выполнять преобразование вершин в пространство координат канонический объем Сделать это можно при помощи встроенной

функции ftransform() Простейший фрагментный шейдер будет

задавать константное значение цвета фрагмента

Компьютерная графика. Лекция 7

Page 99: Введение в использование шейдеров  OpenGL

ПРИМЕР// Простейший вершинный шейдерvoid main(){ // аналогично gl_Vertex = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = ftransform();}

// Простейший фрагментный шейдерvoid main(){ gl_FragColor = vec4(0.5, 0.2, 0.5, 1.0);}

Компьютерная графика. Лекция 7

Page 100: Введение в использование шейдеров  OpenGL

ПРОСТЕЙШЕЕ ДИФФУЗНОЕ ОСВЕЩЕНИЕ

Вспомним формулу Ламберта для расчета диффузной составляющей освещения

Id – интенсивность рассеянного света Is – интенсивность падающего света s – направление на источник света m – направление нормального вектора в

точке поверхности

0,max

msmsII dsd

Компьютерная графика. Лекция 7

Page 101: Введение в использование шейдеров  OpenGL

ОСОБЕННОСТИ РЕАЛИЗАЦИИ НА GLSL Стандартная модель освещения OpenGL

производит вычисления освещенности лишь в вершинах примитивов, интерполируя полученный свет вдоль фрагментов примитива На практике объекты выглядят довольно

некрасиво При помощи языка шейдеров GLSL можно

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

Компьютерная графика. Лекция 7

Page 102: Введение в использование шейдеров  OpenGL

ПРИНЦИП РАБОТЫm1

m2 m

3

s2

s1

s3

Вершинный шейдер вычисляет необходимые векторы в вершинах примитиваВ процессе примитива растеризации значения, вычисленные вершинным шейдером интерполируются и передаются через varying-переменные фрагментному шейдеруФрагментшый шейдер вычисляет интенсивность диффузного освещения по формуле Ламберта, используя значения переданных varying-переменных

Компьютерная графика. Лекция 7

Page 103: Введение в использование шейдеров  OpenGL

ФУНКЦИИ ВЕРШИННОГО ШЕЙДЕРА Выполняет трансформацию вершин Вычисляет векторы s и m в вершинах

примитива Вычисленные векторы передаются через varying-

переменные фрагментному шейдеру Нововведения:

gl_ModelViewMatrix – матрица моделирования-вида gl_LightSource – массив структур, определяющих

характеристики встроенных источников света gl_NormalMatrix – матрица 3x3 для преобразования

нормалей – получается из glModelViewMatrix gl_Normal – вектор нормали, связанный с вершиной

Компьютерная графика. Лекция 7

Page 104: Введение в использование шейдеров  OpenGL

ИСХОДНЫЙ КОД ВЕРШИННОГО ШЕЙДЕРА// Varying-переменные, передаваемые от вершинного шейдера во фрагментныйvarying vec3 L; // направление на источник светаvarying vec3 N; // направление вектора нормали

void main(void){ // вычисляем координаты вершины в системе координат наблюдателя // там же задается и положение источника света vec3 p = vec3(gl_ModelViewMatrix * gl_Vertex);

// вычисляем направление на источник света L = normalize(gl_LightSource[0].position.xyz - p);

// трансформируем вектор нормали в систему координат наблюдателя N = normalize(gl_NormalMatrix * gl_Normal);

// вычисляем позицию вершины – обязательный этап работы вершинного шейдера gl_Position = ftransform();}

Компьютерная графика. Лекция 7

Page 105: Введение в использование шейдеров  OpenGL

ФУНКЦИИ ФРАГМЕНТНОГО ШЕЙДЕРА Нормализация вектора нормали и

направления на источник светаНеобходимо, т.к. при интерполяции векторов

нормали и источника света они перестают быть единичными

Используется функция встроенная функция normalize()

Вычисление диффузной составляющей освещения по формуле ЛамбертаИспользуется встроенная функция dot() для

вычисления скалярного произведения и функция max() для определения максимального из 2-х значений

Формирование цвета фрагмента

Компьютерная графика. Лекция 7

Page 106: Введение в использование шейдеров  OpenGL

ИСХОДНЫЙ КОД ФРАГМЕНТНОГО ШЕЙДЕРА/* векторы нормали и направления на источник света, изменяющиеся при растеризации примитива */varying vec3 L;varying vec3 N;

void main (void){ // нормируем вектора, т.к. при интерполяции они перестают быть единичными vec3 N2 = normalize(N); vec3 L2 = normalize(L);

// вычисление диффузной составляющей освещения vec4 Idiff = vec4 ( 1.0, 1.0, 1.0, 1.0 ) * max(dot(N2,L2), 0.0);

// необходимый шаг – формирование цвета фрагмента gl_FragColor = Idiff;}

Компьютерная графика. Лекция 7

Page 107: Введение в использование шейдеров  OpenGL

РЕЗУЛЬТАТКомпьютерная графика. Лекция 7

Page 108: Введение в использование шейдеров  OpenGL

ДАЛЬНЕЙШИЕ УЛУЧШЕНИЯ Наложение текстуры для детализации

поверхности цветом Вычисление зеркальной составляющей

освещения Можно использовать формулу Фонга

Применение более одного источника света

Компьютерная графика. Лекция 7