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

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    1,62 Mb
  • Опубликовано:
    2011-06-16
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

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

 

 

 

 

 

 

 

 

 

 

 

 

 

ДИПЛОМНЫЙ ПРОЕКТ

На тему: «Разработка приложения для визуализации трехмерных сцен с использованием карт освещения и динамического освещения»

Введение

Цель описываемой работы - создать систему отрисовки 3D сцен с возможностью динамичнского освещения в реальном времени. Такую систему в среде разработки видеоигр (для которых, обычно, предназначаются такие продукты в первую очередь) принято называть «графическим движком» (graphic engine). Графический движок - является основной частью сложного комплекса для разработки игрового приложения, называемого «игровым движком».

Игровой движок (англ. game engine) - это центральный программный компонент компьютерных и видеоигр и других интерактивных приложений с графикой, обрабатываемой в реальном времени. Он обеспечивает основные технологии, упрощает разработку и часто даёт игре возможность запускаться на нескольких платформах, таких как игровые консоли и настольные операционные системы, например, GNU/Linux, Mac OS X и Microsoft Windows.

Словосочетание «игровой движок» подразумевает целый комплекс прикладных программ, включающий графический движок для 2D или 3D графики, физический движок, звук, набор инструментария, анимацию, искусственный интеллект, сетевой код, управление памятью и так далее. Строго говоря, все части кода, написанные программистами при разработке игры, являются компонентами движка. Игровой процесс (gameplay) определяется функциями, реализованными в этих программах.

В дополнение к многократно используемым программным компонентам, игровые движки предоставляют набор визуальных инструментов для разработки. Эти инструменты обычно составляют интегрированную среду разработки для упрощённой, быстрой разработки игр на манер поточного производства. Эти игровые движки иногда называют «игровым подпрограммным обеспечением» (сокр. ППО; англ. middleware), так как, с точки зрения бизнеса, они предоставляют гибкую и многократно используемую программную платформу со всей необходимой функциональностью для разработки игрового приложения, сокращая затраты, сложность и время разработки - все критические факторы в сильноконкурирующей индустрии видеоигр.

Как и другие ППО решения, игровые движки обычно платформо-независимы и позволяют некоторой игре запускаться на различных платформах, включая игровые консоли и персональные компьютеры, с некоторыми внесёнными в исходный код изменениями (или вообще без таковых). Часто игровое ППО имеет компонентную архитектуру, позволяющую заменять или расширять некоторые системы движка более специализированны-ми (и часто более дорогими) ППО компонентами, например, Havok - для физики, FMOD - для звука или SpeedTree - для рендеринга. Некоторые игровые движки, такие как RenderWare, проектируются как набор слабосвязанных ППО компонентов, которые могут выборочно комбинироваться для создания собственного движка, вместо более традиционного подхода расширения или настройки гибкого интегрируемого решения. Тем не менее расширяемость достигнута и остаётся высокоприоритетной в игровых движках из-за широких возможностей их применения. Несмотря на специфичность названия, игровые движки часто используются в других типах интерактивных приложений, требующих графику в реальном времени, таких как рекламные ролики, архитектурные визуализации, обучающие симуляторы и среды моделирования.

Некоторые игровые движки предоставляют только возможности 3D рендеринга в реальном времени вместо всей функциональности, необходимой играм. Эти движки доверяют разработчику игры реализацию остальной функциональности или её сбор на основе других игровых ППО компонентов. Такие типы движков обычно относят к «графическим движкам», «движкам рендеринга» или «3D движкам» вместо более содержательного термина «игровой движок». Однако эта терминология используется противоречиво: так, многие полнофункциональные игровые 3D движки упомянуты просто как «3D движки». Некоторые примеры графических движков: RealmForge, Ogre 3D, Power Render, Crystal Space и Genesis3D.

Графический движок (англ. graphics engine; иногда «рендерер» или «визуализатор») - подпрограммное обеспечение, основной задачей которого является визуализация (рендеринг) двухмерной или трёхмерной компьютерной графики. Может существовать как отдельный продукт или в составе игрового движка. Может использоваться для визуа-лизации отдельных изображений или компьютерного видео. Графические движки, ис-пользующееся в программах по работе с компьютерной графикой (таких, как 3ds Max, Maya, Cinema 4D, Zbrush, Blender), обычно называются «рендерерами», «отрисовщиками» или «визуализаторами». Само название «графический движок» используется, как правило, в компьютерных играх.

Основное и важнейшее отличие «игровых» графических движков от программных рендереров состоит в том, что первые должны обязательно работать в режиме реального времени, тогда как вторые могут тратить по несколько десятков часов на вывод одного изображения. Вторым существенным отличием является то, что начиная приблизительно с 1995-1997 года, графические движки производят рендеринг с помощью графических процессоров (англ. GPU), которые установлены на отдельных платах - видеокартах. Программные рендереры используют только центральные процессоры (англ. CPU).

На этапе становления компьютерных игр графический движок являлся главнейшей частью игрового движка. Собственно, примерно 90-95% игрового движка составлял именно графический движок (остальную часть занимали подсистемы ввода / вывода и т.п.). Однако с середины 90-х годов вследствие стремительного развития компьютерных игр разработчики игр начали добавлять в свои продукты и другие подсистемы, такие как звуковой движок, работа с сетью.

Чаще всего 3D движки или системы рендеринга в игровых движках построены на графическом API, таком как Direct3D или OpenGL, который обеспечивает программную абстракцию GPU или видеокарты. Низкоуровневые библиотеки, например, DirectX, SDL и OpenAL, также используются в играх, так как обеспечивают аппаратно-независимый доступ к другому аппаратному обеспечению компьютера, такому как устройства ввода (мышь, клавиатура и джойстик), сетевые и звуковые карты. До появления аппаратно-ускоряемой 3D графики использовались программные визуализаторы. Программный рендеринг всё ещё используется в некоторых инструментах моделирования для рендеринга изображений, для которых визуальная достоверность важнее производительности (количество кадров в секунду) или когда аппаратное обеспечение компьютера не удовлетворяет требованиям, например, не поддерживает шейдеры.

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

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

1.     
Обзор предметной области

1.1       История возникновения игровых движков

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

Первые примитивные компьютерные и видеоигры были разработаны в 1950-х и 1960-х годах. Они работали на таких платформах, как осциллографы, университетские мейнфреймы и компьютеры EDSAC. Самой первой компьютерной игрой, стал симулятор ракеты, созданный в 1942 году Томасом Голдсмитом Младшим и Истл Рей Менном. Позже, в 1952, появилась программа, играющая в «крестики-нолики», созданная А.С. Дугласом как часть его докторской диссертации в Кембриджском Университете. Игра работала на большом университетском компьютере, известном как EDSAC (Electronic Delay Storage Automatic Calculator). В 1958 году, Уильям Хигинботем, помогавший строить первую ядерную бомбу, в Национальной Лаборатории Брукхевен (Аптон, Нью-Йорк), для развлечения посетителей создал «Теннис для двоих». В 1962 году, Стив Рассел написал «Космическая война и Большое Приключение Джона». Игра работала на миникомпьютере PDP-1 и быстро распространилась по всем университетам страны. В 1968 году, Ральф Баер, который позже стал известен как «Король Видеоигр». запросил патент на раннюю версию игровой консоли «Televisio n Gaming and Training Appataus». В 1967 году, Баер создал пингпинг игру, похожую на «Теннис для двоих». Вместе с Magnavox он работал над созданием первой консоли, названной Magnavox Odyssey в 1972 году. Разработка игровых автоматов в 1970-х привела к так называемому «Золотому веку аркад». Одна из самых известных игр того времени - «Pong».

С появлением первых персональных компьютеров, игры быстро распространились и на этой платформе. И в настоящее время самыми популярными игровыми платформами являются персональные компьютеры и специализированные игровые приставки, такие как PlayStation 3 и Xbox 360.

С эволюцией игр эволюционировали и методы их создания. Так в начале 90-х годов 20-го века, разработчики, создавая новую игру, могли модифицировать и повторно использовать исходный код своих предыдущих игровых проектов. Потом разработчики поняли, что повторно используемый код можно отделить от всей остальной игры. Так стали выделяться такие низкоуровневые операции, как вывод изображения, звук, работа в сети и некоторые другие. Первопроходцем здесь можно признать игру Doom от id Software. Подобный модульный и расширяемый дизайн позволил игрокам и программистам быстро видоизменять игровое ядро - создавать новые игры с новыми моделями, сценарием, звуками, или изменять существующий материал.

