Главная страница
Навигация по странице:

  • 5.5. Буфер кадра

  • 5.6. Первое приложение

  • 6.1. Свойства шейдеров

  • 6.2. Виды шейдеров

  • 6.3. Язык GLSL

  • К. В. Рябинин вычислительная геометрия и алгоритмы компьютерной графики


    Скачать 1.44 Mb.
    НазваниеК. В. Рябинин вычислительная геометрия и алгоритмы компьютерной графики
    АнкорVychislitelnaya_geometriya_i_algoritmy_kompyuternoy_grafiki._Rabota_s_3D-grafikoy_sredstvami_OpenGL
    Дата28.04.2022
    Размер1.44 Mb.
    Формат файлаpdf
    Имя файлаVychislitelnaya_geometriya_i_algoritmy_kompyuternoy_grafiki._Rab.pdf
    ТипДокументы
    #503739
    страница4 из 8
    1   2   3   4   5   6   7   8
    5.4. Многопоточность графического приложения
    Отдельного внимания заслуживает вопрос многопоточности графического приложения. С целью оптимизации нагрузки вычисли- тельной системы имеет смысл вынести цикл (4) в отдельный поток, в особенности, если обрабатываемая сцена достаточно сложна. Идея в том, чтобы отделить визуальную часть от обработки команд пользо-
    37
    вателя (которая обычно выполняется в главном потоке приложения),
    тем самым обеспечив большую отзывчивость приложения.
    В зависимости от конкретной платформы и конкретного гра- фического API контекст может быть связан либо с процессом, либо с потоком. Например, в ОС Windows, GNU/Linux и OS X контекст
    OpenGL связан с процессом, и обращение к нему (т. е. вызов API
    OpenGL) может быть осуществлён из любого потока. В iOS, напро- тив, контекст связан с потоком, а для разделения одних и тех же гра- фических ресурсов между разными потоками существует специаль- ный механизм объединения нескольких контекстов в группу.
    Одни стандарты графических API предусматривают встроен- ные средства потокобезопасного использования, но другие – нет. Так,
    например, в Direct3D есть возможность осуществлять одновремен- ные обращения к API функциям из разных потоков, а OpenGL требу- ет организации монопольного доступа к графическим ресурсам. При этом, например, в системе OS X в контекст OpenGL встроен мьютекс,
    обеспечивающий синхронизацию, но захват и освобождение этого мьютекса программист должен осуществлять в явном виде. В систе- ме iOS, напротив, в контексте OpenGL (точнее, OpenGLES, так как в iOS используется версия OpenGL для мобильных устройств) встро- енных средств синхронизации нет, и для организации монопольно- го доступа к общим графическим ресурсам программисту требуется оформлять критические секции полностью самостоятельно.
    В целях упрощения подачи материала в данном пособии на практике не рассматриваются вопросы организации многопоточных графических приложений. Во всех приведённых примерах вся рабо- та с графическими ресурсами, включая их загрузку и изменение, бу- дет производится в главном потоке приложения.
    5.5. Буфер кадра
    В процессе работы графического конвейера порождается некоторое множество данных, которые необходимо сохранять для дальнейшего использования. Это не только финальное изображение,
    но и различная сервисная информация, которая может быть нужна
    38
    как самому конвейеру, так и приложению (для реализации дополни- тельной логики). Порождаемые данные сохраняются в специальные структуры, называемые буферами. Как правило, каждый буфер представляет собой матрицу точек, по размеру равную итоговому растру, структура элементов которой зависит от назначения буфера.
    Например, для сохранения итогового изображения используется
    буфер цвета
    (англ.
    Color Buffer
    ), в ячейках которого сохраняются цвета, закодированные в соответствии с некоторой цветовой моде- лью (чаще всего RGB или RGBA). Другие буферы (служащие для хранения сервисной информации) будут рассмотрены позднее.
    За частью буферов чётко закреплено их назначение. Другие же могут быть использованы для сохранения произвольной инфор- мации, вычисляемой на конвейере, которая может быть нужна при- ложению для организации различных специальных эффектов. Такие буферы называются
    целями рендеринга
    (англ.
    Render Target
    ). Про- граммист сам определяет число и назначение целей рендеринга, а также принцип их заполнения.
    Перед началом работы, как правило, выполняется очистка каждого из буферов, т. е. заполнение их некоторым начальным набором значений.
    Все используемые буферы объединяются в одну агрегирую- щую структуру данных, называемую
    буфером кадра
    (англ.
    Frame
    Buffer
    ). В одном приложении может быть произвольное число бу- феров кадра, которые, как правило, создаются на этапе подготовки графических ресурсов, а затем переключаются по необходимости (в соответствии с логикой приложения при подготовке каждого следу- ющего кадра). В каждый момент времени активным буфером кадра может быть только один.
    5.6. Первое приложение
    Изучение низкоуровневых средств работы с графикой пред- лагается начать со стандарта OpenGL. Данный стандарт описывает лишь работу с графикой (в рамках приведённого ранее графического конвейера), и ничего более. Операции, связанные с созданием окна,
    39
    обработкой команд пользователя, загрузкой внешних мультимедий- ных ресурсов (изображений и 3D-моделей) и т. п. этим стандартом не специфицируются. Для упрощения создания графического кон- текста, поверхности рендеринга, обработки команд пользователя и отображения результата под управлением конкретной ОС предлага- ется использовать мультиплатформенные библиотеки GLEW [7] и
    GLFW [8].
    Библиотека GLEW предназначена для упрощения этапа ди- намической загрузки функций библиотеки, реализующей стандарт
    OpenGL. Библиотека GLFW предназначена для упрощения этапа создания окна с контекстом OpenGL и поверхностью рендеринга
    (независимым от конкретной ОС способом).
    Следует отметить, что стандарт OpenGL прошёл достаточно длинный путь развития, в ходе которого в нём, вместе с разви- тием элементной базы графических процессоров, появлялись и исчезали различные функции. В данном пособии рассматривается
    OpenGL версии 3.3+ (для настольных компьютеров). На сегодняш- ний день эта версия полностью поддерживается большинством настольных компьютеров под управлением всех популярных ОС.
    На мобильных устройствах под управлением iOS и Android исполь- зуется OpenGLES 2.0 и 3.0, «облегчённая» модификация OpenGL
    (ввиду ограничений аппаратуры). Для создания графических Web- приложений используется WebGL, основанный на OpenGLES 2.0
    (для организации совместимости и с настольными компьютерами, и с мобильными устройствами). Однако в отношении общей логики работы настольная, мобильная и Web-ориентированная версии эквивалентны. Таким образом, если читатель освоит наиболее пол- нофункциональный стандарт (настольную версию), ему не составит труда в дальнейшем перейти и на облегчённые.
    Заготовку приложения (на языке С++), на основе ко- торой можно будет реализовывать описанные далее мето- ды и алгоритмы, можно скачать в сети Интернет по адресу https://github.com/icosaeder/cg-tutorial.git.
    40

    В целях увеличения наглядности код заготовки разбит на функции, соответствующие шагам приведённого выше общего алгоритма работы графического приложения.
    Стандарт OpenGL предполагает чисто процедурный стиль программирования (хотя имеет биндинги в самые разные языки программирования, включая объектно-ориентированные и функци- ональные). Поэтому все графические ресурсы (например, объекты сцены) в нём представлены в виде целочисленных знаковых или беззнаковых дескрипторов. Для модификации каждого из них используется «политика активации»: существуют специальные функции, принимающие в качестве параметра дескриптор и де- лающие соответствующий ресурс активным, а также функции модификации каких-либо параметров активного ресурса.
    Следует обратить внимание на то, что стандарт OpenGL и вспомогательные библиотеки (такие как GLEW и GLFW) при- держиваются единого соглашения о именовании функций, типов данных и констант. Все функции и типы названы в
    «верблюжьем
    регистре»
    (англ.
    Camel Case
    ), начиная с префикса, отражающего их принадлежность к конкретной библиотеке. У функций префикс пишется маленькими буквами, у типов – большими. Константы записаны в
    «заглавном змеином регистре»
    (англ.
    Capitalized Snake
    Case
    ). Например, функция очистки буферов по маске называется glClear
    , тип маски:
    GLbitfield
    , константа маски буфера цвета:
    GL COLOR BUFFER BIT
    Работа графического конвейера OpenGL управляется маши- ной состояний. Она представляет собой набор свойств, значения которых можно изменять при помощи специальных функций. Бинар- ные свойства изменяются функциями glEnable
    (для включения) и glDisable
    (для выключения), принимающими в качестве парамет- ра константу, именующую свойство. Небинарные свойства изме- няются специальными функциями, как, например,
    glClearColor
    ,
    которая устанавливает значение для очистки буфера цвета.
    Машина состояний, так же как и графические ресурсы, свя- зана с контекстом. Таким образом, функции изменения машины со- стояний, так же как и функции активации и модификации ресурсов,
    41
    могут быть использованы в любом месте в приложении при условии наличия активного контекста.
    Приложение по указанной выше ссылке лишь создаёт окно с контекстом и поверхностью рендеринга OpenGL и закрашивает его синим цветов. Закраска достигается путём очистки буфера цвета. Бу- фер цвета создаётся автоматически при создании контекста как часть
    буфера кадра по умолчанию
    (англ.
    Default Frame Buffer
    ). В случае данного приложения (где создание контекста берёт на себя GLEW)
    ссылки на буфер кадра по умолчанию в явном виде нет. Тем не ме- нее он выставлен в качестве активного, поэтому все операции по из- менению – установка цвета для очистки, команда очистки и т. д. –
    касаются именно его.
    Задание:
    Подготовить рабочее пространство для дальнейшего изучения стандарта OpenGL: настро- ить компилятор C++ (или среду программирования)
    так, чтобы он успешно собрал описанное выше при- ложение.
    Подсказка:
    Требуется установить библиотеки GLEW, GLFW и
    OpenGL на используемую читателем операционную систему и на- строить доступ компилятора/линковщика к ним. В UNIX-подобных операционных системах установка может быть совершена при по- мощи используемого в конкретной ОС пакетного менеджера.
    42

    6. Шейдеры
    На первых этапах развития компьютерной графики конвейер был
    фиксированным
    (англ.
    Fixed Pipeline
    ), т. е. каждый из его этапов был реализован в соответствии с определённым наперёд заданным алгоритмом, а настройка конвейера производилась лишь изменением ограниченного набора параметров этих алгоритмов.
    Но современное графическое оборудование поддерживает полное переопределение некоторых этапов конвейера. Таким образом,
    фиксированный конвейер уступил место
    программируемому
    (англ.
    Programmable Pipeline
    ).
    Программируемый конвейер является значительно более гиб- ким инструментом для генерации изображений, поэтому современ- ные графические системы в большинстве своём используют именно его. Каждый из этапов конвейера переопределяется в отдельности путём подстановки на его место исполняемого модуля, называемого
    шейдером
    (англ.
    Shader
    ).
    Программируемыми являются не все этапы: в зависимости от графического оборудования и используемого графического API
    часть этапов должна быть определена программистом обязательно
    (не имеет реализации по умолчанию), часть имеет реализацию по умолчанию, но допускает переопределение, а часть фиксирована и управляется лишь машиной состояний.
    6.1. Свойства шейдеров
    Шейдеры иногда называют
    микропрограммами
    для этапов графического конвейера. Здесь приставка «микро» подчёркивает их малый размер: шейдер выполняет лишь узкоспециализированную задачу и для увеличения производительности конвейера должен быть по возможности освобождён от лишних действий. Конкретная задача и свойства шейдера определяются этапом конвейера, для которого он является исполнителем. Однако для всех шейдеров можно определить ряд общих свойств:
    43

    1. Автономность. Шейдер не является частью кода основного приложения и минимально зависит от него. Часто шейдеры входят в состав графического приложения в виде исходных ко- дов и компилируются во время выполнения непосредственно перед встраиванием в конвейер.
    2. Аппаратная поддержка. На современном оборудовании шей- деры выполняются на видеокарте, а их исполняемый модуль автоматически оптимизируется под архитектуру GPU.
    3. Специальный язык программирования. Шейдеры пишутся на некотором языке программирования, чаще всего в процедур- ной парадигме.
    4. Параллелизм по данным. Как правило, шейдеры в явном виде не поддерживают многопоточности, однако должны быть ре- ентерабельны на уровне всего своего кода, так как рассчитаны на многократный параллельный запуск с разными входными данными.
    5. Узкая специализация. Шейдер выполняет лишь один неболь- шой шаг на пути построения итогового изображения, его код должен быть минимален и очень хорошо оптимизирован, так как для получения одного кадра каждый шейдер, как правило,
    запускается многократно (на некоторых сценах число вызовов одного шейдера на кадр может достигать миллионов).
    Превращая фиксированный конвейер в программируемый,
    шейдеры обеспечивают целый ряд преимуществ:
    1. Единообразный механизм представления разнородных визу- альных эффектов.
    2. Высокую эффективность графического конвейера.
    3. Настраиваемость графического конвейера (вплоть до органи- зации адаптивности, когда в зависимости от конкретной кон- фигурации системы для одних и тех же эффектов автоматиче- ски выбираются шейдеры различной сложности, обеспечивая тем самым учёт возможностей конкретного оборудования).
    4. Децентрализацию кода.
    44

    5. Возможность переиспользования визуальных эффектов в раз- личных приложениях (так как шейдеры, как уже отмечалось,
    минимально зависят от использующего их приложения).
    Жизненный цикл шейдера может несколько отличаться в раз- ных графических API, однако различия незначительны, так как этот цикл обусловлен аппаратной организацией GPU:
    1. Загрузка исходного кода из файла или строковой константы.
    2. Компиляция «на лету» (т. е. во время выполнения основного приложения).
    3. Встраивание в конвейер (
    активация
    ).
    4. Множественное выполнение (шейдер выполняется ровно один раз для каждой сущности, обрабатываемой данной ступенью конвейера во время рендеринга кадра).
    5. Отсоединение от конвейера (
    деактивация
    ).
    6. Удаление из памяти.
    6.2. Виды шейдеров
    Как уже отмечалось выше, шейдеры классифицируются по со- ответствующей им ступени графического конвейера, и число под- держиваемых типов шейдеров зависит от конкретного графического оборудования.
    В данном пособии будут рассмотрены лишь два вида шей- деров, которые поддерживаются на сегодняшний день почти на любом оборудовании (включая мобильные устройства) –
    вершин-
    ные шейдеры
    (англ.
    Vertex Shader
    ) и
    фрагментные шейдеры
    (англ.
    Fragment Shader
    ).
    Схематично место указанных шейдеров в графическом кон- вейере показано на рис. 11.
    Вершинный шейдер – это микропрограмма, которая за один свой вызов обрабатывает одну вершину (из всего множества отправ- ленных в данный момент на графический конвейер). Задача вершин- ного шейдера – определить итоговые характеристики вершины, име- ющие значение для последующих этапов конвейера (например, по- ложение вершины в пространстве).
    45

    Рис. 11. Место вершинного и фрагментного шейдеров в графическом конвейере
    Фрагментный шейдер – это микропрограмма, которая за один свой вызов обрабатывает один фрагмент изображения, вычисляя его числовые характеристики (например, цвет). Фрагмент – это
    атомар-
    ная
    ячейка растра, принадлежащая объекту сцены. Значение число- вых характеристик соответствующей ячейки может быть перевычис- лено несколько раз в течение подготовки изображения из-за того,
    что объекты сцены могут накладываться друг на друга. Графический процессор автоматически подбирает фрагменты, соответствующие обрабатываемому в данный момент примитиву, и вызывает для каж- дого из них фрагментный шейдер.
    Следует отметить, что понятие фрагмента близко к понятию пикселя, но имеет два важных отличия:
    1. Число фрагментов в общем случае не равно числу пикселей,
    так как пиксель – ячейка итогового изображения, а фрагмент –
    ячейка растра, принадлежащая примитиву. В случае перекры- вающихся примитивов одна и та же ячейка растра будет со- ответствовать разным фрагментам. В случае наличия мест на экране, не занятых объектами, не всем ячейкам будут соответ- ствовать фрагменты.
    2. Фрагмент – всегда низкоуровневое физическое понятие, ато- марная ячейка растра, тогда как пиксель может быть понятием
    46

    логическим
    . Например, в контексте ретина-дисплеев [9] один пиксель состоит из четырёх и более фрагментов для организа- ции
    субпиксельной точности
    изображений.
    6.3. Язык GLSL
    Для написания шейдеров используются специализированные языки программирования, которые, как правило, характеризуются следующими свойствами:
    1. Процедурной парадигмой.
    2. Полнотой по Тьюрингу.
    3. Наличием специализированных типов данных и встроенных функций для работы с обрабатываемыми шейдером сущностя- ми.
    4. C-подобным синтаксисом.
    Каждый стандарт графического API описывает свой язык для разработки шейдеров (иногда даже несколько допустимых языков). В данном пособии будет рассмотрен язык GLSL (англ.
    Graphics Library Shading Language
    – язык шейдеров графической библиотеки), являющийся частью стандарта OpenGL.
    Как и стандарт OpenGL, язык GLSL имеет на сегодняшний день несколько версий, появившихся в результате его развития, и от версии к версии в языке происходили ощутимые изменения. Более того, стандарт OpenGLES описывает свою модификацию этого язы- ка – ESSL (англ.
    Embedded Systems Shading Language
    – язык шей- деров для встраиваемых систем). В данном пособии будут рассмат- риваться примеры GLSL версии 330 и выше, но будут также даны комментарии по совместимости с ESSL.
    Основной особенностью языка GLSL является наличие специ- альных типов данных и встроенных функций, облегчающих решение частых графических задач.
    Базовыми типами данных являются скаляры bool
    ,
    int и
    float
    . Числа с плавающей точкой двойной точности в общем случае не поддерживаются.
    47

    В языке ESSL для базовых типов float и
    int присутствуют
    квалификаторы точности
    (англ.
    Precision Qualifiers
    ):
    highp
    (вы- сокая точность),
    mediump
    (средняя точность) и lowp
    (низкая точ- ность). Конкретные параметры точности зависят от GPU. Выбран- ная точность определяет диапазон представимых значений. В языке
    GLSL квалификаторы точности отсутствуют, и точность по умолча- нию полагается максимальной.
    Из базовых типов строятся двух-, трёх- и четырёхкомпонент- ные векторы:
    bvec2
    ,
    bvec3
    ,
    bvec4
    – векторы с компонентами типа bool
    ;
    ivec2
    ,
    ivec3
    ,
    ivec4
    – векторы с компонентами типа int
    ;
    vec2
    ,
    vec3
    ,
    vec4
    – векторы с компонентами типа float
    Для векторов перегружены операции сложения, вычитания,
    умножения и деления. Все эти операции выполняются
    покомпо-
    нентно
    , за один такт графического процессора. Следует обратить внимание, что запись вида c
    =
    a
    *
    b;
    , где a
    ,
    b
    ,
    c
    векторы одинаковой размерности, приведёт к покомпонентному перемноже- нию (хотя в геометрии и линейной алгебре такого рода умножение для векторов не определено). Это же справедливо и относительно деления.
    Инициализация векторов осуществляется при помощи пере- груженных конструкторов, например:
    vec3 a = vec3(0.1, 0.2, 0.3);
    vec4 b = vec4(a, 0.4); // b =
    {
    0.1,0.2,0.3,0.4
    }
    vec2 c = vec2(a); // c =
    {
    0.1,0.2
    }
    vec3 d = vec3(1.0); // d =
    {
    1.0,1.0,1.0
    }
    Доступ к элементам можно осуществить как при помощи ин- декса (как у обычных массивов), так и при помощи
    мнемонических
    полей
    . Имеется три
    эквивалентных
    набора мнемонических полей:
    xyzw
    ,
    rgba и
    stpq
    . Они обеспечивают доступ к соответствующим компонентам вектора. Технического различия в том, какие поля ис- пользовать, нет; разное написание используется исключительно с це- лью увеличения читаемости кода (чтобы подчеркнуть логическое на- значение вектора). Записи следующего вида эквивалентны:
    vector[1] = 1.0;
    vector.y = 1.0;
    48
    vector.g = 1.0;
    vector.t = 1.0;
    Для получения субвектора либо изменения порядка компо- нентов могут (и с целью обеспечения эффективной работы должны)
    быть использованы т. н.
    коктейли
    (англ.
    Swizzling
    ) – одновременная запись множества мнемонических полей, идущих в определённом порядке. Например, для извлечения из данного вектора двухком- понентного, содержащего его компоненты
    y
    и
    z
    , должна быть использована запись вида vec2 vector2 = vector1.yz;
    Коктейли обеспечивают не только чтение, но и присваивание значений. Например, чтобы изменить порядок следования значений первых трёх компонентов вектора на обратный, можно воспользо- ваться записью vector.xyz = vector.zyx;
    Использование коктейлей рекомендуется всюду, где это воз- можно, так как оно позволяет оптимизировать доступ к векторным данным на этапе компиляции шейдера. Учитывая то, что графиче- ский процессор предназначен для эффективной работы с векторами,
    их использование также рекомендуется во всех возможных случаях.
    Следующими важными типами языка
    GLSL
    являются четырёх-, девяти- и шестнадцатикомпонентные матрицы mat2
    ,
    mat3
    ,
    mat4
    с элементами типа float
    . Для них, так же как и для векторов, перегружены операции сложения, вычитания (работа- ют покомпонентно) и умножения (работает по алгебраическим правилам). Операция деления не поддерживается. Кроме того, реа- лизована перегрузка умножения матрицы на вектор, работающая по алгебраическим правилам и интерпретирующая вектор как столбец.
    С точки зрения хранения матрица – это массив векторов- столбцов, т. е. к её элементам доступ может быть осуществлён по правилам адресации в двумерном массиве.
    В GLSL поддерживается описание массивов и структур в пол- ном соответствии со стандартом ANSI C. Элементами массивов и полями структур могут выступать любые поддерживаемые языком типы.
    49

    Для описания функций, не возвращающих никакого значения,
    используется тип void
    . Допустимо использование глобальных пе- ременных (доступ к которым есть из всех функций). Однако нет ни ссылочного типа, ни указателей (работа с динамической памятью не поддерживается).
    Управляющие структуры языка GLSL (циклы, условия, вызо- вы функций и т. п.) идентичны описанным в стандарте ANSI C.
    Для удобного и эффективного решения наиболее часто встре- чающихся математических задач в GLSL имеется целый ряд встро- енных функций. Наиболее важные и часто используемые функции приведены ниже.
    1. Функции работы с векторами (есть версии функций для векто- ров всех размерностей):
    1.1.
    dot(v1, v2)
    – скалярное произведение v1
    и v2 1.2.
    cross(v1, v2)
    – векторное произведение v1
    и v2 1.3.
    normalize(v)
    – нормировка v
    1.4.
    reflect(v1, v2)
    – отражение v1
    относительно v2 1.5.
    refract(v1, v2, r)
    – преломление v1
    относительно v2
    с коэффициентом преломления r
    1.6.
    length(v)
    – длина v
    1.7.
    distance(v1, v2)
    – расстояние между точками v1
    и v2 2. Функции работы с матрицами (есть версии функций для мат- риц всех размерностей):
    2.1.
    determinant(m)
    – определитель m
    2.2.
    transpose(m)
    – транспонирование m
    2.3.
    inverse(m)
    – обратная m
    3. Тригонометрические функции (есть векторные версии функ- ций, работающие покомпонентно):
    3.1.
    sin(a)
    ,
    cos(a)
    ,
    tan(a)
    – прямые функции от угла a
    ,
    заданного в радианах.
    3.2.
    asin(x)
    ,
    acos(x)
    ,
    atan(x)
    – обратные функции от ар- гумента x
    , возвращающие угол в радианах.
    3.3.
    radians(a)
    ,
    degrees(a)
    – перевод угла a
    из градусов в радианы и обратно.
    50

    4. Гиперболические функции (есть векторные версии функций,
    работающие покомпонентно):
    4.1.
    sinh(x)
    ,
    cosh(x)
    ,
    tanh(x)
    – прямые функции от ар- гумента x
    4.2.
    asinh(x)
    ,
    acosh(x)
    ,
    atanh(x)
    – обратные функции от аргумента x
    5. Прочие математические функции (есть векторные версии функций, работающие покомпонентно):
    5.1.
    pow(x, y)
    – возведение x
    в степень y
    5.2.
    exp(x)
    – экспонента x
    5.3.
    log(x)
    – натуральный логарифм x
    5.4.
    sqrt(x)
    – квадратный корень x
    5.5.
    abs(x)
    – модуль x
    5.6.
    sign(x)
    – сигнум x
    5.7.
    ceil(x)
    ,
    floor(x)
    ,
    round(x)
    – округление x
    в разные стороны.
    6. Функции выбора (есть векторные версии функций, работаю- щие покомпонентно):
    6.1.
    min(x, y)
    ,
    max(x, y)
    – минимум и максимум из x
    и y
    6.2.
    clamp(x, minVal, maxVal)
    – ограничение x
    снизу по minVal и сверху по maxVal
    6.3.
    mix(x, y, t)
    – линейная интерполяция от x
    до y
    по t
    6.4.
    smoothstep(x, y, t)
    – гладкая эрмитова интерполя- ция от x
    до y
    по t
    6.5.
    step(e, x)
    – пороговая функция, работающая по прин- ципу step
    (e, x) =
    {
    0,
    e > x,
    1,
    e
    ≤ x
    .
    Полный список поддерживаемых операций, так же как и бо- лее подробную справку по GLSL, можно получить в официальной документации [10].
    51

    1   2   3   4   5   6   7   8


    написать администратору сайта