Индустрия создания и продажи движков приобрела поистине широкий размах благодаря развитию 3D-технологий. Реализация низкоуровневых операций работы с графикой и звуком стала очень трудоемкой и дорогостоящей, и многие разработчики предпочитают использовать уже готовые движки для своих игр. Продажа движков стала настолько выгодной, что некоторые разработчики игр занимаются в первую очередь созданием движков, а не игр. Например, цена лицензии на использование известного движка Unreal Engine 2 от компании Epic Games составляет 750000 долларов на одну платформу плюс 100000 за каждую дополнительную платформу, а количество игр, выпущенных на этом движке, перевалило за четыре десятка. Раз так называемый игровой движок является основой для построения игр, попробуем разобраться, что же он из себя представляет.

1.2       
Общая характеристика игровых движков

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

Игровой движок - это центральный программный компонент компьютерных и видео игр или других интерактивных приложений с графикой, обрабатываемой в реальном времени. Он обеспечивает основные технологии и часто даёт игре возможность запускаться на нескольких платформах, таких как игровые консоли и настольные операционные системы, например, Linux, Mac OS и Microsoft Windows.

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

В наиболее широком случае, игровой движок включает в себя:

·        Систему игровой логики

·        Систему ввода и работы в сети

·        Систему анимации

·        Физический движок или систему навигации и обнаружения столкновения

·        Систему искусственного интеллекта

·        Звуковой движок

·        Скриптовый движок

·        Базу данных трехмерных моделей и изображений

·        Разнообразные редакторы для работы с движком и создания игры

Некоторые игровые движки предоставляют только возможности 3D рендеринга (т.е. визуализации) в реальном времени вместо всей функциональности, необходимой играм. Эти движки доверяют разработчику игры реализацию остальной функциональности или её сбор на основе других игровых компонентов. Такие типы движков обычно относят к графическим движкам («движкам рендеринга» или «3D движкам») вместо более содержательного термина «игровой движок». Однако эта терминология используется противоречиво: так, многие полнофункциональные игровые 3D движки упомянуты про сто как «3D движки».

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

Структура игрового движка сильно зависит и от жанра игры, для которой он создается. Например, в гоночных аркадах может не быть развитого физического движка, а только учет сил трения, упругих соударений и импульса. А в некоторых играх физика может составлять часть игрового процесса (геймплея - совокупность игровых возможностей, образующих собственно игровой процесс) данной игры, как например в Half-life 2.

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

Низкоуровневые библиотеки, например, DirectX, SDL и OpenAL, обычно используются в играх, так как обеспечивают аппаратно-независимый доступ к аппаратному обеспечению компьютера, такому как устройства ввода (мышь, клавиатура и джойстик), сетевые и звуковые карты, и сильно облегчают разработку игр.

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

1.3        Графический движок

игровой движок приложение программа

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

Графический движок является «лицом» игры. Именно по качеству получаемой картинки у игрока складывается первое впечатление об игре. И причина - в том, что в отличие от баланса и глубины миссий в игре графику не заметить невозможно.

Современный графический движок должен уметь:

·         Рисовать интерфейс пользователя:

·        Экранные меню

·        Игровой интерфейс

·        Рисовать сцену:

·        Ландшафт

·        Объекты

·        Модели (с анимацией)

·        Окружение (небо, облака, погода и т.д.)

·         Эффекты Тени

Данный список может быть не полным, так как все зависит от жанра игры, и от этого же зависит, на каких частях движка делается упор разработчиков. Например, в стратегиях, в отличие от 3D-шутеров, не нужны столь детализированные объекты, ландшафт, тени.

Чаще всего 3D движки или системы рендеринга в игровых движках построены на графическом API, таком как Direct3D или OpenGL, который обеспечивает программную абстракцию GPU или видеокарты. До появления аппаратно-ускоряемой 3D графики использовались программные визуализаторы. Программный рендеринг всё ещё используется в некоторых инструментах моделирования, для рендеринга изображений, для которых визуальная достоверность важнее производительности (количество кадров в секунду) или когда аппаратное обеспечение компьютера не удовлетворяет требованиям, например, не поддерживает шейдеры или, в случае Windows Vista, - Direct3D 10.

Конвейер рендеринга

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

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

Получив информацию о сцене, графический движок должен приступить к, собственно, рендерингу сцены. Конвейер рендеринга может несколько отличаться, в зависиости от используемого 3D API. Но в наиболее общем случае его можно представить следующим образом:

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

Система визуализации мира определяет, где в мире находится камера, и какие секции / полигоны мира видны в поле зрения камеры. Все это можно осуществить различными способами оптимизации. Например, с помощью BSP деревьев, или метода порталов. Возможно комбинированное применение разных методов. Все полигоны, проходящие через тест отсечения лишней геометрии, передаются визуализатору полигонов.

Для каждого полигона, передавшегося на визуализатор, визуализатор осуществляет трансформацию полигона в соответствии с локальной математикой (то есть анимацией модели) и математикой мира (местоположения модели по отношению к камере). Затем полигоны исследуются на предмет наличия нелицевых полигонов (находящихся на невидимой стороне объекта). Нелицевые полигоны, опять же, отбрасываются. Оставшиеся полигоны освещаются в соответствии с действующими световыми источниками. Визуализатор затем определяет, какие текстуры полигон использует и удостоверяется, что API/видеокарта будет использовать те же текстуры для отображения. Затем полигоны направляются на API рендеринга и затем на видеокарту.

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

От скорости прохождения конвейера рендеринга в большой степени зависит производительность высокотехнологических игр. Медленная скорость работы игры оказывает неприятное впечатление на общий игровой процесс. Поэтому повышение производительности графического движка является серьезной проблемой для разработчиков игр, и важно найти правильный баланс между производительностью и качеством графики. Для возможности запуска игры на разных конфигурациях персональных компьютеров (это не относится к игровым приставкам, т. к. технические возможности приставок определяются при их создании и не изменяются в течение всего цикла их жизни) разработчики должны оставить возможность самим пользователям определить уровень качества получаемой картинки. Соответственно возможность таких настроек должна быть предусмотрена при разработке графического движка

1.4        Шейдерные эффекты

1.4.1 О шейдерах

Шейдером в широком смысле называется программа для визуального определения поверхности объекта. Это может быть описание освещения, текстурирования, постобработки и т.п. Шейдеры выросли из работ Кука (Cook's shade trees [12]) и Перлина (Perlin’s pixel stream language). Программируемые шейдеры были впервые представлены в RenderMan компании Pixar, там определены несколько типов шейдеров: light source shaders, surface shaders, displacement shaders, volume shaders, imager shaders. Эти шейдеры чаще всего программно выполняются универсальными процессорами и не имеют полной аппаратной реализации. В дальнейшем, многие исследователи описывали похожие на RenderMan языки, но они уже были предназначены для аппаратного ускорения. Peercy сотоварищи разработали технику для того, чтобы программы с циклами и условиями выполнять на традиционных аппаратных архитектурах при помощи нескольких проходов рендеринга. Шейдеры RenderMan разбивались на несколько проходов, которые комбинировались во буфере кадра. Позднее появились языки, которые были аппаратно ускоренными в Direct X и OpenGL. Так шейдеры были адаптированы для графических приложений реального времени.

Видеочипы раннего времени не были программируемы и исполняли только заранее запрограммированные действия (fixed-function), например, алгоритм освещения был жестко зафиксирован в аппаратном обеспечении, где ничего нельзя было изменить. Затем, компании-производители видеочипов постепенно ввели в свои чипы элементы программируемости, сначала это были очень слабые возможности, которые не получили программной поддержки в Microsoft DirectX API, но со временем возможности постоянно расширялись.

Версия Shader Model 2.0 (SM2), появившись в DirectX 9, серьезно расширила возможности шейдеров реального времени, предложив более длинные и сложные шейдеры и заметно расширившийся набор команд. Была добавлена возможность расчетов с плавающей запятой в пиксельных шейдерах, что также стало важнейшим улучшением. DirectX 9, в лице возможностей SM2, также привнес и язык шейдеров высокого уровня - high-level shader language (HLSL), весьма похожий на язык Си. И эффективный компилятор, переводящий HLSL программы в низкоуровневый код, «понятный» для аппаратных средств

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

Все шейдеры состоях из двух состовляющих: это вершинные и пиксельные шейдеры. Вершинные шейдеры - это программы, выполняемые видео чипами, которые производят математические операции с вершинами, иначе говоря, они предоставляют возможность выполнять программируемые алгоритмы по изменению параметров вершин и их освещению. Каждая вершина определяется несколькими переменными, например, положение вершины в 3D пространстве определяется координатами: x, y и z. Вершины также могут быть о писаны характеристиками цвета, текстурными координатами и т.п. Вершинные шейдеры, в зависимости от алгоритмов, изменяют эти данные в процессе своей работы, например, вычисляя и записывая новые координаты и / или цвет. Таким образом, входные данные вершинного шейдера - данные об одной вершине геометрической модели, которая в данный момент обрабатывается. Обычно это координаты в пространстве, нормаль, компоненты цвета и текстурные координаты. Результирующие данные выполняемой программы служат входными для дальнейшей части конвейера, растеризатор делает линейную интерполяцию входных данных для поверхности треугольника и для каждого пикселя исполняет соответствующий пиксельный шейдер.

Пиксельные шейдеры - это программы, выполняемые видеочипом во время растеризации для каждого пикселя изображения, они производят выборку из текстур и / или математические операции над цветом и значением глубины (Z-buffer) пикселей. Все инструкции пиксельного шейдера выполняются попиксельно, после того, как операции с трансформированием и освещением геометрии завершены. Пиксельный шейдер в итоге своей работы выдает конечное значение цвета пикселя и Z-значение для последующего этапа графического конвейера, смешивания (blending).

1.4.2 Программирование шейдерных программ

Выполнение шейдерных программ происходит в процессе визуализации изображения, который разбит на множество последовательных шагов [1, 3]. Иными словами в графическом процессоре используется конвейерная обработка данных.

1) В самом начале графического конвейера расположен блок обработки вершин. Программа, по которой происходит обработка - есть вершинный шейдер (Vertex Shader). Помимо значения координат к вершинам так же могут быть привязаны текстурные координаты, цвет, нормали, и.т.д. Шейдерная программа обрабатывает их, выдавая трансформированные вершины, заданные в логической системе однородных координат и лежащих в промежутке от -1.0 до 1.0. Так же на данном этапе вычисляется освещенность каждой точки, находящейся в вершинном буфере.

игровой движок приложение программа

Рисунок 1.1 Схема графического конвейера

) На следующем этапе идет процесс сборки вершин в примитивы. В зависимости от заданных параметров это могут быть треугольники (как правило, это именно они), линии, точки, и т.п. На этом же этапе идет отсечение невидимых, скрытых и полностью прозрачных частей. Это делается с целью экономии ресурсов и времени, так как нет необходимости визуализировать то, чего не видно. В итоге после завершения данной стадии конвейера мы уже имеем дело с потоком каких-то примитивов, а не с набором никак не связанных вершин.

) После того как из точек были собраны графические примитивы в дело вступает геометрический шейдер (при условии что программа была написана на Shader Model 4.0 или выше), который преобразует существующие примитивы и при необходимости добавляет новые.

) Далее координаты вершин трансформируются в оконную систему, в которой они и будут отображены на экран. Следует так же отметить, что программист может с самого начала задавать все вершины в оконных координатах. В этом случае необходимость в 1-3 шагах конвейера отпадает.

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

) Теперь поток пикселей, полученный в результате интерполирования примитивов, попадает на вход пиксельному шейдеру (Pixel Shader), где он обрабатывается в соответствии с заданной программой. Помимо цвета пикселя, на вход к шейдеру могут подаваться и другие параметры. Чаще всего это значение текстурных координат, по которым происходит выборка текселя из заранее определенной текстуры, находящейся в памяти видео карты. Вне зависимости от программы, пиксельный шейдер обязан вернуть цвет итогового пикселя, поступающего на вход следующему этапу графического конвейера.

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

1.5       
Графические
API

1.5.1 Обзор API

На сегодняшний день существует три основных API позволяющих программировать графический конвейер: Direct3D, OpenGL и XNA. Каждое из них имеет свои преимущества и недостатки.

OpenGL

OpenGL, является, пожалуй, самым распространенным API для программирования GPU. Он поддерживается большинством современных платформ, к примеру, существуют эффективные реализации OpenGL для таких сред как Windows, Linux, MacOS и PlayStation III. OpenGL был разработан SGI (Silicon Graphics Incorporated), который позже, в 1992 году возглавил консорциум OpenGL ARB (Architecture Review Board) в состав которого сейчас входят такие производители профессиональных и потребительских графических аппаратных средств, как SGI, 3Dlabs, Matrox и Evans & Sutherland, ATI и NVIDIA. Из производителей аппаратного обеспечения входящих в состав ARB можно назвать Intel, IBM, Apple, Dell, Hewlett-Packard и Sun Microsystems. Так же нельзя не упомянуть одного из крупнейших разработчиков игрового программного обеспечения - IdSoftware. Из достоинств OpenGL можно назвать: невероятную гибкость, открытость и расширяемость, а так же упомянутую выше кроссплатформенность. К недостаткам OGL можно, отнести лишь одну, но крайне существенную особенность - крайне медленные темпы развития и обновления версий OpenGL. Это связанно с постоянно возникающими разногласиями и нестыковками между членами консорциума, а это попросту недопустимо в стремительно развивающемся мире графических адаптеров.

Direct3D

Несмотря на то, что все операционные системы семейства Windows, начиная с 95-ой версии, способны превосходно работать с библиотеками OpenGL, Microsoft параллельно ведет разработку и поддержку своего собственного API для программирования графических адаптеров. Direct3D является частью проекта DirectX, включающего в себя набор инструментов для работы с мультимедиа, к примеру DirectSound используется для работы со звуком, DirectInput и DirectPlay для работы с внешними контроллерами и сетью соот-ветственно. Direct3D, в отличие от OpenGL, не является кроссплатформенными и поддерживается лишь системами Microsoft Windows и Microsoft XBox. Но благодаря тому факту, что Microsoft регулярно выпускает новые версии DirectX, его API всегда поддерживает возможности новейших видеокарт.

The XNA Framework

XNA Framework - самая молодая из троицы API, дата ее выпуска - 2007-ой год. XNA базируется на DirectX SDK и предоставляет программисту высокоуровневый объектно-ориентированный функционал для разработки видеоигр. На данный момент XNA официально поддерживает лишь язык C#, так как ее основные библиотеки построены на Microsoft.NET framework. Поддерживаемые платформы - Microsoft Windows и Xbox 360.

1.5.2 Сравнение трех основных графических API

Кросс-платформенная разработка

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

На данный момент больше всего различных платформ поддерживает OpenGL: Microsoft Windows, Linux, Mac. OpenGL не может работать под Xbox и Xbox 360 но поддер-живается PlayStation 3.

Direct3D API работает лишь на платформах Microsoft (Windows, Xbox, Xbox 360), а также эмулируется под Linux при помощи платформы Wine, которая перенаправляет вызовы Direct3D API в OpenGL API.

Как уже говорилось выше, XNA Framework работает лишь на тех платформах Microsoft, которые поддерживают.NET framework (т.е. Windows XP, Vista, 7 и Xbox 360).

Простота использования

В терминах синтаксиса кода самым простым для использования будет XNA API, а самым сложным - DirectX. Так как DirectX и OpenGL - нативные библиотеки C, предоставляемый интерфейс не поддерживает классы и пространства имен.

С другой стороны, XNA ограничена платформой.NET, что означает ее невозможность использования с нативными языками, но лишь с управляемым кодом, который, в свою очередь, как раз поддерживает классы и пространства имен. Кроме того, в XNA встроено множество встроенных классов-помощников, как написанных специально для XNA Framework, так и предоставляемых.NET.

Таким образом, если OpenGL и Direct3D ближе к аппаратному уровню и могут быть портированы на языки высокого уровня, время, затрачиваемое на разработку приложения под эти API, будет значительно больше, чем при использовании XNA.

Производительность

Так как OpenGL и Direct3D - API основанные на С, они ближе к аппаратному уровню, и имеют не так много уровней абстракции. Таким образом, разница в производительности между первым и вторым API несущественны. Если и будут серьезные различия, то это будет скорее всего вызвано тем, как драйвер видеокарты выполняет команды API.

XNA Framework - это библиотека.NET, которая выполняет вызовы Direct3D на виртуальной машине, в которой.NET Framework работает. Такой высокий уровень абстракции может привести в потерям производительности.

Свойства

API часто ограничены количеством свойств, которые они имеют на момент выпуска. Это приводит к тому, что API постоянно обновляются, увеличивая номер в названиях версии. Новые версии SDK для DirectX/Direct3D выпускаются каждые несколько месяцев.

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

XNA Framework основана на 9-ой версии Direct3D и содержит лишь функционал этого API. Если новая версия Direct3D выпускается, XNA получит обновление лишь позже, серьезно уступаю в этом плане другим API.

Поддержка

OpenGL API поддерживается исключительно сообществом разработчиков. DirectX API поддерживается как сообществом разработчиков, так и авторами API через MSDN. XNA Framework также имеет профессиональную поддержку аналогичную DirectX.

Популярность

Direct3D API наиболее популярное решение для платформ Windows и Xbox, а то есть для большинства разработчиков игр.

OpenGL пользуется популярностью среди профессиональных 3D программистов, но среди разработчиков игр интерес к данному API иссяк примерно в 2000-ом году. OpenGL - единственный вариант для разработки программ с аппаратным графическим ускорением под платформами не принадлежащими Microsoft.

XNA Framework популярна, в первую очередь, среди программистов, для которых графика - хобби, а также среди тех, кто начинает изучать основы программирования 2D и 3D графики. На данный момент под XNA выпущено всего несколько профессиональных продукта.

Лицензия

Очень важным аспектом в разработке программ - это лицензионные ограничения, накладываемые на API. OpenGL и Direct3D имеют лицензионные модели, которые позволяют выпускать коммерческие продукты без ограничений.

Для выпуска продукта под XNA Framework должно быть заключено лицензионное соглашение между разработчиком и Microsoft, которое ограничивает использование сетевых функций XNA. XNA Game Studio не может быть использована для разработки коммерческих игр под Xbox 360, но выпуск игр под Windows разрешен. Чтобы выпускать игры под Xbox 360, существует специальная подписка для разработчиков, размером в $99.

Таблица 1: Сравнение трех основных графических API

Свойства

OpenGL

Direct3D

XNA

Поддержка различных платформ, число

Да, множество

Да, три

Да, две

Сложность освоения

Высокая

Высокая

Низкая

Базовый язык (нативный)

C

C

C#

Поддерживаемые языки

Большинство языков

Большинство языков

NET языки

Высокая производительность

Да

Да

Нет

Лицензионные ограничения

Нет

Нет

Да

Поддержка производителем

Нет

Да, платно

Да, платно

Платформа Библиотеки

Нативный код

Нативный код

Управляемый код

1.5.3 Общие принципы работы с графическими API

Direct3D и OpenGL имеют ряд серьезных различий в их структуре и наборе предоставляемых функций, но тем не менее они выполняют одну и ту же роль, а именно подготавливают систему для исполнения кода шейдера на GPU [7]. Этот процесс в общих чертах может быть разбит на следующие этапы:

. Создание графического устройства (device) представляющее собой своеобразную программную модель графического процессора. Именно через него осуществляется почти работа с GPU.

. Подготовка буфера вершин (vertex buffer), содержащего перечень координат всех вершин, а так же некоторых дополнительных параметров. К примеру, в этой роли может выступать значение освещенности вершины, ее текстурные координаты (они используются для привязки текстуры к графическому примитиву), векторы нормали и.т.д.

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

4. Загрузка файлов-эффектов, представляющих собой набор шейдеров, используемых при визуализации текущего объекта.

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

. Далее следует ключевой этап - визуализация сцены (Scene). Именно здесь в дело вступает графический конвейер, который проделывает всю работу по превращению набора точек в законченное трехмерное изображение.

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

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

1.6        Теоретический обзор шейдерных эффектов

1.6.1 Равномерное освещение

Равномерное освещение (ambient lighting) обеспечивает постоянное начальное освещение для всей сцены. Оно освещает все вершины объектов одинаково, потому что не зависит ни от каких других факторов освещения. Это самый простой и быстрый тип освещения, но при этом дает наименее реалистичный результат. Формула для вычисления этой модели освещения так же очень проста, т. к. там всего одна арифметическая операция - умножение. Для ее вычисления достаточно перемножить цвет материала на интенсивность освещения:

(1)

1.6.2 Диффузионная модель освещения

Диффузная модель освещения (diffuse lighting model) - модель освещения, которая зависит от положения источника освещения и от объектной нормали поверхности. Поскольку излучение света одинаково во всех направлениях, видовой вектор не имеет значения, т.е. v = 0. Такой метод требует большего вычисления, так как изменяется для каждой вершины объекта, однако неплохо затеняет объекты и придает им объем. Свет падает, не заполняя всю поверхность одинаковым цветом (как в случае с раномерным освещением), а создается впечатление, что, свет направлен на какую либо поверхность.

Рисунок 1.2. Диффузная модель освещения

Если вектор позиции источника освещения перпендикулярен поверхности, то никакой матовости не будет наблюдаться, потому что интенсивность света зависит от угла б. Для расчета диффузной модели освещения используется формула (по закону Ламберта):

 (2)

1.6.3 Бликовая модель освещения

В этой модели освещения помимо векторов позиции источника освещения и нормали (как в случае с диффузной моделью освещения) используются еще два вектора: видовой вектор и вектор отражения. Бликовую модель освещения (specular lighting model) предложил Буи-Туонг Фонг [13].

Рисунок 1.3. Бликовая модель освещения

Угол между видовым вектором и вектором отражения - в. Чем больше угол в, тем ярче бликовое освещение. Поэтому бликовая модель освещения вычисляется по следующей формуле:

(3)

где п - коэффициент яркости свечения.

С ростом параметра п отражение становиться все более бликовым и все более концентрируется вдоль направления вектора отражения R.

1.6.4
Модификация модели свещения по Блину

Джим Блинн [6] придумал альтернативный способ вычисления бликового освещения, который устраняет дорогие вычисления над вектором отражения.

Общая формула имеет вид:

(4)

Он ввел промежуточный вектор (half vector), который является средним значением между видовым вектором и вектором позиции источника освещения

1.6.5 Тени ShadowMap

Тени являются важной зрительной подсказкой как в реальности, так и в визуализированных сценах. На самом низком уровне тени предоставляют информа-цию о расположении объектов относительно друг друга и источников света, даже если эти источники на сцене не видны. Когда речь идет об играх, тени могут сделать игровой мир совершенно жутким. Представьте, что вы заворачиваете за угол в подземелье, освещенном лишь факелами, и входите в тень своего самого страшного кошмара Питер Пен отдыхает'[5].

На сегодняшний день существует множество алгоритмов построения теней. Эти алгоритмы являются важными в компьютерной индустрии, так как они помогают реализовать важную часть в представлении объектов моделируемого мира, без тени объекты не будут выглядеть реалистичными. Существуют такие алгоритмы как Shadow volume, Ray casting, Photo mapping, Radiosity, Shadow Mapping.

Shadow volume

Это техника используется компьютерной графике для воспроизведения теней в отображаемой сцене. Впервые техника была представлена Франком Кровом в 1977 году [20] как геометрически смоделированная 3D поверхность, закрывающая собой источник света. Shadow volume разделяла виртуальный мир на две части: то что находилось в тени и то что находилось не в тени.

Shadow volume становилась популярной техникой для отображения теней в реальном времени, так же как и более популярная shadow mapping. Техника shadow volume требует создания геометрии объекта-тени, что может отразиться на производительности CPU (зависит от реализации). Преимущество метода shadow map относительно SV в том, что она чаще всего быстрее, в полигоны shadow volume часто очень большие в пределах пространства экрана и требуют большого времени для отрисовки (особенно для выпуклых объектов), тогда как карты теней не имеют этого ограничения.

Ray casting

Он используется для решения разнообразных проблем в компьютерной графике, связанных с пересечением лучей света на поверхности. В компьютерной графике способ был впервые представлен в 1982 году на докладе Скота Роса по описанию метода для рендеринга CSG models [21].

Ray Casting имеет отношение к:

·        Общая проблема определения первого пересечения объекта с лучом.

·        Методика для удаления невидимых поверхностей, основанная на поиске первого пересечения луча, который проектируется из точки обозрения к каждому пикселю изображения.

·        Нерекурсивный вариант трассировки лучей, при котором «бросаются» только первичные лучи.

·        Метод прямого объёмного рендеринга, также называемый «volumeray casting (англ.)».

Рейкастинг не является синонимом к рейтрейсингу (трассировке лучей), но он может быть представлен как сокращённая и существенно более быстрая версия алгоритма трассировки лучей. Оба алгоритма являются «image order» и используются в компьютерной графике для рендеринга трёхмерных сцен на двухмерный экран с помощью проекционных лучей, которые проектируются от глаз обозревателя к источнику света. Метод бросания лучей не вычисляет новые тангенсы лучей света, которые возникнут после того, когда луч, который проектируется от глаза к источнику света, пересечётся с поверхностью. Эта особенность делает невозможным точный рендеринг отражений, преломлений и естественной проекции теней с помощью рейкастинга. Однако все эти особенности могут быть добавлены с помощью «фальшивых» (обманных, аппроксимационных) методик, например, через использование текстурных карт или другие методы. Высокая скорость вычисления сделала рейкастинг удобным методом рендеринга в ранних компьютерных играх с трёхмерной графикой реального времени.

В реальной природе источник света испускает луч света, который, «путешествуя» по пространству, в конечном счёте «натыкается» на какую-либо преграду, которая перерывает распространение этого светового луча. Луч света можно представить в виде потока фотонов, который движется вдоль вектора луча. В какой-либо точке пути с лучом света может случиться любая комбинация трёх вещей: поглощение, отражение (рефлекция) и преломление (рефракция). Поверхность может отразить весь световой луч или только его часть в одном или нескольких направлениях. Поверхность может также поглотить часть светового луча, что приводит к потере интенсивности отраженного и / или преломлённого луча. Если поверхность имеет какие-либо свойства прозрачности, то она преломляет часть светового луча внутри себя и изменяет его направление распространения, поглощая некоторый (или весь) спектр луча (и, возможно, изменяя цвет). Суммарная интенсивность светового луча, которая была «потеряна» вследствие поглощения, преломления и отражения, должна быть в точности равной исходящей (начальной) интенсивности этого луча. Поверхность не может, например, отразить 66% входящего светового луча, и преломить 50%, так как сумма этих порций будет равной 116%, что больше 100%. Отсюда истекает, что отраженные и / или преломлённые лучи должны «стыкаться» с другими поверхностями, где их поглощающие, отражающие и преломляющие способности снова вычисляются, основываясь на результатах вычислений входящих лучей. Некоторые из лучей, сгенерированных источником света, распространяются по пространству и, в конечном счете, попадают на область просмотра (глаз человека, объектив фото- или видеокамеры и т.д.). Попытка симулировать физический процесс распространения света путём трассировки световых лучей, используя компьютер, является чрезмерно расточительным, так как только незначительная доля лучей, сгенерированных источником света, попадает на область просмотра.

Photon mapping

В компьютерной графике, photon mapping это двухходовой алгоритм глобального освещения разработанный Henrik Wann Jensen [22] для решения проблемы выравнивания при рендеренге. Лучи исходящие из источника света и лучи исходящий из камеры трассируются самостоятельно, пока не встретиться некоторый предел, затем они соединяются на последующем шаге для создания radiance value (излучающая величина). В особенности, это искусная симуляция преломления света проходящего через прозрачную субстанцию такую как стакан воды, diffuse interreflection между освещённым объектами, subsurface scattering света в полупрозрачных материалах, и некоторые эффекты такие как испарение воды и туман. Это может так же быть расширено более аккуратной симуляцией света, та-кой как spectral rendering.

Shadow Mapping

Карты теней (Shadow maps) широко используются в отображении теней в работе с компьютерной графикой. Shadow mapping, впервые был представлен Ленсом Вильянсом в 1978 году, в докладе «Casting curved shadows on curved surfaces» [23].

Теория метода отображения тени проста. Вопрос: какие части сцены попадут в тень'' Ответ, части, на которые не падает непосредственно свет. Представьте, что вы наблюдаете сцену, находясь в источнике света Что «увидел» бы источник света, будь он камерой? Все, что наблюдается с позиции источника света, освещается, а все остальное попадает в тень. Различие между наблюдением с позиции камеры и наблюдением с позиции источника света иллюстрируется на рис. 3. С позиции камеры и источника света сцена выглядит по-разному.

Рисунок 1.4. Изображение сцены с позиции камеры и источника света

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

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

Основной нашей целью является проектирование карты тени (вида с позиции источника света) сцены обратно на сцену так, будто свет исходит от источника света, но наблюдение ведется с позиции камеры. Мы проектируем полученные глубины, представляющие расстояние от источника света до первого объекта, на который падают лучи света. Перевод текстурных координат в нужную систему координат потребует немного математических расчетов

В графическом конвейере идет процесс преобразования вершин из пространства объектов в систему координат наблюдения, затем - в усеченное пространство нормированных координат устройства и, наконец, - в пространство окна. В работе с этими преобразованиями участвуют две матрицы, одна представляет проекцию с позиции источника света, вторая - обычную проекцию камеры. Два набора соответствующих преобразований показаны на рис. 1.5.

Рисунок 1.5. Процесс перехода из системы наблюдения камеры в систему наблюдений источника света.

Большой стрелкой в центре на рисунке 4 показаны преобразования, которые нужно применить к текстурным координатам, линейным в системе наблюдения

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

В конце нам нужно получить текстурные координаты, указывающие в нашу карту тени из усеченного пространства источники света. Начинаем с проектирования текстурных координат, линейных в системе наблюдения, в пространство «глаза камеры». Следовательно, вначале нужно перейти во внешнюю систему координат, потом - в систему с центром в источнике света, а затем - в усеченное пространство источника света. Это преобразование можно обобщить следующей последовательностью матричных умножений.

 (5)

Однако это еще не все. Усеченного пространства источника света недостаточно. Помните, что для всех координат (х, у и z) усеченное пространство ограничивается диапазоном [-1,1]. Текстуру глубины карты тени, подобно всем стандартным двухмерным текстурам, нужно индексировать в диапазоне [0,1]. Кроме того, глубины, с которыми нужно сравнивать значения, принадлежат диапазону [0,1], поэтому координату z также нужно перевести в этот диапазон Для этого следует выполнить масштабирование с коэффициентом одна вторая (S) и сместить результат на одну вторую (В).

(6)

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

 (7)

К сожалению, для большинства теневых текстур, созданных по технологии shadow mapping допускает алиасинг - резкие границы теней. Современные видео-карты имеют встроенные методы для понижения алиасинга на простых текстурах: а именно mipmapping и anisotropic filtering. Эти методы не подходят к стандартным теневым картам, так как они могут изменить глубину соседних пикселей, которая хранится в компоненте цвета текстуры.

Для вычисления теней в общих сценах и борьбы с алиасинг используется процентная Близкая Фильтрация (Percentage Closer Filtering, PCF) обеспечивает решение проблемы алиасинга карты теней. Ключевой момент в том, что корректный алгоритм фильтрации нуждается в выявление результатов срав-нения глубин, вместо их фильтрации. Это совершается выборочно семплированием карты теней, таким образом, требуя множество семплов для уничтожения помех.

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

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

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

Альтернативное решение проблемы алиасинга карты теней это изменение проекции карты теней. Этот подход рассматривается в adaptive shadow maps, perspective shadow maps, light space perspective shadow maps и trapezoidal shadow maps.

2.     
Проектирование 3
D-приложения

Для проектирования 3D-приложения необходима библиотека классов, которая облегчает процесс разработки такого рода приложений. Такую библиотеку классов также часто называют «3D движком», Над разработкой «3D движка» работают многие коммерческие фирмы с большим штатом программистов в течение длительного времени, но все эти «3D движки» закрыты или являются очень дорогостоящими. В связи с тем, что мы не обладаем большими финансовыми и штатными резервами и также ограничены во времени, будем проектировать собственный «3D движок» c минимальным достаточным набором функций.

2.1        Постановка задачи

Цель данной работы - разработка 3D-приложения на основе библиотеки классов. Разработанная библиотека классов должна предоставлять пользова-телю следующий перечень возможностей:

выводить, управлять Windows - окнами

подключать / отключать графическую библиотеку, в нашем случае - OpenGL

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

уметь манипулировать математикой основных 3d данных:

) вектора разной размерности (2,3,4 компонентные),

) матрицы (3,4 разрядные),

) кватернионы

) углы Эйлера, а также их взаимное преобразование, а именно переход из углов Эйлера в матрицу и наоборот

загружать / выгружать текстуры (файловые изображения)

уметь создавать базовые модели плоскость, куб, сфера, торус

уметь загружать / выгружать произвольные 3d-модели

загружать шейдеры

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

задавать материалы к загруженным 3d-моделям

работа с внеэкранными буферами

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

Рисунок 2.1 Общая схема 3D-движка

Модуль Камера предназначен для создания и управления камерой наблюдателя в нашем проектируемом 3d мире

Модуль Текстуры предназначен загрузки изображений и преобразований ее формат OpenGL. В нашей программе мы используем TGA формат для загрузки изображения, как один из наиболее распространенный.

Модуль шейдеры предназначен компиляции, отладки, подключение к программе, а также передачи из программы в шейдер параметров

Модуль внеэкранный буфер предназначен

Модуль 3d математика предназначен манипулировать математикой основных 3d данных:

) вектора разной размерности (2,3,4 компонентные),

) матрицы (3,4 разрядные),

) кватернионы

) углы Эйлера, а также их взаимное преобразование, а именно переход из углов Эйлера в матрицу и наоборот

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

Модуль OpenGL API функции необходим для описания и подключений функций OpenGL и его расширений

Модуль приложения предназначен для создания окна windows и инициализации контекста OpenGL. В данной разработке мы используем OpenGL версии 3.3.

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

общее количество данных

-    массив данных, в формате (вершина, текстурная координата, нормаль)

-        количество индексов

массив индексов

Модуль материалы предназначен для описания структуры материала, а также передачи данных в шейдер. Считаем, что материал описывается такими параметрами:

Свечение материала

Фоновое освещение материла

Рассеянный свет источника света

Отраженный свет источника света

Модуль тени предназначен для описания алгоритмов построения теней от 3d объектов

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

Свечение источника света

Фоновое освещение источника света

Рассеянный свет источника света

Отраженный свет источника света

Позиция источника света

Направление источника света

Проекционная матрица источника света

2.2        Архитектура 3D-приложения с использованием проектируемого 3D движка

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

3.     
Реализация 3
D-приложения

В данном разделе представлен и расписан алгоритм добавления тени для 3D объектов на основе теневой карты (shadow map) с фрагметнтами программного кода и шейдерами. Весь программный код 3D - приложения приведен в приложениях А, Б, В, Г, Д соответственно

3.1        Обобщенный алгоритм работы 3d-программы

Обобщенный алгоритм работы 3d-программы представлен на рис. 3.1 и состоит из 8 шагов.

. Ввод исходных данных

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

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

Источники света

Текстуры

Материалы

Дополнительный буфер

. Инициализируется Windows-окно и контекст OpenGL 3.3.

. Обработка очереди сообщений Windows-окна

. Обработка ввода с клавиатуры пользователя

. Рисование кадра 3D-приложения

. Пересчет кадра 3D-приложения

. Проверка условий работает ли 3D-приложение

. Деинициализация Windows-окна и контекста OpenGL 3.3

Рисунок 3.1 Обобщенный алгоритм работы 3d-программы

3.2        Рисование кадра 3d-приложения

Рисование кадра 3D-приложения представляет собой двух этапный алгоритм (рис. 3.2) и состоит следующих этапов:

рисование сцены в текстуру тени.

рисование итогового изображения вместе с тенью

Рисунок 3.2 Алгоритм рисования кадра 3D-приложения

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

Рисование сцены в текстуру тени

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

·      Матрицу вида (view matrix)

·        Матрицу проекции (projection matrix)

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

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

Рисунок 3.3 Алгоритм рисования сцены в текстуру тени

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

const mat4 OrthoProjection (float left, float right,bottom, float top,zNear, float zFar)

{float tx = - (right + left) / (right - left),= - (top + bottom) / (top - bottom),= - (zFar + zNear) / (zFar - zNear);

mat4 (2 / (right - left), 0, 0, tx,

, 2 / (top - bottom), 0, ty,

, 0, -2 / (zFar - zNear), tz,

0, 0, 0, 1);

}

Теневая карта использует буфер глубины (depth buffer), для того, чтобы определить, находится ли пиксель в прямой видимости источника освещения, либо он чем-то загорожен.

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

Для того, чтобы получить буфер глубины, нам необходимо:

Создать текстуру для хранения буфера глубины

Создать Framebuffer Object (FBO) и привязать к нему текстуру

Настроить камеру и выполнить рендер сцены в созданный FBO

Начнем по порядку, для начала создадим текстуру для хранения буфера глубины, делается это следующим образом:

// функция создания текстуры для хранения буфера глубины

GLuint TextureCreateDepth (GLsizei width, GLsizei height)

{texture;

// запросим у OpenGL свободный индекс текстуры(1, &texture);

// сделаем текстуру активной(GL_TEXTURE_2D, texture);

// установим параметры фильтрации текстуры - линейная фильтрация

glTexParameteri (GL_TEXTURE_2D,_TEXTURE_MIN_FILTER, GL_LINEAR);(GL_TEXTURE_2D,_TEXTURE_MAG_FILTER, GL_LINEAR);

// установим параметры «оборачиваниея» текстуры - отсутствие оборачивания

glTexParameteri (GL_TEXTURE_2D,_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);(GL_TEXTURE_2D,_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// необходимо для использования depth-текстуры как shadow map

glTexParameteri (GL_TEXTURE_2D,_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);

glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

// проверим на наличие ошибок_CHECK_FOR_ERRORS();texture;

}

// создадим текстуру для хранения буфера глубины

GLuint depthTexture = TextureCreateDepth (DEPTH_TEXTURE_WIDTH, DEPTH_TEXTURE_HEIGHT);

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

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

// Framebuffer Object (FBO) для рендера в него буфера глубиныdepthFBO = 0;

// переменная для получения состояния FBOfboStatus;

// создаем FBO для рендера глубины в текстуру(1, &depthFBO);

// делаем созданный FBO текущим(GL_FRAMEBUFFER, depthFBO);

// отключаем вывод цвета в текущий FBO

glDrawBuffer (GL_NONE);(GL_NONE);

// указываем для текущего FBO текстуру, куда следует производить рендер глубины

glFramebufferTexture (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);

// проверим текущий FBO на корректность((fboStatus = glCheckFramebufferStatus (GL_FRAMEBUFFER))!= GL_FRAMEBUFFER_COMPLETE)

{_ERROR («glCheckFramebufferStatus error 0x % X\n», fboStatus);

return false;

}

// возвращаем FBO по-умолчанию(GL_FRAMEBUFFER, 0);

После создания FBO и привязки к нему текстуры мы можем выполнить рендер всей сцены с использованием этого FBO:

// установим активный FBO(GL_FRAMEBUFFER, depthFBO);

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

glViewport (0, 0, DEPTH_TEXTURE_WIDTH, DEPTH_TEXTURE_HEIGHT);

// отключаем вывод цвета(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

// включаем вывод буфера глубины(GL_TRUE);

// очищаем буфер глубины перед его заполнением

glClear (GL_DEPTH_BUFFER_BIT);

// отключаем отображение внешних граней объекта, оставляя внутренние(GL_FRONT);

// выполним рендер сцены с использованием шейдерной программы и камеры источника освещения(depthProgram, lightCamera);

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

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

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

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

layout (location = VERT_POSITION) in vec3 position;

// параметры преобразованийstruct Transform

{modelViewProjection;

} transform;main(void)

{

// переводим координаты вершины в однородные_Position = transform.modelViewProjection * vec4 (position, 1.0);

}

Т.к. нас интересует только глубина фрагментов, а не их цвет, то фактически фрагментный шейдер может быть пустым:

main(void)

{

}

Рисования итогового изображения вместе с тенью

Рисунок 3.4 Алгоритм рисования итогового изображения вместе с тенью

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

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

void CameraSetupLightMatrix (GLuint program, const Camera &camera)

{

// матрица сдвига текстурных координатconst mat4 bias (

.5f, 0.0f, 0.0f, 0.5f,

.0f, 0.5f, 0.0f, 0.5f,

.0f, 0.0f, 0.5f, 0.5f,

0.0f, 0.0f, 0.0f, 1.0f

);

// расчитаем необходимые матрицы

mat4 view = GLFromEuler (camera.rotation) * GLTranslation (-camera.position);viewProjection = bias * camera.projection * view;

// передадим матрицу источника освещения в шейдерную программу

glUniformMatrix4fv (glGetUniformLocation(program, «transform.light»), 1, GL_TRUE, viewProjection.m);

}

Комментарий по поводу матрицы bias. Сначала мы получаем видовую матрицу источника освещения view, она переводит координаты вершины из мирового пространства координат в пространство координат источника освещения. Затем, используя проекционную матрицу, мы переводим координаты в однородные. Однако, известно что однородные координаты лежат в диапазоне [-1, 1], а нам необходимо получить текстурные координаты, которые лежат в диапазоне [0, 1], именно для этого используется матрица bias. Трансформация этой матрицы равносильна операции a * 0.5 + 0.5 для каждого элемента трансформируемого вектора.

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

layout (location = VERT_POSITION) in vec3 position;(location = VERT_TEXCOORD) in vec2 texcoord;(location = VERT_NORMAL) in vec3 normal;

// параметры преобразованийstruct Transform

{model;viewProjection;light;normal;viewPosition;

} transform;

// параметры точеченого источника освещения

uniform struct Light

{ambient;diffuse;specular;4 position;

} light;

// параметры для фрагментного шейдера

out Vertex

{texcoord;smcoord;normal;lightDir;viewDir;

} Vert;

void main(void)

{

// переведем координаты вершины в мировую систему координат

vec4 vertex = transform.model * vec4 (position, 1.0);

// передадим в фрагментный шейдер некоторые параметры

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

Vert.smcoord = transform.light * vertex;

// передаем текстурные координаты.texcoord = texcoord;

// передаем нормаль в мировой системе координат

Vert.normal = transform.normal * normal;

// передаем направление на источник освещения

Vert.lightDir = vec3 (light.position);

// передаем направление от вершины к наблюдателю в мировой системе координат

Vert.viewDir = transform.viewPosition - vec3 (vertex);

// переводим координаты вершины в однородные_Position = transform.viewProjection * vertex;

}

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

Самплер sampler2DShadow

Функция textureProj

Использование специального текстурного самплера sampler2DShadow позволяет изменить логику работы некоторых функций для работы с текстурой, а использование функции textureProj позволяет получить значение текселя текстуры с коррекцией текстурных координат. При передаче в функцию textureProj в качестве текстурных координат 3х компонентного вектора для получения текселя она использует первые два компонента деленные на третий. Это позволит нам получить корректное значение карты глубины с учетом глубины фрагмента относительно камеры источника освещения.

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

glTexParameteri (GL_TEXTURE_2D,_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);

Использование этого параметра позволяет производить автоматический тест на затенение (shadow test), это происходит когда мы вызываем функцию textureProj. В случае если глубина фрагмента с координатами smccord больше чем в текстуре глубины depthTexture функция textureProj вернет 1.0, иначе она вернет 0.0. Итоговый фрагментый шейдер:

// текстурный самплер карты глубиныsampler2DShadow depthTexture;

// параметры точеченого источника освещенияstruct Light

{ambient;diffuse;specular;position;

} light;

// параметры материалаstruct Material

{D texture;ambient;diffuse;specular;emission;shininess;

} material;

// параметры полученные из вершинного шейдера

in Vertex

{texcoord;smcoord;normal;lightDir;viewDir;

} Vert;

(location = FRAG_OUTPUT0) out vec4 color;

void main(void)

{

// нормализуем полученные данные для коррекции интерполяции

vec3 normal = normalize (Vert.normal);lightDir = normalize (Vert.lightDir);viewDir = normalize (Vert.viewDir);

// коэффициент затененияshadow = textureProj (depthTexture, Vert.smcoord);

// добавим собственное свечение материала= material.emission;

// добавим фоновое освещение+= material.ambient * light.ambient;

// добавим рассеянный светNdotL = max (dot(normal, lightDir), 0.0);

color += material.diffuse * light.diffuse * NdotL;

// добавим отраженный светRdotVpow = max (pow(dot (reflect(-lightDir, normal), viewDir), material.shininess), 0.0);+= material.specular * light.specular * RdotVpow;

// вычислим итоговый цвет пикселя на экране с учетом текстуры

color *= texture (material.texture, Vert.texcoord) * shadow;

}

Для сглаживания краев тени в используется техника Percentage Closer Filtering (PCF). Данная техника заключается в том, что производится несколько тестов на затенение в окрестностях искомого фрагмента и для затенения используется среднее значение этих тестов, таким образом, граница тени будет более «мягкой».

Относительно описанного выше фрагментного шейдера эту технику можно использовать так:

// сглаживание границы тени, используем PCF с выборкой 3x3

float PCF (in vec4 smcoord)

{res = 0.0;+= textureProjOffset (depthTexture, smcoord, ivec2 (-1, - 1));+= textureProjOffset (depthTexture, smcoord, ivec2 (0, - 1));+= textureProjOffset (depthTexture, smcoord, ivec2 (1, - 1));+= textureProjOffset (depthTexture, smcoord, ivec2 (-1, 0));+= textureProjOffset (depthTexture, smcoord, ivec2 (0, 0));+= textureProjOffset (depthTexture, smcoord, ivec2 (1, 0));+= textureProjOffset (depthTexture, smcoord, ivec2 (-1, 1));+= textureProjOffset (depthTexture, smcoord, ivec2 (0, 1));+= textureProjOffset (depthTexture, smcoord, ivec2 (1, 1));

(res / 9.0);

}

// коэффициент затененияshadow = PCF (Vert.smcoord);

3.3        Пересчет кадра 3d-приложения

В связи с тем, что мы используем не статический, а динамический источник света а также динамическую камеру наблюдения и объекты, необходимо заново рассчитывать основные параметры для камеры, источника света и объектов. Алгоритм пересчета всех этих параметров представлен на рисунке 3.5. Блок 1 и 2 отвечают за изменение параметров объектов и их реализация выглядит:

// зададим углы поворота куба с учетом времени((torusRotation[0] += 30.0f * (float) deltaTime) > 360.0f)[0] -= 360.0f;((torusRotation[1] += 15.0f * (float) deltaTime) > 360.0f)[1] -= 360.0f;

((torusRotation[2] += 7.0f * (float) deltaTime) > 360.0f)[2] -= 360.0f;

// зададим матрицу вращения куба[1].rotation = GLFromEuler (torusRotation[0],[1],[2]);[2].rotation =GLFromEuler (-torusRotation[0],[1],

torusRotation[2]);

Рисунок 3.5. Алгоритм пересчета кадра 3D-приложения

Блок 3 и 4 отвечают за изменение параметров наблюдателя и их реализация выглядит:

// вращаем камеру(mainCamera, (float) deltaTime * rotateDelta[1], (float) deltaTime * rotateDelta[0], 0.0f);

// двигаем камеру(mainCamera, (float) deltaTime * moveDelta[0]*5, 0.0f, (float) deltaTime * moveDelta[1]*5);

[0] = rotateDelta[1] = 0;[0] = moveDelta[1] = 0;

Блок 5 и 6 отвечают за изменение источника света и их реализация выглядит:

// движение источника света= false;(directionalLight.position[0] < -50)

(directionalLight.position[0] > 50)= true;

(decLightPos).position += vec3 (-deltaTime*2, 0, 0);.position += vec3 (deltaTime*2, 0, 0);                  

(lightCamera, directionalLight.position, vec3 (0,0,0), vec3_y);[4].position = directionalLight.position;[4].position += vec3 (2,2,2);

4.     
Тестирование реализации 3
d приложения

Тестирование реализации 3D приложения будем производить на разных настройках карт теней. Изменять будем проекционную матрицу. Как известно из предыдущих разделов проекционная матрица задается функцией OrthoProjection (float left, float right, float bottom, float top, float zNear, float zFar).

Будем пропорционально увеличивать left, right, bottom, top для тестов 1-3, а для тестов 4 и 5 ZNear соотвествестно.

Тест 1

Значение параметров

left = -10.0f, right = 10.0f,

bottom = -10.0f, top = 10.0f,= 0.0f, zFar = 100.0

Рисунок 4.1 Результат теста 1

Тест 2

Значение параметров

left = -50.0f, right = 50.0f,

bottom = -50.0f, top = 50.0f,

zNear = 0.0f, zFar = 100.0

Рисунок 4.2 Результат теста 2

Тест 3

Значение параметров

left = -100.0f, right = 100.0f,

bottom = -100.0f, top = 100.0f,

zNear = 0.0f, zFar = 100.0

Рисунок 4.3 Результат теста 3

Тест 4

Значение параметров

left = -10.0f, right = 10.0f,

bottom = -10.0f, top = 10.0f,

zNear = 20.0f, zFar = 100.0

Результат теста 4 при параметрах -10.0f, 10.0f, -10.0f, 10.0f, 20.0f, 100.0f

Рисунок 4.4 Результат теста 4

Тест 5

Значение параметров

left = -10.0f, right = 10.0f,

bottom = -10.0f, top = 10.0f,

zNear = 60.0f, zFar = 100.0

Результат теста 5 при параметрах -10.0f, 10.0f, -10.0f, 10.0f, 60.0f, 100.0f

Рисунок 4.5 Результат теста 5

Исходя из тестов можно сделать следующие выводы:

1.       При увеличении параметры left, right, bottom, top происходит уменьше-ние доли занимаемой сцены в карте теней.

2.       Уменьшение доли занимаемой сцены в карте теней ведет к ухудшению качества тени

.        Увеличение параметра zNear при неизменном zFar и left, right, bottom, top ведет к увеличению четкости карты теней и следовательно качеству теней в итоговом изображении.

5.     
Технико-экономическое обоснование

5.1        Концепция экономического обоснования

Целью технико-экономического обоснования дипломной работы является разработка плана организации исследований выполняемых работ, обобщение организационно-экономических показателей и получение оценок эффективности проекта. Индустрия компьютерных игр, графические редакторы для дизайнеров и специалистов в области мультимедиа, навигационные программы и визуализация ландшафта местности, применяемая для разведки и освоения полезных ископаемых - все эти области требуют всё больших затрат оперативной памяти и ресурсов процессора для всё более качественных эффектов и детальной прорисовки моделируемых объектов в режиме реального времени. В свою очередь, рынок и научно-технический прогресс не стоит на месте, предлагая всё новые технологии и эффекты. В данном случае речь пойдёт о динамичес-ком освещении, ему и посвящена данная работа.

Для технико-экономического обоснования НИР выделены сле-дующие этапы:

определение трудоемкости проводимых в ходе дипломного проектирования работ и составление календарного плана выпол-нения работ;

составление сметы затрат на проведение работ;

оценка эффективности дипломной работы.

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

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

Все необходимые действия по выполнению данной НИР производились в составе научного сотрудника и инженера-программиста на кафедре МОЭВМ.

5.3        Смета затрат на проведение работ

Калькуляция себестоимости разработки осуществляется по следующим статьям:

материалы;

расходы на оплату труда;

отчисления на социальные нужды;

накладныерасходы;

прочие прямые расходы.

Затраты на израсходованные материалы приведены в таблице 5.3.1.

Таблица 5.3.1 Затраты на материалы

Материал

Количество, шт.

Стоимость единицы, руб.

Стоимость, руб.

Ч/б картридж для принтера

1

1800

1800

Бумага размера A4 для принтера, пачка

1

150

150

Комплектканцелярских принадлежностей

1

-

60

USBflash-накопительемкостью на 2 Гб

1

1

299

Транспортные расходы

7-10% от общих затрат на материалы

-

231

ИТОГО:

2540


Основная и дополнительная заработные платы непосредст-венных исполнителей проекта рассчитываются на основании трудо-емкости выполнения работ научным сотрудником Тр и инженером-программистом Ти, ставок научного сотрудника Др и инженера-программиста Ди и величины процента дополнительной заработной платы (12%):

Тр = 13 чел.-дн.;

Ти = 52 чел.-дн.;

Др = 24000 руб./мес.;

Ди = 12000 руб./мес.

Основная заработная плата исполнителей Сзо рассчитывается по формуле:

                                                  (1)

где число 22 - норматив рабочих дней в месяце.

Сзо = (13 Ч 24000 + 52Ч12000) = 42 545 руб.

Дополнительная заработная плата - заработная плата за неотработанное время, как правило, это «отпускные». Дополнительная заработная плата исполнителей Сдоп. рассчитывается по формуле:

                                                                       (2)

где число 0,12 - ставка дополнительной заработной платы.

Сдоп. = 42 545 Ч 0,12 = 5 105 руб.

Величина расходов на оплату труда составляет 47650 руб.

Рассчитаем величину отчислений во внебюджетные фонды. Она рассчитывается по формуле:

                                                                                 (3)

где Сзо - величина заработной платы; Hвф - суммарный процент отчислений во внебюджетные фонды составляет 26,2%.

Свф=42 545* 26,2/100 = 11 147 руб.

К прочим прямым расходам отнесем плату за Internet, приведенную для рабочего места на основе использованного Internet-трафика, а также абонентскую плату за телефон по данным кафедры, и сведем их к таблице 6.3.2.

Так как все работы по исследованию производились ни личном компьютере, то нет необходимости считать амортизационные отчисления для персональных компьютеров кафедры проведения исследовательских работ.

Таблица 6.3.2 Расходы, относящиеся к статье «Прочие прямые расходы»

Наименование

Сумма, руб.

Плата за Internet

1100

Абонентская плата за телефон

200

ИТОГО:

1300


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

Накладные расходы составляют 20% от оплаты труда и выплат во внебюджетные фонды:

                                                                        (4)

где Сзо - величина заработной платы; Свф - величина отчислений во внебюджетные фонды.

Снр = (42 545+11 147) * 0,2 = 10 738 руб.

Рассчитаем общую себестоимость проекта, для чего все предыдущие вычисления сведем в одну таблицу 5.3.3.

Таблица 5.3.3 Смета затрат на проведение НИР

Наименование статьи расходов

Сумма, руб.

Материалы

2 540

Расходы на оплату труда

47650

Внебюджетные фонды

11 147

Прочие прямые расходы

1 300

Накладные расходы

10 738

Итого:

73375

5.4        Комплексная оценка эффективности внедрения программы

 

Разработанный программный продукт можно использовать в качестве обучающего материала на кафедре МОЭВМ в течении года, что принесет экономию средств в размере 32000 р.

Вышеуказанная сумма получилась после того, как было взято общее количество занятий в год и подсчитаны расходы на материалы (на бумагу и другие канцтовары).

Коэффициент эффективности (32000/73375= 0.415) или 43.6%. Таким образом, средства будут окуплены примерно через два года, или более точно (100/43.6=2. года).



Заключение

Разработана и реализована архитектура библиотеки классов, способная отрисовывать любые трехмерные сцены с использованием основных алгоритмов обработки. В библиотеке реализованы следующие алгоритмы 3D-графики: освещение объекта (равномерное, диффузное, бликовое), текстурирование, Shadow Mapping, вывод в квадрат любой текстуры, создание и управление навигацией камеры, загрузка и визуализация сложных 3D моделей, настройка материалов, загрузка, выгрузка и передача данных в шейдеры. Создано демонстрационное приложение с использованием этой библиотеки. Кроме того, данный набор библиотек может служить основой для разработки коммерческой системы моделирования, а само приложение может быть использовано в качестве учебного материала по дисциплине компьютерная графика.

Список использованных источников

1. Горнаков С.Г. DirectX 9: «Уроки программирования на С++». - СПб.: БХВ-Петербург, 2005. - 400 с.

2. Программирование игр на платформе XNA [Электронный ресурс]. - Режим доступа: http://www.xnadev.ru свободный.

3. Luna, Frank D. Introduction to 3D game programming with DirectX 9.0. - Wordware Publishing, Inc, 2003. - 421 p.

4. ixbt.com [Электронный ресурс]. - Режим доступа: http://www.ixbt.com свободный.

5. Blinn, James F. Simulation of Wrinkled Surfaces // Computer Graphics, Vol. 12 (3), pp. 286-292, SIGGRAPH-ACM (August 1978).

6. Dempski, Kelly and Viale, Emmanuel, Advanced Lighting and Materials with Shaders // Wordware Publishing Inc., 2005, 361 p.

7. Программирование игр [Электронный ресурс]. - Режим доступа: http://www.gamedev.ru свободный.

8. Nitschke B. Professional XNA Game Programming: For Xbox 360 and Windows - Wrox Press, 2007. - 504 p.

9. Krishnamurthy and Levoy, Fitting Smooth Surfaces to Dense Polygon Meshes // SIG-GRAPH 1996.

10. Guardado, Juan, NVIDIA, GPU Gems, 2004 by NVIDIA Corporation.

11. Pharr, Matt and Fernando, Randima, NVIDIA, GPU Gems 2: Programming Techniques for High-Performance Graphics and General-Purpose Computation, 2005, by Addison-Wesley Professional, 880 p.

12. Cook, Robert L., Shade trees // Proceedings of the 11th annual conference on Computer graphics and interactive techniques, p. 223-231, January 1984, SIGGRAPH-ACM.

13. Phong, Bui-Tuong, Illumination for computer generated images // Comm. ACM 18, 6 (June 1975) 311-317.

14. Blinn, James F., Models of Light Reflection for Computer Synthesized Pictures // Computer Graphics, Vol. 11, No. 2, July, 1977, 192-198.

15. Krishnamurthy and Levoy, Fitting Smooth Surfaces to Dense Polygon Meshes // SIG-GRAPH 1996

16. Cohen et al., Appearance-Preserving Simplification // SIGGRAPH 1998

17. Cignoni et al., A general method for recovering attribute values on simplifed meshes // IEEE Visualization 1998

18. Oliveira, Manuel M.; Bishop, Gary; McAllister, David, Relief texture mapping // International Conference on Computer Graphics and Interactive Techniques archive, proceedings of the 27th annual conference on Computer graphics and interactive techniques, Pages: 359 - 368, 2000.

19. Kaneko, T., et al., Detailed Shape Representation with Parallax Mapping // In Proceedings of ICAT 2001, pp. 205-208, 2001.

20. Crow, F., Shadow algorithms for computer graphics, // SIGGRAPH, vol. 11, 242-248, 1977.

21. Roth, Scott D., Ray Casting for Modeling Solids // Computer Graphics and Image Processing 18: 109-144, doi:10.1016/0146-664X(82) 90169, February 1982.

22. Jensen, Realistic Image Synthesis Using Photon Mapping // AK Peters, July 2001.

23. Williams, Lance; Casting curved shadows on curved surfaces // SIGGRAPH-ACM, Volume 12, Issue 3 (August 1978), pp: 270 - 274., 1978.

24. Spencer, Greg; Shirley Peter; Zimmerman, Kurt; Greenberg, Donald P.; Physically-based glare effects for digital images // SIGGRAPH: 325. doi:10.1145/218380.218466., 1995.

25. Debevec, Paul E. and Malik Jitendra, Recovering High Dynamic Range Radiance Maps from Photographs // SIGGRAPH, 1997.

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

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!