<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated on Wed, 25 Nov 2009 07:09:46 -0800 -->
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <atom:link href="http://software.intel.com/ru-ru/articles/graphics/type/technical-article/feed/" rel="self" type="application/rss+xml" />
    <title>Intel Software Network articles фид</title>
    <link>http://software.intel.com/ru-ru/articles/graphics/technical-article/</link>
    <description></description>
    <language>ru-ru</language>
    <item>
      <title>Обзор методов программного моделирования пламени</title>
      <description><![CDATA[ <h2>Введение</h2>
<p>Демонстрационная программа <a href="http://software.intel.com/ru-ru/articles/smoke-game-technology-demo/">Smoke</a> (Дым) создана  для демонстрации возможностей масштабируемой многопоточной архитектуры игровых  движков.  Приложение Smoke использует новую  концепцию программной генерации огня. Сцена игры представляет собой ферму, на  которой расположены деревья, сельхозтехника, сараи, а также управляемые  искусственным интеллектом животные - лошади, цыплята и ласточки. Пламя,  возникающее от метеоритного дождя, реалистично распространяется по кронам  деревьев, перекидываясь с дерево на дерево и с ветки на ветку. Задача игрока -  быстро потушить огонь.</p>
<p>Рассмотрим механизмы создания  реалистичного пламени, его взаимодействия с объектами игровой сцены и водой.  Вы можете <a href="http://software.intel.com/ru-ru/articles/smoke-game-technology-demo-download">скачать исходный код </a>Smoke. Инструкции по сборке приложения находятся в подкаталоге smoke\docs архива с исходным кодом.</p>
<h2>Моделирование пламени</h2>
<p>Специалисты компьютерной графики  обратили внимание на тот факт, что рендеринг пламени в 3D как правило  обходится без моделирования физических свойств огня. Природная случайность и  турбулентность пламени часто моделируется с помощью систем частиц на основе  хорошо известных шума Перлина и распределения Гаусса. Это позволяет достигнуть адекватного  эффекта без учета физических свойств пламени, особенно если в сцене присутствует  более одного источника огня.</p>
<p>«Smoke» также  использует традиционную систему частиц, но при этом используется дополнительная  система, в которой огонь рассматривается как источник тепла. Этот тепловой  излучатель учитывает такие аспекты как распространение огня по горючим  материалам, его интенсивность в конкретной точке, взаимодействие источников тепла  с соседними источниками горючего.</p>
<h2>Реализация</h2>
<h2 class="sectionHeading">Объекты в Smoke</h2>
<p>Архитектура Smoke [2] использует различные  компоненты, которые мы будем называть «системы»,  которые выполняют типичные функции игрового  движка, такие как физика, графика, звук, искусственный интеллект и т.д.  Типичный игровой объект в Smoke является абстрактным объектом, привязанным  к нескольким системам. Например, лошадь на «Дымной» ферме привязана к следующим  системам:</p>
<ul>
<li>Графика скелетной анимации и  анимации модели</li>
<li> Геометрия позиционирования и  ориентации в пространстве</li>
<li> Физика обнаружений и контроля  столкновений</li>
<li> Звуковые эффекты</li>
</ul>
<p>Подобная структурная логика применима  ко всем объектам сцены, например, к падающим с неба метеорам, которые также  используют системы графики, физики, звука, плюс систему огня. Система огня отвечает  за физические свойства огня в программе и его графическое представление.</p>
<h2 class="sectionHeading">Система огня</h2>
<p><b>«Умные» частицы</b></p>
<p>Система огня состоит из двух  частей: эмиттер частиц на основе системы частиц, описанной в [1], которая  включает плоские текстуры пламени (частицы огня) и систему источника тепла,  которая моделирует тепловые свойства огня (тепловые частицы).</p>
<table align="center" border="0">
<tbody>
<tr>
<td align="center" width="200">Частицы огня</td>
<td align="center" width="200">Тепловые частицы</td>
</tr>
<tr>
<td style="text-align: center;"><img title="fire.JPG" src="http://software.intel.com/file/14812" alt="Частицы огня" /></td>
<td style="text-align: center;"><img title="heat.JPG" src="http://software.intel.com/file/14813" alt="Тепловые частицы" /></td>
</tr>
</tbody>
</table>
<p>Источник топлива, такой как  дерево, как правило, является достаточно сложным объектом, состоящим из  множества ветвей и розеток листьев. Хотя каждый геометрический объект может служить  источником топлива, в том числе метеоры. Таким образом, каждая ветка и розетка дерева  может служить носителем для системы частиц огня. Система использует выровненный  по осям ограничивающий блок (ВООБ, AABB = axis-aligned bounding box) носителя  не только для того, чтобы определять, где должны располагаться видимые частицы  огня, но и для проверки на столкновение частиц в источнике тепла. Как и при  настоящем пожаре, тепло распространяется вверх и в стороны от источника,  перемещаясь к вершине дерева с ветки на ветку, достигает вершины и затем  спускается вниз по кроне, как показано на рис. 1.</p>
<p><img src="http://software.intel.com/file/14814" alt="Система умных частиц – определение источника топлива" width="746" height="523" /></p>
<p><i>Рис. 1. Система умных частиц –  определение источника топлива</i></p>
<p><b>Распространяющийся огонь.</b></p>
<p>Метеоры – единственные объекты в  сцене, которые горят изначально, падая с неба и проходя через деревья или рядом  с ними. Деревья состоят из веток и розеток листьев, каждая из которых  представляет индивидуальный геометрический объект. Метеоры являются носителями  для системы огня, и, пролетая через сцену, некоторые из них проходят рядом с  элементами, также ассоциированными с системой огня. Если такой объект пока не  горит, алгоритм отслеживания столкновений системы огня зажжет его,  распространяя огонь по всему дереву и, возможно, на другие деревья сцены.<br /> Обнаружение столкновений  источников тепла является ресурсоемким вычислительным процессом, который хорошо  вписывается в параллельную архитектуру, ориентированную на задачи и специально разработанную  с учетом многоядерных процессоров. Каждый горящий объект содержит несколько  отдельных языков пламени, которые входят в видимую систему частиц и физическую  частицу источника тепла. В терминах обнаружения столкновений, частица огня представляет  собой луч, который и проверяется на пересечение с соседним ВООБом источника  топлива. Длина этого луча определяет температуру пламени. Объекты вне радиуса  действия этого луча исключаются из расчетов.</p>
<p><img src="http://software.intel.com/file/14815" alt="Система умных частиц – обнаружение столкновений" width="746" height="523" /></p>
<p><i>Рис. 2. Система умных частиц –  обнаружение столкновений</i></p>
<p>На рис. 2 показано, как  столкновение источника тепла с веткой «помечает» ее как горящую. Это активирует  излучатель видимых частиц и тепла этого объекта, позволяя огню  распространяться. Процесс продолжается до тех пор, пока огнем не будут охвачены  все источники топлива в пределах радиуса действия.<br /> Каждый горящий объект проверяется  на соприкосновение с соседними источниками топлива и тепла. Рассмотрим алгоритм  этой проверки в псевдо-коде:</p>
<pre name="code" class="plain:nogutter:nocontrols">For each Fire Object (each tree)<br /><br />For each Fire in  all Fire Objects (each branch)<br /><br />For each Heat  Emitter in each fire<br /><br />Check for  collision against the list of fuel sources<br /><br />If collision,  mark object as burning</pre>
<p>Внутренняя часть кода выполняет  тест на пересечение тепловых лучей источника тепла в дереве А и ветки дерева Б.  Поскольку тепловые частицы принадлежат источникам тепла в разных объектах, эти  горячие частицы переносятся в локальное пространство других геометрических  объектов, как показано на рис. 3.</p>
<p><img src="http://software.intel.com/file/14816" alt="Перенос и тест столкновения" width="746" height="481" /></p>
<p><i>Рис. 3. Перенос и тест столкновения</i></p>
<p><b>Параметры системы огня</b></p>
<p>Система огня использует набор  входных параметров для визуальной и теплоизлучающей систем частиц, которые определяют  специфичное поведение частиц:</p>
<ul>
<li> Тип (сферическое пламя  метеоров, линейное пламя веток, пламя неправильной формы для листьев)</li>
<li> Плотность огня</li>
<li> Размер (плоский)</li>
<li> Импульс</li>
<li> Сдвиг/импульс (изменение позиции  для определения направления пламени)</li>
<li> Время жизни</li>
</ul>
<p><b>Рендеринг огня, дыма и углей</b></p>
<p>Видимая система частиц, используемая  для рендеринга фрагментов огня, использует набор текстур, которые сменяют друг  друга пока частица существует, имитируя переход пламени в дым и искры. Искры вздымаются  над деревьями в виде факелов, реализованных в коде шейдера Ogre3D [3].</p>
<p><img src="http://software.intel.com/file/14817" alt="Огонь, дым и искры над  горящим деревом" width="746" height="560" /></p>
<p><i>Рис 4. Огонь, дым и искры над  горящим деревом</i></p>
<p><b>Вода</b></p>
<p>В приложении Smoke  имеется пожарный шланг, изображенный на рис.  5, который пользователь может «перетаскивать» по сцене, чтобы потушить огонь.</p>
<p>Как было отмечено в предыдущих  параграфах, каждый объект, в нашем случае – объект, привязанный к  геометрическому объекту дерева, проверяется, на столкновение (соприкосновение)  с каким-нибудь из источников тепла, в том числе с соседними негорящими ветвями.  Вода является естественным расширением системы огня, использующим дополнительные  проверки в коде обнаружения столкновений для тушения горящих элементов и  предотвращения распространения огня на соседние объекты.</p>
<p><img src="http://software.intel.com/file/14818" alt="Система огня – Вода" width="746" height="579" /></p>
<p><i>Рис. 5. Система огня – Вода</i></p>
<p>Так же как метеоры используют привязанную  к ним систему огня, настроенную в качестве источника тепла на поджог огня,  невидимые холодные объекты используют систему огня как источник холода, которые  вступают в соприкосновения с другими объектами системы огня. В Smoke используется  плагин ParticleFX из пакета Ogre3D [3] для скриптовой системы частиц. Контроль  столкновений происходит посредством системы огня,  привязанной к невидимым объектам, выпускаемым  с позиции камеры как скорострельные снаряды. Когда водяной объект проходит мимо  или сталкивается с горящим объектом, присоединенная система огня определяет, не  пересекает ли этот горящий объект какой-либо холодный луч, гася огонь.</p>
<p>Дополнительный плюс этого эффекта  в том, что невидимый объект воды также привязан к физической системе Havok [4],  что позволяет воде взаимодействовать с разрушаемыми элементами сцены, например  строениями.</p>
<h2>Заключение</h2>
<p>Демонстрационное приложение Smoke реализует  оригинальный подход к программному моделированию распространяющегося пламени,  включая графические и физические системы частиц, которые могут  взаимодействовать со сценой. Такая концепция прекрасно подходит для  произвольных объектов сцены, особенно в сочетании с параллельной архитектурой  игрового движка, который позволяет распределить трудоемкие расчеты столкновений  объектов между имеющимися в потоками.</p>
<p><b>Исходный код</b></p>
<p><a href="http://software.intel.com/ru-ru/articles/smoke-game-technology-demo-download">Исходные коды Smoke</a> доступны для загрузки. Инструкции по сборке находятся в zip архиве с исходным кодом в директории Smoke\docs.</p>
<p><b>Планы на будущее</b></p>
<p>Текущая версия системы огня не содержит  несколько эффектов, которые могут быть добавлены в будущем:</p>
<ul>
<li> Разрушение горящих объектов с  течением времени</li>
<li> Повторное возгорание потушенных  объектов</li>
<li> Добавление наложений или  изменение текстур горящих и сгоревших объектов.</li>
</ul>
<h2>Ссылки</h2>
<p>[1] [Luna06]  Frank Luna. Introduction to 3D Game Programming with DirectX 9.0c: A Shader <br /> Approach.  Wordware Publishing Inc. <br /> [2] [Smoke08]  Ryan Shrout. “A Smoke Screen from Intel: Implementing multi-threaded <br /> gaming”. Intel  2008. <br /> [3] [Ogre3D08]  Ogre3D Open Source Object-Oriented Graphics Rendering Engine <br /> <a href="http://www.ogre3d.org/">http://www.ogre3d.org</a>. <br /> [4] [Havok08]  Havok Physics <a href="http://www.havok.com/">http://www.havok.com</a>.</p>
<h2>Об авторах</h2>
Хью Смит (Hugh Smith) старший  программист в группе Software Services Group, работает с независимыми производителями  игровых программ по внедрению оптимизации для графических и многоядерных систем  Интел в ведущие игровые продукты. Его электронный адрес<br /> hugh.a.smith в домене intel.com.
<p> </p>
<p>Джефф Фримен (Jeff Freeman)  программист в группе Software Solutions Group, где он работает с графическими  решениями Интел в отделе Visual Computing Software Division. Имеет степень  бакалавра компьютерных наук от Rensselaer Polytechnic Institute. Его  электронный адрес <br /> jeffrey.m.freeman в домене intel.com.</p>
<h2>Дополнительные изображения</h2>
<p><img src="http://software.intel.com/file/14819" width="746" height="560" /></p>
<p><img src="http://software.intel.com/file/14820" width="746" height="560" /></p>
<p><img src="http://software.intel.com/file/14821" width="746" height="560" /></p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/an-overview-of-procedural-fire</link>
      <pubDate>Mon, 03 Aug 2009 02:37:24 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/an-overview-of-procedural-fire#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/an-overview-of-procedural-fire</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Производительность игровой физики на архитектуре Larrabee</title>
      <description><![CDATA[ <p><a href="#p1"><strong>Введение</strong><br /></a><a href="#p2"><strong>Модели эмуляции игровой физики</strong></a><br /><a href="#p3"><strong>Многоядерная архитектура Larrabee</strong></a><br /><a href="#p4"><strong>Перенесение моделей игровой физики на платформу Larrabee</strong></a><br /><a href="#p5"><strong>Выводы</strong></a><br /><a href="#p6"><strong>Ссылки</strong></a></p>
<h2>Аннотация</h2>
<p>Игровая физика лежит в самом сердце любого современного игрового движка и используется для эмуляции естественных движений и взаимодействий объектов, твердых и гибких тел, одежды, воды. Приложения, рассчитывающие физику, очень интенсивно задействуют процессор и память. Стремление к повышенной степени реализма требует более сложных алгоритмов и больших объемов данных. Чтобы удовлетворить растущие требования программ, нужна компьютерная архитектура с высокой скоростью вычислений с плавающей точкой и быстрой шиной памяти. К счастью, современные многоядерные архитектуры общего назначения уже практически превзошли эти требования. Larrabee является одной из таких многоядерных архитектур. Она состоит из массива ядер архитектуры Интел, каждое из которых усилено 16-элементным векторным процессором. В данной статье мы проанализируем несколько игровых приложений и покажем, как расширенный параллелизм потоков и данных в Larrabee сочетается с большим количеством физических алгоритмов, как эти алгоритмы можно распараллелить и перенести на архитектуру  Larrabee и, следовательно, получить хороший прирост производительности.</p>
<a name="p1" id="p1"></a>
<h2>Введение</h2>
<p>Растущий рынок компьютерных игр подогревает стремление разработчиков графики к достижению все большего реализма, правдоподобия и скорости. За последнюю декаду эмуляция игровой физики стала ключевым моментом достижения реализма, которого требуют геймеры.</p>
<p>Высокая степень реализма, однако, требует реалистичных взаимодействий между объектами игры. Например, мяч должен реагировать по-разному на столкновения с бетонной поверхностью и с травой. Физическая симуляция мяча должна учитывать эту разницу в физических свойствах (трение, жесткость и т.д.) этих двух поверхностей и их воздействие на движение мяча. Пушечный снаряд, при попадании в кирпичное здание, должен заставлять отдельные кирпичи падать и, возможно, обрушиться все здание. Тяжелый предмет, брошенный в воду, должен производить брызги и волны, которые должны успокаиваться через некоторое время. Достижение желаемой степени реализма в физических симуляциях требует сложных математических моделей, которые превращаются в жадные до вычислений алгоритмы. По мере роста размеров сцены и увеличения количества объектов, соответственно увеличивается вычислительная сложность и объем структур данных. Эти два фактора делают работу в реальном времени (по меньшей мере 30 FPS, фреймов в секунду) труднодостижимой без использования достаточных аппаратных ресурсов.</p>
<p>Однако, стандартные многоядерные архитектуры быстро приближаются к уровню, который соответствует и даже превосходит этот уровень требований. Larrabee [Seiler et al 2008] является одной из таких высокопоточных многоядерных архитектур. Она состоит из массива процессорных ядер IA Intel, каждое из которых расширено 16-элементным векторным процессором.</p>
<p>В этой статье мы рассмотрим несколько моделей, которые используются для расчета разных типов эмуляции физики в современных играх. Затем кратко коснемся архитектуры Larrabee. В заключение расскажем, как нужно распараллеливать приложения и переносить их на архитектуру Larrabee, чтобы получить должное ускорение. Отдельно остановимся на методах, которые мы использовали для расчета игровой физики, представленной на рис 17 из [Seiler et al 2008]. В общих словах, параллелизм потоков и данных и стандартная процессорная архитектура Larrabee хорошо подходят для множества физических алгоритмов. В данной статье мы показали, как на LRB можно запускать алгоритмы расчета игровой физики. Отдельные реализации игровой физики для РС не вошли в эту статью. Дополнительные детали по производительности и архитектурным особенностям при обработке игровой физики на Larrabee обсуждались в [GamePhysics08].</p>
<a name="p2" id="p2"></a>
<h2>Модели эмуляции игровой физики</h2>
<p>В этом разделе мы рассмотрим высокоуровневую модель развивающейся во времени физической симуляции и несколько основанных на этой модели приложений, рассчитывающих игровую физику. Описание основывается на [Chen07]. На рис. 1 показан типичный процесс физической симуляции. На каждом шаге времени приложение физической симуляции использует на входе состояние сцены (позиция, ориентация, скорость всех объектов), и данные с внешних датчиков (например, показывающих, какие действия выполняет игрок). Приложение рассчитывает физические процессы, которые формируют обновленное состояние (силы, моменты или давление). В зависимости от схемы, эти данные используются для развития сцены во времени (например, с помощью законов движения). Если возникают различные феномены, типа столкновений, то состояние обновляется в зависимости от этих феноменов, и заново рассчитываются силы и повторяются временные фазы, возможно, с меньшим шагом времени.</p>
<p><img height="313" width="321" src="http://software.intel.com/file/18839" alt="Обзор физической эмуляции" /></p>
<p><em>Рис.1. Обзор физической эмуляции.</em></p>
<p>Приведем несколько примеров важных приложений симуляции игровой физики, основанных на процессе, приведенном выше.</p>
<h3 class="sectionHeading">Игровые флюиды с помощью сглаженной гидродинамики частиц</h3>
<p>Сглаженная гидродинамика частиц (СГЧ, Smoothed Particle Hydrodynamics, SPH), как техника интерактивной симуляции флюидов, возникла относительно недавно [Muller2003]. Метод СГЧ рассматривает флюид как набор отдельных частиц и правил их сопротивления изменению плотности: если частицы располагаются слишком близко, силы отталкивания раздвигают их, если они разлетаются слишком далеко, силы притяжения стягивают их обратно. Если пара частиц расположены достаточно далеко друг от друга, между ними не возникает никакой силы. СГЧ дифференцирует уравнения Навье-Стокса (Navier-Stokes) и находит решения для конечного числа частиц в пространстве и времени. В решеточном (grid) методе позиция контрольных точек фиксирована, в случае СГЧ частицы свободно перемещаются в пространстве. Разница фундаментально меняет принцип решения уравнений Навье-Стокса и обычно сильно упрощает его реализацию, делая СГЧ более пригодным для интерактивного окружения.</p>
<p><img height="222" width="374" src="http://software.intel.com/file/18840" alt="Пространственная структура данных для СГЧ" /></p>
<p><em>Рис. 2. Пространственная структура данных для СГЧ.</em></p>
<p>Для отслеживания движений соседних частиц и расстояния их друг от друга, иногда используют структуры данных ускорений. Например, может использоваться равномерная решетка, тогда частицы на каждом шаге симуляции попадают в клетки решетки одинакового размера <em>h</em>. Чтобы найти всех соседей данной частицы, всего лишь нужно проверить все частицы в окружающих клетках.</p>
<h3 class="sectionHeading">Эмуляция ткани</h3>
<p><img height="305" width="342" src="http://software.intel.com/file/18841" alt="Пространственные связи в ткани" /></p>
<p><em>Рис. 3. Пространственные связи в ткани</em></p>
<p>Модели игровой физики рассматривают ткань как набор частиц [Jacobes2001]. Каждая частица подвергается внешним воздействиям, таким как гравитация, ветер, растяжение и другие силы. Как показано на рис. 3(а), для поддержания формы объекта используются пружинные связи, а для предотвращения взаимопроникновения с окружением используются реакции на столкновение. Уравнение движения частицы, образующееся при применении внешних сил, получается с помощью Верлетовского (Verlet) интегрирования. Вышеупомянутые связи создают систему уравнений, соединяющих вместе позиции частиц. Эта система решается на каждом шаге симуляции с помощью релаксации, т.е. усиления связей за определенное число итераций. Это показано на рис. 3(б). Самостолкновения обычно игнорируются.</p>
<h3 class="sectionHeading">Эмуляция твердого тела</h3>
<p>Динамика твердого тела [Eberly2003] эмулирует движение и взаимодействие недеформирующихся объектов при наличии воздействия сил и вращающих моментов. Динамика твердого тела очень часто используется в игровой физике современных игр. Примерами твердых тел могут служить автомобили, куклы, подъемные краны, бочки, ящики и даже целые здания.</p>
<p>При традиционном подходе решается система дифференциальных уравнений, представляющих второй закон Ньютона, F=ma, где m масса объекта, a ускорение, F приложенная сила. Приложенная сила определяет ускорение объекта, так что скорость и позиция получаются с помощью интегрирования этого уравнения. Вычислительные трудности возникают потому, что движение твердого тела нарушается из-за взаимодействия с окружением. Например, рассмотрим разрушаемое окружение, где тысячи твердых объектов взрываются, разрушаются, сталкиваются, что выливается в сотни тысяч взаимодействий. Реалистичная симуляция такой сцены требует обнаружения столкновений (см. следующий раздел), вычисления точек соприкосновения, физически корректное вычисление сил, возникающих во время контакта. Полный процесс, демонстрирующий все шаги, необходимые для эмуляции твердого тела, приведен на рис. 4. Для ускорения определения столкновений используются структуры данных пространственных частиц, такие как гриды или иерархии окружающих объемов. Для определения сил при столкновении, контакт моделируется как линейная комплементарная задача [Baraff97].</p>
<p><img height="237" width="350" src="http://software.intel.com/file/18842" alt="Алгоритм расчета состояния твердого тела" /></p>
<p><em>Рис.4. Алгоритм расчета состояния твердого тела</em></p>
<h3 class="sectionHeading">Обнаружение столкновений</h3>
<p>Обнаружение столкновений является важным моментом  для всех упомянутых приложений и используется для определения, находятся ли два объекта в контакте, или проникают друг в друга, как частица и твердый объект, или взаимодействуют подобно твердому телу и ткани, или просто являются двумя твердыми телами [Ericson04].</p>
<p>Обнаружение столкновений состоит из больших (broad) и малых (narrow) фаз. Большие фазы определяют потенциально сталкивающиеся объекты, отбрасывая не сталкивающиеся пары. Малая фаза берет на входе потенциально сталкивающиеся пары (как выход большой фазы) и проверяет, действительно ли они сталкиваются, а также находит точки соприкосновения. В следующей стадии решатель связей использует эту информацию для расчета сил, необходимых для сопротивления тел взаимопроникновению (рис. 4).</p>
<p>Малая фаза обнаружения столкновений использует структуры данных ускорений, чтобы пространственно разделить эмулируемые объекты, так что затратный тест на столкновение проводится только для объектов, находящихся по соседству друг от друга. Существуют несколько алгоритмов для большой фазы. Самый используемый – sweep and prune (S&amp;P). S&amp;P сортирует начало и конец окружающего объема каждого объекта вдоль всех осей. Когда объекты двигаются, их окружающие объемы могут пересекаться (рис. 5). Если объемы по всем осям двух объектов пересекаются, то велика вероятность, что они столкнулись, и на малой фазе они проверяются алгоритмом обнаружения столкновений. Существует большое количество специализированных и оптимизированных реализаций алгоритма обнаружения столкновений малой фазы, такие как определение столкновения двух сфер или капсул. Однако определение столкновения более сложных выпуклых объектов обычно делается с помощью алгоритма GJK [Gilbert88]. Этот алгоритм итерационно вычисляет расстояние между двумя выпуклыми объектами, пока не найдет минимальное. В случае невыпуклых объектов можно (1) разбить объект на несколько выпуклых и затем применить метод для выпуклых, (2) представить геометрию как триангулярную поверхность и использовать общий алгоритм столкновения триангулярных сеток (mesh), что опять включает использование алгоритма столкновений выпуклых объектов.</p>
<p><img height="170" width="318" src="http://software.intel.com/file/18843" alt="Sweep and Prune" /></p>
<p><em>Рис. 5. Sweep and Prune (S&amp;P)</em></p>
<p><img height="212" width="355" src="http://software.intel.com/file/18844" alt="Схема многоядерной архитектуры Larrabee " /></p>
<p><em>Рис. 6. Схема многоядерной архитектуры Larrabee</em></p>
<a name="p3" id="p3"></a>
<h2>Многоядерная архитектура Larrabee</h2>
<p>Larrabee (см. рис. 6) это многоядерная архитектура Интел, спроектированная в расчете на использование большого количества ядер. На этой архитектуре можно запускать большое число параллельных приложений, таких как 3D рендеринг, игровая физика, обработка медицинских изображений, и другие высокопроизводительные вычисления. Каждое ядро Larrabee поддерживает полный набор инструкций х86. Каждое ядро имеет короткий очередный (in-order) конвейер инструкций, разделяемый между потоками. Аппаратная часть может переключать потоки так, чтобы исполнялись инструкции, готовые к использованию, и останавливает другие потоки, которые находятся в состоянии ожидания своих данных (например, в ситуациях взаимной зависимости данных (back-to-back data dependence), или промаха кеша первого уровня). Как результат, повышенная латентность некоторых потоков прячется за полезной работой других потоков.  Анализ большого количества параллельных приложений говорит, что аппаратная поддержка многопоточности – это хороший компромисс между сложностью аппаратной части и повышением производительности многопоточных приложений.</p>
<p>Хотя архитектура Larrabee имеет очень быструю систему памяти, для снижения суммарных требований сразу многих приложений каждое ядро имеет кэш первого уровня с низкой латентностью. Большой общий полнокогерентный L2 кэш равномерно распределен между ядрами, каждое ядро имеет быстрый доступ к своей части, а для доступа к остальным частям кэша используется системная шина.</p>
<p>Каждое ядро дополнено 16-элементным векторным конвейером (16-wide vector pipeline unit, VPU), который обрабатывает целочисленные и с плавающей точкой единичной точности векторные инструкции. Хорошо известно, что два фундаментальных фактора ограничивают векторную эффективность: (1) контроль потока и (2) непрямой доступ к памяти. Larrabee предоставляет аппаратную поддержку обоих моментов.</p>
<p>Чтобы справиться с контролем потока, каждая инструкция может использовать регистр масок для указания, в какой вектор или адрес памяти будет производиться запись, а какие останутся неизмененными. Существуют команды управления масками, которые устанавливают содержание регистра масок. Чтобы освоить непрямой доступ к памяти, в Larrabee включены инструкции gather/scatter, которые читают и пишут в непрерывные адреса памяти, используя адрес из вектора адресов. 16 элементов могут загружаться или сохраняться в 16 различных адресах памяти. Скорость работы загрузки/сохранения зависит от кэша, который дает доступ к одной линии за такт, что в худшем случае требует 16 доступов к кэшу. Но если данные располагаются на одной линии кэша, что нередко случается во многих графических и других задачах, все эти элементы могут быть загружены за один доступ к L1 кэшу, существенно повышая производительность приложения.</p>
<p><img height="188" width="580" src="http://software.intel.com/file/18845" alt="Характеристики параллелизма" /></p>
<p><em>Рис. 7. Характеристики параллелизма</em></p>
<a name="p4" id="p4"></a>
<h2>Перенесение моделей игровой физики на платформу Larrabee</h2>
<p>Все программы игровой физики выигрывают от высоких вычислительных возможностей архитектуры Larrabee и мощной ISA. В этом разделе мы расскажем, как можно распараллелить приложения, для использования параллелизма Larrabee, как уровня потоков, так и уровня SIMD.</p>
<p>Рис. 7 отображает высокоуровневую характеристику параллелизма уровня потоков и SIMD в разных модулях игровой физики. В конце данного раздела приведена дискуссия о параллелизме и объясняется эта характеристика.</p>
<h3 class="sectionHeading">Очевидный параллелизм</h3>
<p>Для многих игровых движков параллелизм уровня потоков и SIMD является очевидным путем. Например, множественные независимые итерации в цикле легко распределяются на потоки с помощью прагм OpenMP [OpenMP05]. В случае SIMD, вычисления на каждой итерации преобразуются в векторный код с помощью векторизующего компилятора.</p>
<p><img height="104" width="352" src="http://software.intel.com/file/18846" alt="Использование TLP в детекторе столкновений" /></p>
<p><em>Рис. 8. Использование TLP в детекторе столкновений.</em></p>
<p>Алгоритмы обнаружения столкновений являются примерами блоков игровой физики, которые распараллеливаются тривиально. Например, sweep and prune алгоритм большой фазы может обрабатывать объекты абсолютно параллельно, а в алгоритме обнаружения столкновений малой фазы пары объектов абсолютно независимы. Работа этих двух алгоритмов может легко распределяться на потоки с помощью OpenMP (см. рис. 8). Также, как и алгоритм движения частиц, который рассчитывает следующую позицию частицы на основе текущей позиции и данных о приложенных силах – это простой цикл, перебирающий элементы массива и выполняющий над ними элементарные вычисления. Так что все это векторизуется тривиально.</p>
<h3 class="sectionHeading">Синхронизация потоков и программная блокировка</h3>
<p><img height="161" width="346" src="http://software.intel.com/file/18847" alt="Декомпозиция решеток в СГЧ" /></p>
<p><em>Рис. 9. Декомпозиция решеток в СГЧ</em></p>
<p>Некоторые физические алгоритмы при распараллеливании требуют применения синхронизации между несколькими потоками. Обычно для этого используются программные блокировки, гарантирующие взаимное исключение. Например, алгоритм для построения пространственной структуры данных ускоряющихся соседних объектов обращается к частицам СГЧ (см. раздел о игровых флюидах) с целью получения данных обо всех частицах, что требует блокировки взаимного исключения. В нашем случае каждый поток действует на своем локальном наборе частиц. Поток переносит частицы в соответствующие соседние клетки решетки. Поскольку каждая клетка может содержать более одной частицы, несколько частиц добавляются в начало связанного списка. Вставка частиц в одну клетку несколькими потоками требует применения блокировки взаимного исключения, чтобы только один поток мог обновлять список за раз. В таких случаях SIMD параллелизация используется в каждой итерации отдельно, а не совместно, как можно делать, когда все итерации независимы. В другом случае, алгоритм, вычисляющий силы, также является частью приложения игровых флюидов. Здесь каждая частица в клетке решетки обновляет состояние других частиц, которые находятся на определенном расстоянии от нее. Может случиться так, что несколько частиц в той же или другой клетке захотят обновить одну и ту же частицу. В случае, если частицы обрабатываются разными потоками, для корректного выполнения требуется блокировка взаимного исключения, чтобы гарантировать, что только один поток обновляет частицу в данный момент времени. Установка и снятие блокировок на каждую клетку решетки выливается в большие производственные издержки. Чтобы их сократить, мы разбиваем решетку на несколько больших кусков, каждый из которых назначается своему потоку, как изображено на рис. 9. Обновление внутри одного куска решетки гарантированно производится одним потоком и не требует синхронизации. В этом случае только пограничные клетки требуют обработки несколькими потоками и соответствующих блокировок. Размеры кусков грида могут быть настолько большими, что практически сведут к нулю издержки на синхронизацию.</p>
<h3 class="sectionHeading">Аппаратная поддержка SIMD</h3>
<p>Существует подкласс приложений  игровой физики, который в больших объемах использует SIMD параллелизм, но для эффективной работы требует специальной аппаратной поддержки, которая присутствует в архитектуре Larrabee.</p>
<p><img height="536" width="365" src="http://software.intel.com/file/18848" alt="Использование масок в детекторе столкновений малой фазы" /></p>
<p><em>Рис. 10. Использование масок в детекторе столкновений малой фазы.</em></p>
<p>Известно, что основными проблемами эффективности SIMD являются контроль потока и непрямой доступ к памяти. Если в оригинальном скалярном коде есть ветвления, то, чтобы перевести такой код в SIMD необходимо использовать условные операции SIMD. Larrabee предоставляет возможность условного исполнения команд SIMD с помощью векторной битовой маски. Для каждой команды SIMD маска указывает, какие операнды нужно игнорировать.</p>
<p>Маски SIMD приходятся очень кстати во многих алгоритмах обнаружения столкновений малой фазы, таких как столкновения прямоугольников или GJK. Эти алгоритмы обычно содержат много проверок с ранним выходом, которые пытаются определить отсутствие столкновения двух объектов как можно раньше, чтобы избежать последующих интенсивных вычислений. На рис. 10(а) показан пример проверки с ранним выходом (earlyCDtest1 и earlyCDtest2), проверки столкновения между двумя объектами выполняются последовательно. Если оба теста возвращают значение «ложь», то это значит, что объекты столкнулись и запускается программа обнаружения точек контакта getcontactpoints.</p>
<p>Чтобы перевести этот код в Larrabee 16-элементный SIMD, мы выполняем проверку одновременно на 16 парах, используя 16-элементные команды SIMD, как показано на рис. 10(б). Проверки столкновений превращаются в операции, которые устанавливают биты маски, F0 и F1 (рис. 10(в)). Если проверка с ранним выходом выдает результат FALSE, то соответствующий бит маски сбрасывается в 0. Остальная часть кода прочитает нулевое значение маски, что будет означать, что никаких дополнительных проверок этой пары не требуется. Код вычисления точек контакта блокируется маской F1. Если она равна 0, то это значит, что одна из предыдущих проверок совершила ранний выход и, таким образом, результат вычислений не должен менять содержимого структуры данных соответствующей пары. Хотя такой подход означает неэффективное использование команд SIMD в случаях, когда большинство масок равно 0, но он приводит к существенной векторизации кода обнаружения столкновений. В большинстве случаев уровень использования SIMD достаточно высок из-за алгоритма большой фазы, который выкидывает большинство не сталкивающихся объектов – остающиеся объекты с большой вероятностью могут столкнуться и, скорее всего, пройдут ранние тесты. </p>
<p><img height="157" width="585" src="http://software.intel.com/file/18849" alt="Релаксация связей в решателе ткани" /></p>
<p><em>Рис. 11. Релаксация связей в решателе ткани.</em></p>
<p><img height="119" width="358" src="http://software.intel.com/file/18850" alt="Непрямой доступ в алгоритме обнаружения столкновений&lt;" /></p>
<p><em>Рис. 12. Непрямой доступ в алгоритме обнаружения столкновений</em></p>
<p>Традиционно, при программировании аппаратных SIMD векторов, операнды и результаты должны группироваться вместе последовательно в памяти. Для большей эффективности они должны помещаться в выровненные структуры. На рис. 12(а) показан пример массива из 16 структур, по одной на каждую пару объектов, где в каждой структуре имеется три поля. Без аппаратной поддержки чтения векторов, эффективное использование команд SIMD требует перепаковки массива структур в формат структуры массивов. Как показано на рис. 12 (б), поля из разных структур пакуются вместе. Такое перераспределение данных, реализуемое программно, может быть очень затратным.</p>
<p>Larrabee предоставляет аппаратное ускорение подобных операций с помощью поддержки инструкций чтения векторов (см. подраздел Larrabee). Инструкция чтения (gather) собирает соответствующие элементы векторов из разбросанных участков памяти и сохраняет их вместе в один векторный SIMD регистр. В приведенном выше примере команда чтения собирает 16 разбросанных в памяти значений, напр. X0, X1,…, X15.</p>
<p>Видно, что векторная поддержка контроля потока и непрямого доступа к памяти приводит к гораздо более эффективному использованию команд SIMD, чем при программных преобразованиях, и таким образом имеет большую ценность для производительных алгоритмов игровой физики.</p>
<h3 class="sectionHeading">Легко параллелизуемые реализации и алгоритмы</h3>
<p>Большинство алгоритмов игровой физики в большой степени используют SIMD и поточный параллелизм, который легко использовать с помощью аппаратной поддержки SIMD и поточной синхронизации. Однако, существуют несколько алгоритмов, где параллелизм сразу не применишь. Для параллелизации необходимо изменение реализации, или алгоритма, или и того и другого.</p>
<p><img height="564" width="369" src="http://software.intel.com/file/18851" alt="Решатель физики, пригодный для SIMD" /></p>
<p><em>Рис. 13. Как сделать решатель физики пригодным для SIMD</em></p>
<p>Приведем пример алгоритма, который требует изменений игровой ткани. Как было замечено в разделе об эмуляции ткани, алгоритм использует технику итеративной релаксации связей, которая усиливает одну связь за другой, пока вся система не сожмется до состояния, где все связи приходят с состояние равновесия. Усиление связи состоит в изменении позиции каждой частицы решетки, основанной на ее расстоянии от соседей справа, снизу, и по диагонали. Прямое усиление всех связей слева направо, сверху вниз, как на рис. 11(а), приводит к последовательной зависимости между связями и невозможности параллелизации. Вместо этого выполняются несколько проходов по связям. В первый проход приводятся в равновесие вертикальные связи (рис. 11(б)), Видно, что все связи не зависят друг от друга и могут обрабатываться параллельно. Также выполняются проходы по горизонтальным и диагональным связям (рис. 11(в), 11(г)).</p>
<p>Разрушая зависимость между связями, мы можем широко использовать поточный и SIMD параллелизм, но при этом замедляется работа алгоритма, поскольку одна связь теперь воздействует на другие через большее число итераций. Однако с помощью анализа симуляции мы выяснили, что параллельный алгоритм никогда не бывает медленнее, чем последовательный, более чем в два раза. Широкое применение параллелизма компенсирует замедление сходимости.</p>
<p>Другой пример из модели эмуляции твердого тела. Во время выполнения физической симуляции, фаза обнаружения столкновений вычисляет пары сталкивающихся объектов, и они используются как входные данные для фазы разрешения связей. Решатель физики работает с этими парами и вычисляет силы отталкивания, возникающие при контакте, которые препятствуют телам проникнуть друг в друга. На рис. 13 (а) показан случай столкновения четырех тел (три прямоугольника и плоскость основания), где соответствующие пары сталкивающихся объектов приведены на рис. 13 (б). Нужно разрешить результирующие связи C1, C2, C3, и C4 и обновить позиции тел.</p>
<p>Для параллелизации этой фазы нам в идеальном случае надо было бы распределить связи между свободными потоками и разрешать их параллельно. Однако этому часто мешают внутренние зависимости между соседними связями. В нашем примере связи С1 и С2 относятся к телу т2 и не могут разрешаться параллельно. Эти зависимости могут сильно усложнить вычисления, но можно перегруппировать связи по пачкам так, чтобы в каждой пачке не было конфликтующих связей. Т.е. каждая пачка содержит только одну связь для каждого тела.</p>
<p>Алгоритмы перераспределения перебирают связи, составляя упорядоченный список частично наполненных пачек. Каждая связь записывается в первую пачку, не содержащую конфликтующих связей. Как результат, все связи в пачке могут обрабатываться параллельно, а разные пачки должны  обрабатываться последовательно.</p>
<p>Например, мы переупорядочиваем связи на рис 13(б) и получаем две пачки (С1, С3) и (С4, С2), как показано на рис. 13(в). Отметим, что С1 и С3 из первой пачки связаны каждая со своим телом и могут обрабатываться параллельно. То же относится к С4, С2. Как результат, С1 и С3 обрабатываются параллельно и результат прилагается как часть ввода ко второй пачке.</p>
<p>Если внедрять параллелизм вышеприведенным образом, то применение потоков и SIMD является очевидным. Использование поточного параллелизма требует барьерной синхронизации между последовательными пачками параллельно обрабатываемых связей.</p>
<h3 class="sectionHeading">Результаты масштабирования</h3>
<p><img height="262" width="361" src="http://software.intel.com/file/18852" alt="Производительность игровой физики при масштабировании" /></p>
<p><em>Рис. 14. Производительность игровой физики при масштабировании</em></p>
<p>Мы провели детальный анализ масштабирования симуляции в нескольких играх на разных конфигурациях Larrabee [Seiler08]. На рис. 14 показана масштабируемость нескольких популярных тестов игровой физики и алгоритмов твердого тела, флюидов и ткани. Мы получили результат более 50% использования ресурсов на 64 ядрах Larrabee, и в некоторых случаях почти линейное ускорение при параллельной работе. Это означает, что архитектура Larrabee является достаточно масштабируемой для обеспечения растущих потребностей интерактивных алгоритмов твердого тела, флюидов и ткани.</p>
<a name="p5" id="p5"></a>
<h2>Выводы</h2>
<p>В данной статье мы представили несколько ключевых моделей эмуляции физики игры. Для удовлетворения потребностей в вычислительной мощности и памяти этих игровых приложений нам понадобилась компьютерная архитектура, обеспечивающая высокоскоростные вычисления с плавающей точкой и быструю шину памяти.</p>
<p>Мы кратко остановились на многоядерной многопоточной архитектуре Intel Larrabee с 16-элементным векторным процессором. Ее большой  вычислительный потенциал и широкая шина данных вполне удовлетворяют требованиям игровых приложений.</p>
<p>Мы также описали несколько моделей эмуляции игровой физики и показали, как их можно распараллелить, перенести и масштабировать на архитектуру Larrabee. Детали производительности и архитектурные тонкости обсуждаются в статье [GamePhysics08].</p>
<a name="p6" id="p6"></a>
<h2>Ссылки</h2>
<p>[1] [Baraff97] D. Baraff, “Physically Based Modeling: Principals and Practice,” Online Course Notes, SIGGRAPH, 1997. <br />[2] [Eberly03] D. H. Eberly. Game Physics. Morgan Kaufmann/Elsevier, San Francisco, 2003. <br />[3] [Ericson04] Christer Ericson, San Mateo. Real-time Collision Detection (Series in Interactive 3D Technology), Morgan Kaufmann, 2004. <br />[4] [Gilbert88] E. G. Gilbert, D.W. Johnson, and S. S. Keerthi. A fast procedure for computing the distance between complex objects in three-dimensional space. In IEEE Journal of Robotics and Automation, 4(2):193–203, 1988. <br />[5] [Chen07] Yen-Kuang Chen, Jatin Chhugani, Christopher J. Hughes, Corporate Technology Daehyun Kim, Sanjeev Kumar, Victor Lee, Albert Lin, Anthony D. Nguyen, Eftychios Sifakis, Mikhail Smelyanskiy. High-Performance Physical Simulations on Next- Generation Architecture with Many Cores. Intel Technology Journal, 2007. <br />[6] [Jacobsen01] T. Jacobsen, Advanced Character Physics, Game Developers Conference, 2001. <br />[7] [Muller03] M. Muller, D. Charypar, and Markus Gross. Particle-based fluid simulation for interactive applications. In Proceedings of the Eurographics Symposium on Computer Animation, 2003. <br />[8] [OpenMP05] OpenMP Application Program Interface, May 2005, Version 2.5. <br />[9] [Seiler08] Larry Seiler, Doug Carmean, Eric Sprangle, Tom Forsyth, Michael Abrash, Pradeep Dubey, Stephen Junkins, Adam Lake, Jeremy Sugerman, Robert Cavin, Roger Espasa, Ed Grochowski, Toni Juan, Pat Hanrahan. Larrabee: A Many-Core x86 Architecture for Visual Computing. In Proceedings of SIGGRAPH, 2008. <br />[10] [GamePhysics08] Parallelization and Analysis of Game Physics Performance on Larrabee Many-core Architecture. Currently under submission.</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/game-physics-performance-on-larrabee</link>
      <pubDate>Wed, 13 May 2009 04:00:55 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/game-physics-performance-on-larrabee#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/game-physics-performance-on-larrabee</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Зачем может понадобиться расширенный набор растровых операций  и как выбрать нужную</title>
      <description><![CDATA[ <p><strong>Автор:</strong> Михаил Трофимов (mt2)</p>
<p>Наверное все, кто когда-либо решал задачи программирования графики, знакомы с функцией API MS Windows BitBlt, которая позволяет эффективно скопировать битовый образ из одной области оперативной памяти (растра, bitmap) в другую. Обращение к этой функции выглядит следующим образом (здесь и далее мы используем Delphi-7; любителям других языков не составит труда сделать соответствующий перевод):</p>
<pre name="code" class="delphi:nogutter:"><br />function  BitBlt(DestDC: HDC; X, Y, Width, Height: Integer; <br />                     SrcDC: HDC; XSrc, YSrc: Integer; <br />                     Rop: DWORD): BOOL;  stdcall; // unit Windows<br /></pre>
<p><br />где SrcDC, DestDC –области памяти: исходный растр и растр назначения, т.е. «откуда» и «куда», <br /> соответственно;</p>
<p>X, Y, Width, Height,  XSrc, YSrc – начало координат и размеры прямоугольной области для  <br /> «куда» и начало координат для «откуда»;</p>
<p>Rop – код растровой операции.</p>
<p>Об этом последнем параметре и пойдет речь. Но прежде чем рассказать о практической задаче на углубленное (или, если хотите, «продвинутое») использование этих операций, напомню, что в математике и в Computer Sci. графом называется конструкция, состоящая из непустого множества вершин и множества ребер, причем каждому ребру соответствует пара вершин, которая это ребро соединяет. В компьютере графы проще всего представляются с помощью матрицы смежности - двумерного массива булевского типа, где элемент (i,j) имеет значение true, если существует ребро, соединяющее вершины i,j, и false в противном случае. (Здесь речь идет о так называемых неориентированных графах. Подробнее о графах см. [1-3] .) Другим часто применяемым представлением графа является список смежности – список всех ребер, т.е. список соответствующих пар вершин. Однако для человеческого восприятия граф лучше нарисовать - это, в частности, показал недавно проводившийся конкурс Intel Threading Challenge – при решении задач на использование алгоритмов теории графов у участников сразу возник спрос на инструменты для их (графов) визуализации и редактирования. Для более основательных задач такие инструменты являются незаменимыми. На рисунке представлено фото экрана с одним из подобных инструментов – MT2GraphEdit-2004 (подробнее о нем см. [4]):</p>
<p><img src="http://software.intel.com/file/17436" alt="Инструмент визуализации графов MT2GraphEdit-2004" width="467" height="288" /></p>
<p>Вершины графа раскрашены в результате работы некоего алгоритма – пользователь MT2GraphEdit-2004 может писать фильтры (plugins) и таким образом испытывать свои алгоритмы, что называется, не «отходя от кассы» - нарисовал граф и запустил из меню свой фильтр. Но вот, готовя статью об одном таком алгоритме в научный журнал, я был вынужден обрабатывать это фото в Adobe PhotoShop - в журнале ведь иллюстрации черно-белые! Я изменил изображение графа следующим образом:</p>
<p><img src="http://software.intel.com/file/17437" alt="Измененное изображение графа" width="300" height="168" /><br />Т.е. вместо кружков, изображающих вершины, нарисовал графические примитивы: квадратики, ромбики, … , туз пик, наконец, чтобы каждая пиктограмма соответствовала определенному цвету. Сейчас, разрабатывая новый редактор графов MT2GE, я решил добавить эту опцию в программу: чтобы можно было как раскрашивать вершины графа, так и назначать им некий графический примитив – пиктограмму 16х16 из более чем сотни пиктограмм, находящихся в стандартном наборе редактора. Таким образом, передо мной возникла задача: в точке с координатами вершины программа должна рисовать соответствующую ей пиктограмму, закрашивая ее определенным по ходу работы программы цветом. И должна это делать достаточно быстро, чтобы всякие перерисовки при удалении и возвращении вершин, команды undo и redo не тормозили пользователя. Очевидное решение: копировать с помощью вышеупомянутой функции BitBlt соответствующий графический примитив в точку с координатами вершины, выбрав растровую операцию Rop такой, чтобы вершина закрашивалась цветом, установленным для кисти (brush) данного холста (canvas).</p>
<p><img src="http://software.intel.com/file/17438" alt="Вершины графа закрашены цветом" width="292" height="167" /><br />В любом элементарном учебнике по программированию графики для MS Windows есть список пятнадцати основных растровых операций с именами от cmBlackness до cmWhiteness – «собака зарыта» в слове «основных»: поиск в MSDN Lib приводит на страницу «Ternary Raster Operations» [5], где в таблице приведен их полный набор – 257 операций. Пытаясь решить свою задачу с помощью только основных операций, я получил следующий код (см. папку test1 из приложенного архива):</p>
<pre name="code" class="delphi">  ImageListBm.Draw(bm.Canvas,0,0,shape);<br />  BitBlt (canvas.Handle,x,y,15,15, bm.Canvas.Handle,0,0,srcand);<br />  BitBlt (bm.canvas.Handle,0,0,15,15, bm.Canvas.Handle,0,0,notsrccopy);<br />  bm.canvas.Brush.Color := color;<br />  BitBlt (bm.canvas.Handle,0,0,15,15, bm.Canvas.Handle,0,0,mergecopy);<br />  BitBlt (canvas.Handle,x,y,15,15, bm.Canvas.Handle,0,0,srcpaint);<br /></pre>
<p><img src="http://software.intel.com/file/17439" alt="Ребра графа" width="103" height="97" /></p>
<p>Забегая вперед, укажу альтернативное решение:</p>
<pre name="code" class="delphi">procedure TForm1.drawShape(x,y, shape, color : integer);<br />const<br />  ROP_PSDPxax = $00B8074A;<br />var<br />   bm : TBitmap;<br /><br />begin<br />  bm := TBitmap.Create;<br />  bm.Width := 16;<br />  bm.Height := 16;<br />  ImageListBm.Draw(bm.Canvas,0,0,0);<br />  canvas.Brush.Color := color;<br />  BitBlt (canvas.Handle,x,y,15,15, bm.Canvas.Handle,0,0, ROP_PSDPxax);<br />  bm.Free;<br />end;<br /><br /></pre>
<p>Здесь мы говорим о троичных растровых операциях (Ternary Raster Operations) – есть еще и двоичные (binary Raster Operations), но они для BitBlt не используются. Троичными эти операции называются потому, что оперируют с тремя операндами: с исходным растром (S), с кистью (P)  и с растром назначения (D). В набор операторов входят булевы функции: «И» (a), «НЕ» (n), «ИЛИ» (o), «исключающее ИЛИ» (x). Такой набор имеет свойство функциональной полноты, даже с некоторым избытком – меньший набор из этих функций также будет функционально полон. Это значит, что любая булева функция может быть представлена комбинацией функций набора. Далее, в растровых операциях булевы операции над пикселами растров представлены в так называемой польской записи, удобной для исполнения на стековой машине [6,7].  Например, растровая операция PSo есть операция «ИЛИ» над каждым пикселом кисти и исходного растра, вычисленное значение заменяет соответствующий пиксел в растре назначения. Каждая растровая операция представляется в виде 32-х битового целого числа, в котором старшее слово – индекс булевой операции (Operation index), а младшее – код операции. Индекс булевой операции – это расширенное (добавлением нулей до шестнадцати бит) восьмибитовое значение, представляющее собой комбинацию битов результата для таблицы истинности, соответствующей булевой функции для трех вышеназванных операндов  S, D и P. Например, для операции PSo этот индекс будет равен 00FC. Ниже будет описан инструмент, вычисляющий эту таблицу, и приведено фото панели этого инструмента с такой таблицей. Очевидно, что все возможные значения индексов лежат в диапазоне от 00 до FF, т.е. реализуются все возможные 256 операций плюс еще одна дополнительная NOMIRRORBITMAP с индексом за пределами этого диапазона.</p>
<p>Как выбрать нужную операцию из 257? Для этого я написал уже упомянутый инструмент ROP. Вот как он выглядит (с учетом добавленной в «фотошопе» разметки):</p>
<p><img src="http://software.intel.com/file/17440" alt="Инструмент ROP" width="467" height="371" /></p>
<p>С помощью кнопок “Load” (позиции 1,2 на рисунке) загружаем изображения для аргументов функции BitBlt: Dest  для DestDC и Source для SrcDC. Указываем позицию X, Y на изображении Dest (3), «нажав» в соответствующее место мышью. Задаем цвет кисти (4) и, выбрав приглянувшуюся растровую операцию (5) из списка результатов действия растровых операций на выбранные изображения, смотрим на результат (6). При этом в таблице истинности (7) табулируется выбранная логическая функция, ее представление в польской нотации отображается в поле (8), а в инфиксной форме – в поле (9), соответствующий шаблон для вызова BitBlt с этой операцией - в поле (10). Код функции и растровая операция отображаются в полях (11),(12) соответственно. Поле (13) показывает стандартное имя растровой операции, если такое имя существует. Для занесения информации из этих полей в буфер обмена достаточно нажать с помощью мыши на нужное поле. Можно сохранить выбранный результат с помощью кнопки “Save”, а также основную информацию о результате кнопками “Graphics Log”, “Text Log”. Можно решать и другую задачу: задать таблично желаемые значения функции, выделяя соответствующее поле таблицы (7) и вводя нужное значение 1 или 0 кнопками (14). Можно также провести поиск функции по значениям: “Op.index” (например - 1F), “r Polish” (например - PDSoan) или по имени (например - NOTSRCCOPY). Если поиск прошел удачно, индикатор слева от поля Find окрашивается в зеленый цвет, в противном случае – в красный. Кнопки “About” и “Exit” комментариев не требуют :)</p>
<p>С помощью этого инструмента я отобрал три решения своей задачи (см. папку test2 из приложенного архива):</p>
<p><img src="http://software.intel.com/file/17441" alt="3 решения задачи" width="207" height="53" /></p>
<p>То есть при обозначении вершины графа графическим примитивом «бублик» можно доводить линии, изображающие ребра этого графа, только до квадрата, описывающего этот примитив, а также продолжать или не продолжать ребра в «дырке бублика». В последнем случае без маски не обойтись. В программе я реализовал все три варианта, предоставив пользователю возможность выбирать нужный стиль в меню установок. С точки зрения теории графов все три стиля вполне приемлемы. Программа test2 измеряет время, затраченное на отрисовку этих решений, а также, для сравнения, время, затраченное на отрисовку кружка и буквы близких размеров стандартными методами. Результаты сопоставимы, буква рисуется медленнее. Таким образом, решение оказалось подходящим.</p>
<p>Графы один из важнейших объектов программирования – вспомним хотя бы, что списки и деревья – тоже графы. Поэтому необходимость изображения графов возникает достаточно часто в самых различных задачах. Схема метро, схема шоссейных и железных дорог, электросхема – все это графы. Кроме того, вывод разноцветных графических примитивов может понадобиться и во многих других задачах, например, для обозначений различных игровых единиц (units) на  игровой карте. Поэтому надеюсь, что данный инструмент окажется полезен многим программистам. Если читатели выскажут такое желание, то сюда же можно будет выложить и исходный код этого инструмента. Для этого мне нужно будет дописать в него дополнительные комментарии, чтобы легче было ориентироваться.</p>
<p>В заключение хочу поблагодарить всех, кто откликнулся на мой вопрос с горячим желанием помочь на сайте <a href="http://www.delphikingdom.com/">http://www.delphikingdom.com/</a></p>
<h3><a href="http://software.intel.com/file/17472/">Zip-архив  с файлами</a>:</h3>
<p>Паки test1, test2 – исходные коды и исполняемые файлы примеров.<br />Папка ROP – исполняемый файл инструмента ROP.</p>
<h3>Список литературы и Интернет-источников.</h3>
<ol type="1">
<li>Ф.Харари, Теория графов, М.:УРСС, 2003.</li>
<li>А.А.Зыков, Основы теории графов, М.:Вузовская книга, 2004.</li>
<li>В.Липский, Комбинаторика для программистов, М.:Мир, 1988.</li>
<li>М.И. Трофимов, Инструментальная программа редактирования молекулярных графов MT2 Graph Edit 2004 версия 1.8.1,3-й  Международный симпозиум "Компьютерное обеспечение химических исследований CACR-2006", IVTN-2006, Ярославль, 2006, с. 45. http://www.ivtn.ru/2006/biomedchem/enter/paper.php?p=441</li>
<li><a href="http://msdn.microsoft.com/en-us/library/dd145130(VS.85).aspx">http://msdn.microsoft.com/en-us/library/dd145130(VS.85).aspx</a></li>
<li>А. В. Ахо, Р. Сети, Д. Д. Ульман. <em>Компиляторы: принципы, технологии и инструменты.</em> М.: «Вильямс», 2003. С. 51.</li>
<li><a href="http://ru.wikipedia.org/?oldid=14808020">http://ru.wikipedia.org/?oldid=14808020</a></li>
</ol> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/extended-raster-operations-set</link>
      <pubDate>Fri, 24 Apr 2009 12:07:49 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/extended-raster-operations-set#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/extended-raster-operations-set</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Метод точного рендеринга частиц объема с помощью пиксельного шейдера</title>
      <description><![CDATA[ <p>Многие игры, даже работающие на современном «продвинутом»  оборудовании, рендерят частицы с помощью смотрящих на камеру прямоугольников (quads). В большинстве случаев  эти частицы представляют собой массивы других, более мелких частиц. Объем этих  мелких частиц эмулируется с помощью расчета того, сколько они привносят в  картину, используя простую функцию блендинга. Функция блендинга определяет,  насколько эмулированный объем частиц затеняет сцену за ним.</p>
<p>Такой имитации объема использовался в играх много лет, но в  данной статье мы рассмотрим другой метод, который использует шейдер для более  точной физической передачи частиц объема. Этот метод дает более точную  зрительную передачу эмулированных объемов и потенциально снижает необходимое  количество частиц, что в свою очередь повышает производительность рендеринга.</p>
<p>Для начала нужно заметить, что рассматриваемый метод  ограничивается частицами, которые представляют собой некоторое количество других  субчастиц, и что дальнейший анализ предполагает их равномерное распределение.  Существуют методы, которые позволяют пользователю определять функции для более  сложных объектов, но в рамках данной статьи мы их рассматривать не будем.  Многие игры имитируют такие эффекты как пыль, туман, газ, пламя, и так далее,  годами используя один и тот же метод. В частности, они определяют, насколько  частица заслоняет сцену позади нее, используя альфа-канал.</p>
<p>Альфа-канал служит для определения степени прозрачности, при  этом используется следующий алгоритм: результирующий цвет пиксела (Cr) интерполируется  некоторой функцией (А) между цветом окружения (Ci) и цветом частицы (Cp). В большинстве  случаев, которые я наблюдал, альфа канал определяет значение А, а сама функция  выглядит так:</p>
<p><strong>Cr = A*Cp + (1-A)*Ci; </strong></p>
<p><em>Основная функция интерполяции.</em></p>
<p>Что же не так с этой функцией? В ней используются две операции  сложения и две умножения, в большинстве случаев она рассчитывается аппаратно.  Она легка и проста в использовании.</p>
<p>Смотрящие на камеры полупрозрачные многоугольники, которые  рендерятся с использованием этой функции, эмулируют макроскопические объемы  микроскопических частиц. Если все сделано правильно, -  частицы должны быть отсортированы от заднего  плана к переднему, квады, на которые они рендерятся, не должны соприкасаться с  другими квадами сцены, и так далее, - при соблюдении ряда условий  эффект будет достаточен для эмуляции больших объемов  микроскопических частиц.</p>
<p>Правильность отрисовки зависит от команды художников, многие  движки сортируют частицы по мере рендеринга, так что здесь все в порядке. А что  произойдет, если частицы наложатся на другие объекты? Следствием того, что все  частицы рендерятся как смотрящие на камеру многоугольники, является тот факт,  что частицы практически не сталкиваются друг с другом. Чего нельзя сказать о  столкновении частиц с другими геометрическими объектами сцены.</p>
<p>В некоторых случаях частицы обрабатываются без оглядки на  буфер глубины, и это означает, что ничто не будет загораживать сами частицы. В  других случаях можно проверить столкновение каждой частицы с объектами  остального мира и сделать так, чтобы их не было. В целом же, в большинстве игр  артефакты, связанные с соприкосновением  частиц  и их окружения, считались приемлемыми.</p>
<p><img src="http://software.intel.com/file/15532" alt="Пример из Chrome Dragon Engine, который использует  режим модулированного блендинга для отображения частиц дыма" width="580" height="433" /></p>
<p><em>Рис. 1. Пример из Chrome Dragon Engine, который использует  режим модулированного блендинга для отображения частиц дыма.</em></p>
<p>К сожалению, из-за артефактов, которые возникают при таком  методе рендеринга частиц, художникам приходится прибегать к ухищрениям:</p>
<ol type="1">
<li>Обычно, на первом проходе расчета эффектов       объема художник создает частицы такого размера и плотности, которые ему       кажутся оптимальными. Когда же эффект добавляется в игру, сразу становится       понятно, что частицы получились слишком большими. При рендеринге художнику       приходится менять их внешний вид и подгонять таким образом, чтобы избежать       возможных столкновений с объектами окружения.</li>
<li>В случаях, когда нужны частицы,       расположенные близко к геометрическим объектам, художнику приходится не       только искусственно сжимать частицы, чтобы избежать существенных       артефактов, но и увеличивать количество частиц, чтобы заполнить образовавшееся       место. Как только количество частиц возрастает, нужно сразу менять значения       альфы в функции, чтобы компенсировать возросшее возможное  наложение частиц друг на друга.</li>
</ol>
<p>Это снижает планируемое разрешение альфа канала (и, в принципе, может вызывать артефакты  в картинке), делает сам эффект более зернистым и плотным, а хуже всего то, что  заставляет художника (а иногда и программиста) тратить время на исправление основной  интерполирующей функции.</p>
<p>Благодаря тому, что современного оборудования с избытком хватает  на базовые функции интерполяции, в большинстве игр артефакты столкновений  полупрозрачных частиц с окружением воспринимаются как приемлемые.</p>
<p>В комплектах разработчиков (SDK), таких как OpenGL или DirectX, определены методы рендеринга, которые  просто вызывали соответствующую функцию блендинга одной строчкой. К сожалению,  художники работали не покладая рук, пытаясь привнести базовые партикулярные  эффекты в игры и привыкли рассчитывать на эту строчку кода.</p>
<p>В последние годы произошел значительный прорыв в возможностях аппаратного  рендеринга: были изобретены шейдеры. Даже на дешевой графической плате  разработчик может определить практически любую функцию (обычно ограниченную  количеством свободных регистров и возможностями языка шейдера).</p>
<p>С помощью пиксельного шейдера, технологий рендеринга текстур, плюс  немного математики, мы можем точнее эмулировать объемы, которые раньше  изображали частицы. Проблема современных методов рендеринга частиц объема  в том, что они, как и почти вся геометрия  игры, плоские. Они представляют собой повернутые к камере плоскости,  обрабатываемые с предположением, что их толщина никогда не будет видна.</p>
<p>Таким образом, реальная глубина проявляется тогда, когда  эмулированная глубина (а точнее – ее отсутствие) оказывается рядом с действительно  объемными объектами. Проблема возникает из-за того, что мы отображаем глубину  на эти повернутые к камере многоугольники. Мы берем видимое представление объема  в пространстве, проецируем его на плоскость, затем рендерим плоскость обратно в  объемное пространство.</p>
<p>Предположим, что мы хотим решить эту проблему, не прибегая к существенному  изменению сложившегося порядка действий, которые художник предпринимает в  первый заход. Что нам нужно, чтобы лучше представить объем? Допущения и математика.  В данной статье мы рассмотрим следующие допущения:</p>
<ol type="1">
<li>Содержание каждой частицы имеет       равномерную плотность. То есть, если бы мы взяли пробу из настоящего       объема, из которого была взята текстура частицы, то её плотность была бы       равна плотности любой другой пробы из того же объема.</li>
<li>Существуют две границы с реальным       миром, неявно определенные для каждого пиксела в текстуре источника. Эти       границы – ближняя и дальняя границы объема, который представляется пикселом.</li>
<li>Существует плоскость, которая       определяет зеркальное изображение границы объема для каждого пиксела (это       допущение будет опущено в последующем примере).</li>
<li>Пользователь имеет доступ к значениям       глубины, заданным для сцены, перекрытой частицей в пиксельном шейдере.</li>
</ol>
<p>Мы также примем, что обрабатываемые пиксели многоугольника  представляют собой объемы, видимые с точки расположения камеры.</p>
<p>Идея в том, чтобы взять нарисованный полигон и определить  вокруг него псевдо объем, заданный границами многоугольника, продолженными в ту  сторону, куда смотрит камера.</p>
<p>В следующем примере для создания объема многоугольник  продолжен как в направлении камеры, так и от камеры на некоторое расстояние D.</p>
<p>Начальный многоугольник определяет зеркальную плоскость P(mi), альфа канал каждого  пиксела определяет, насколько граница  B(sp) субчастицы отклоняется  от P(mi). На практике объем был  бы определен как многоугольник, продолженный в противоположную от камеры  сторону, только для того, чтобы вполне воспользоваться аппаратным клиппингом.</p>
<p>Пикселы, перекрытые другими объектами, отбрасываются и не  участвуют в расчетах ближней части объема.</p>
<p><img src="http://software.intel.com/file/15533" alt="" width="580" height="250" /></p>
<p><em>Рис. 2.</em></p>
<p>Теперь для каждого пиксела в частице у нас имеется некоторое  пространство, вдоль всех лучей, проходящих через пиксель, которые и определяют  информацию о столкновении, необходимую, чтобы убрать элиасинг, вызванный плоскостью  частицы. Есть по меньшей мере два пути рассматривать информацию от  альфа-компонента текстуры:</p>
<ol type="1">
<li>Как среднюю плотность микроскопических       частиц в диапазоне от переднего до заднего края объема. Я буду называть       этот метод «методом средней плотности».</li>
<li>Как относительную плотность в       микроскопическом объеме вдоль луча, представленного пикселом. Я назову       этот метод «методом объемной плотности».</li>
</ol>
<p>Для работы шейдера нам потребуется знать глубину окружения в  районе данного пикселя. Эти данные могут передаваться как текстурная информация  от предыдущей стадии рендеринга текстуры. Назовем ее EnvironmentDepth.</p>
<p>Нам потребуется пиксельная позиция начального полигона,  который определяет нашу плоскость отражения. Она может быть получена от  вершинного шейдера. Назовем ее ParticleDepth.</p>
<p>Нам также потребуется функция маппинга от значения альфа к  реальной глубине, чтобы определить глубину девиации, назовем ее DeviationExtent. Скорее  всего, глубина девиации будет постоянной во всем многоугольнике и, возможно, во  всей частице.</p>
<p>Мы возьмем без изменений существующую текстуру частиц, с  цветом и значением альфа, как они были определены в начале.</p>
<p>Определим глобальную функцию прозрачности, которая будет  преобразовывать максимальную плотность частицы и актуальный пропуск цвета через  объем, которую назовем VolumeAlpha. Эта функция определяет  максимальную прозрачность/непрозрачность, какую позволяет объем.</p>
<p>Как следствие, мы сможем увеличить разрешение при расчете  прозрачности, нормализуя альфа канал текстуры частицы, и глобально модулировать  его со значение VolumeAlpha.</p>
<p>Это также позволит нам глобально менять прозрачность всех  частиц.</p>
<p>Теперь альфа канал определяет отношение девиации от плоскости  отражения к границам. Координаты положения частицы в реальном мире относительно  камеры определяются как ParticleDepth  -/+ DeviationExtent. Настоящая граница объема частицы определяется как ParticleDepth -/+ TextureAlpha * DeviationExtent.</p>
<p>Теперь мы можем определить более точное представление  скрывающих свойств частиц, с объектами позади, внутри и спереди нее.</p>
<p>Рассчитаем значения альфа, основываясь на предыдущих  выкладках.</p>
<p>FarParticleDepth = ParticleDepth +  TextureAlpha * DeviationExtent * 0.5;</p>
<p>NearParticleDepth = ParticleDepth - TextureAlpha * DeviationExtent * 0.5;</p>
<p><strong>Расчет средней плотности:</strong></p>
<p>// Get the Environment Depth in terms  of the volume, values we are interested</p>
<p>// in are in the range 0 to DeviationExtent.</p>
<p>Alpha = (EnvironmentDepth – ParticleDepth)/(DeviationExtent);</p>
<p>// Clamp the value to 0..1</p>
<p>Alpha = VolumeAlpha * Clamp( Alpha, 0.0, 1.0 );</p>
<p>// Get resultant pixel</p>
<p>OutputColour = Alpha * ParticleColour + (1.0 – Alpha) * SourceColour;</p>
<p><strong>Расчет объемной плотности:</strong></p>
<p>// Get the Environment Depth in terms  of the volume, values we are interested</p>
<p>// in are in the range 0 to DeviationExtent.</p>
<p>Range = (EnvironmentDepth – ParticleDepth)/(DeviationExtent);</p>
<p>// Scale this range based on the alpha value defined for the pixel</p>
<p>Range = Range *  (1.0/ParticleAlpha);</p>
<p>// Normalize the value to -1..1</p>
<p>Alpha = Clamp( Range, -1.0, 1.0 ) * 0.5 + 0.5;</p>
<p>Alpha = Alpha * VolumeAlpha;</p>
<p>// Get resultant pixel</p>
<p>OutputColour = Alpha * ParticleColour + (1.0 – Alpha) * SourceColour;</p>
<p>Эти алгоритмы используют простой метод интерполяции, который  много лет имеет аппаратную реализацию для случаев отсутствия столкновений. Если  же объемы частиц сталкиваются с окружающими объектами, алгоритм линейно увеличивает  вклад частицы в изменение фона на основе количества объема, закрытого фоном.</p>
<p><img src="http://software.intel.com/file/15534" alt="Экран из движка Chrome Dragon, полученный методом  средней плотности" width="580" height="431" /></p>
<p><em>Рис. 3. Экран из движка Chrome Dragon, полученный методом  средней плотности. (Та  же сцена, что и на рис. 1)</em></p>
<p><img src="http://software.intel.com/file/15535" alt="Экран из движка Chrome Dragon, полученный методом  средней плотности" width="580" height="431" /></p>
<p><em>Рис. 4. Экран из движка Chrome Dragon, полученный методом  объемной плотности. (Та  же сцена, что и  на рис. 1)</em></p>
<p>Применяя данный метод рендеринга частиц, следует иметь ввиду,  что рендерится представление объема и что глубина этого объема, скорее всего,  относится к другому измерению частицы. Возможно, было бы лучше определить  какую-нибудь функцию, переводящую размер частицы в глубину.</p>
<p>Про метод объемной плотности можно добавить, что объемы  используют альфа канал, чтобы определить границы объема для каждого пиксела. К  сожалению, в основном в частицах для изображения объема используется градиент  от центра текстуры, который грубо определяет объем в форме клина.</p>
<p>Как видно на рис.1, многие частицы имеют немного дефектный  вид. Чтобы исправить его, в картинке, возможно, придется определить альфа  компонент текстуры настоящими значениями объема.</p>
<p>Этот подход может быть распространен на:</p>
<ol type="1">
<li>Кодирование девиации от плоскости       отражения в один из каналов текстуры. Это позволит автору определять       альтернативную медиану глубины, назначая точку отражения как девиацию от       начальной плоскости частицы.</li>
<li>Кодирование нормальной объемной       информации в три канала текстуры и передача цвета объема как равномерного       для всей частицы. Это позволяет обрабатывать в шейдере информацию о       подсветке в реальном времени.</li>
</ol>
<p>Современные методы рендеринга объемных частиц полны  недостатков и скоро могут выйти из употребления. Но ситуацию можно исправить с  помощью реализованных в современной аппаратуре шейдеров. Плюс ко всему,  предложенные изменения существующих методов рендеринга требуют лишь незначительных  изменений в работе художников, добавляют незначительное количество регистров в  шейдер, малое число шейдерных инструкций и не требуют значительных изменений для  существующего механизма рендеринга в игре.</p>
<p>Самое важное, что частицы будут лучше отвечать замыслам  художников,  и, что возможно уменьшение количества  частиц без снижения качества изображения.</p>
<p> </p>
<h2>Библиография</h2>
<p>Spherical Billboards for Rendering Volumetric Data - ShaderX 5 - Thomas  Umenhoffer, Laslo Szirmay-Kalos and Gabor Szijarto</p>
<p>Volumetric Post-Processing - Game Programming Gems 5 - Dominic Filion,  Artificial Mind &amp; Movement, and Sylvain Boissé, Motorola</p>
<p>OpenGL Shading Language (Orange Book) - Randi J. Rost</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/a-more-accurate-volumetric-particle-rendering-method-using-the-pixel-shader</link>
      <pubDate>Wed, 01 Apr 2009 04:08:50 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/a-more-accurate-volumetric-particle-rendering-method-using-the-pixel-shader#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/a-more-accurate-volumetric-particle-rendering-method-using-the-pixel-shader</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Проектируем архитектуру параллельного игрового движка</title>
      <description><![CDATA[ <a href="http://software.intel.com/file/8109">Разработка параллельной среды игрового движка (PDF)</a><a id="1" name="1"></a>
<h2>1. Введение</h2>
<p>С приходом на рынок многоядерных процессоров необходимость разработки игровых движков с поддержкой параллельных вычислений становится все более очевидной. Все еще возможно передавать основную нагрузку на графический процессор и использовать однопоточный движок, однако прирост производительности при использовании всех доступных в системе процессоров – как CPU, так и GPU – сулит куда более богатые возможности. Например, при использовании игрой нескольких CPU можно увеличить количество физических объектов (твердых тел), что придаст игре реалистичности, или разработать более «умный» искусственный интеллект, действия которого будут максимально приближены к человеческим.</p>
<a id="1.1" name="1.1"></a>
<h3>1.1. Обзор</h3>
<p>Говоря о дизайне параллельного игрового движка, мы подразумеваем, что параллельный, или многопоточный движок способен адекватно масштабироваться с учетом количества доступных на конкретной платформе процессоров. Масштабирование осуществляется за счет выполнения различных функциональных блоков в параллельном режиме, задействуя все доступные процессоры. На самом деле, это легче сказать, чем сделать: игровой движок включает множество частей, которые активно взаимодействуют друг с другом, в результате чего могут возникать различные ошибки многопоточности. При разработке движка такие взаимодействия необходимо принимать во внимание, предусматривая оптимальные механизмы синхронизации данных, предотвращающие блокировку при синхронизации. В движке также должно быть предусмотрено выполнение синхронизации данных в параллельном режиме, чтобы свести число последовательных операций к минимуму.</p>
<a id="1.2" name="1.2"></a>
<h3>1.2. Допущения</h3>
<p>В статье предполагается, что читатель имеет некоторые практические знания в области разработки современных компьютерных игр, а также опыт распараллеливания игровых движков или прикладных приложений.</p>
<a id="2" name="2"></a>
<h2>2. Режим параллельного выполнения</h2>
<p>Режим параллельного выполнения является краеугольным камнем эффективной многопоточной игровой среды. Чтобы добиться по-настоящему параллельной работы игрового движка, с минимальными затратами на синхронизацию, необходимо сделать так, чтобы каждая система работала в своем собственном режиме выполнения, как можно меньше взаимодействуя с другими системами движка. Конечно, при этом не обойтись без совместного доступа к данным. Однако, вместо того, чтобы каждая система обращалась к общим данным, например, за координатами положения или ориентации объекта, каждой системе следует предоставить свою копию данных. Это устранит взаимную зависимость разных частей движка от данных. Уведомления об изменениях, внесенных какой-либо частью в общие данные, передаются менеджеру состояний (State Manager), который помещает все изменения в очередь – это называется режимом обмена сообщениями (messaging). После того, как разные системы завершили свой очередной цикл выполнения, они обрабатывают сообщения от менеджера состояний, в соответствие с которыми обновляют свои внутренние структуры данных. Использование подобного механизма позволяет значительно сократить накладные затраты на синхронизацию, обеспечивая независимую работу систем.</p>
<a id="2.1" name="2.1"></a>
<h3>2.1. Режимы выполнения</h3>
<p>Менеджер состояний исполнения эффективен при синхронизации операций по определенному тактовому импульсу. Это позволяет всем системам синхронизироваться между собой своевременно. При этом частота синхронизации не обязательно должна соответствовать частоте кадров. Длительность тактов также не обязательно привязывать к какой-либо конкретной частоте, - она может быть выровнена по кадрам таким образом, что один такт соответствует времени, потраченному на завершения одного кадра (вне зависимости от его длительности). Иными словами, конкретная реализация менеджера состояний определяет частоту или длительность тактов.</p>
<p>На Рисунке 1 показано, как разные системы работают в «свободном режиме» пошагового выполнения (free step mode), при этом необязательно, чтобы все они завершали выполнение операции за один и тот же такт. Также возможен и жесткий режим пошагового выполнения (lock step mode, см. Рисунок 2), когда выполнение всех систем завершаются за один такт.</p>
<a id="fig1" name="fig1"></a><img src="http://software.intel.com/file/10886" border="0" alt="Состояние выполнения в свободном пошаговом режиме" width="625" height="353" />
<p>Рисунок 1: Состояние выполнения в свободном пошаговом режиме</p>
<a id="2.1.1" name="2.1.1"></a>
<h3>2.1.1. Свободный пошаговый режим</h3>
<p>Этот режим выполнения позволяет всем подсистемам непрерывно работать в течение времени, требуемого им для завершения очередной порции вычислений. Название «свободный» не следует понимать буквально - подсистемы синхронизируются не в произвольный момент времени, они лишь, «свободны» в выборе необходимого числа тактов.</p>
<p>Как правило, в этом режиме недостаточно послать менеджеру состояний простое уведомление об изменении состояния, - вместе с уведомлением об изменении состояния потребуется также передать данные. Это вызвано тем, что система, которая изменила общие данные, может находиться в состоянии выполнения, в то время как другая система, ожидающая эти данные, уже готова выполнить обновление. В этом случае требуется больше памяти т.к. нужно создавать больше копий данных. Поэтому «свободный» режим нельзя считать универсальным решением на все случаи жизни.</p>
<a id="2.1.2" name="2.1.2"></a>
<h3>2.1.2. Жесткий пошаговый режим</h3>
<p>Этот режим подразумевает, что выполнение задач всех систем завершается за один такт. Такой механизм проще в реализации и не требует передачи данных с уведомлением, поскольку система, которая зависит от изменений, сделанных другой системой, может просто запросить нужную переменную у другой системы (разумеется, в конце цикла выполнения).</p>
<p>При жестком режиме также можно реализовать псевдо-свободный пошаговый режим операций, путем чередования вычислений между различными шагами. В частности, это может потребоваться для расчетов ИИ, где за первый такт вычисляется начальная «общая цель», а затем производится расчет некоторой более детальной цели, вытекающей из начальной.</p>
<a id="fig2" name="fig2"></a><img src="http://software.intel.com/file/10887" border="0" alt="Состояние выполнения в жестком пошаговом режиме" width="625" height="353" />
<p>Рисунок 2: Состояние выполнения в жестком пошаговом режиме</p>
<a id="2.2" name="2.2"></a>
<h3>2.2. Синхронизация данных</h3>
<p>Вероятна ситуация, когда несколько подсистем изменяют одни и те же общие данные. Чтобы разрешить проблему конкурентных изменений обмен сообщениями должен предусматривать некий механизм, позволяющий определять приоритет изменений. Существуют два подхода:</p>
<ul type="disc">
<li>Время – правильное значение хранится в подсистеме, сделавшей последнее изменение. </li>
<li>Приоритет – правильное значение принадлежит системе, имеющей наибольший приоритет. Этот механизм может сочетаться с временным механизмом (для обработки изменений, внесенных подсистемами с одинаковым приоритетом). </li>
</ul>
<p>Данные, признанные устаревшими с точки зрения обоих механизмов, могут быть просто перезаписаны или исключены из очереди уведомлений.</p>
<p>В случае, если данные являются общими, использование различными системами относительных значений может быть затруднительно, так как при синхронизации возникает зависимость от хронологического порядка их поступления. Поэтому везде, где это требуется, следует использовать абсолютные значения. Тогда при обновлении своих локальных данных все подсистемы могут просто заменить старые значения новыми. Оптимальным решением может стать также сочетание абсолютных данных с относительными, в зависимости от конкретной ситуации. Например, общие данные, такие как координаты положения и ориентации, должны иметь абсолютные значения, так как конечные матрицы преобразования зависят от хронологии поступления данных. А, к примеру, подсистема генерации частиц, (являющаяся единственным владельцем информации о частицах) может посылать обновления относительных значений.</p>
<a id="3" name="3"></a>
<h2>3. Движок</h2>
<p>При проектировании движка основное внимание следует уделять его гибкости, обеспечивающей легкое расширение функциональности. Такой подход позволит относительно легко модифицировать движок для работы на платформах, имеющих те или иные ограничения, например, ограничения по памяти. В целом движок состоит из двух частей - оболочки и набора «менеджеров». Оболочка (раздел 3.1) содержит части игры, которые тиражируются в процессе выполнения, т.е. существуют в нескольких экземплярах. В нее также входят элементы, участвующие в выполнении основного цикла игры. Менеджеры (раздел 3.2) представляют собой одноэлементные (singleton) объекты, с которыми взаимодействует логическая часть игры.</p>
<p>На приводимой ниже схеме представлены части игрового движка:</p>
<a id="fig3" name="fig3"></a>
<p><img src="http://software.intel.com/file/10888" border="0" alt="Высокоуровневая архитектура движка" width="627" height="351" /></p>
<p>Рисунок 3: Высокоуровневая архитектура движка</p>
<p>Заметим, что функциональные блоки, относящиеся непосредственно к игре, рассматриваются как отдельный от движка элемент. Это и обеспечивают необходимую гибкость, обеспечиваемую тем, что сам движок играет роль «клея», соединяющего функциональные части. Модульность также позволяет загружать или выгружать системы по мере необходимости.</p>
<p>Интерфейсы представляют собой средство связи между движком и системами. Со стороны системы, интерфейс необходим для того, чтобы предоставить движку доступ к функционалу системы, а со стороны движка – для того, чтобы системы могли взаимодействовать с менеджерами.</p>
<p>Общее представление о такой блочной организации можно получить из Приложения А, «Пример схемы движка». Как указывалось в разделе 2 «Режим параллельного выполнения», системы, по своей сути, являются дискретными элементами. Благодаря этому они могут работать параллельно без вмешательства в работу других систем. В то же время, это порождает определенные проблемы в тех случаях, когда системам необходимо обмениваться информацией, ведь данные необязательно находятся в стабильном состоянии. Обмен информацией между системами может потребоваться по следующим двум причинам:</p>
<ul type="disc">
<li>Чтобы сообщить другой системе об изменении, внесенном в общие данные (например, координаты положения или ориентации объектов), </li>
<li>Чтобы запросить некоторые функции, недоступные в рамках конкретной системы (например, система расчета ИИ обращается к системе расчета геометрии/физики для проверки пересечения лучей). </li>
</ul>
<p>Первая проблема коммуникации между системами решается путем реализации менеджера состояний, как было описано в предыдущем разделе. Более подробно работа менеджера состояний рассматривается в разделе 3.2.2 «Менеджер состояний».</p>
<p>Для решения второй проблемы в системе предусматривается механизм для предоставления служб, которые могут потребоваться другой системе. Более подробное описание этого механизма содержится в разделе 3.2.3 «Менеджер служб».</p>
<a id="3.1" name="3.1"></a>
<h3>3.1. Оболочка</h3>
<p>Оболочка (внутренняя интегрированная среда) служит для объединения всех элементов движка. В оболочке происходит инициализация движка, за исключением менеджеров, экземпляры которых создаются глобально. В ней также хранится информация о сцене. Для обеспечения большей гибкости сцена реализуется в виде так называемой универсальной сцены, которая содержит универсальные объекты, представляющие собой контейнеры для соединения воедино различных функциональных частей сцены. Более подробное описание среды приводится в разделе 3.1.2.</p>
<p>Цикл игры также выполняется в оболочке и имеет следующий порядок:</p>
<a id="fig4" name="fig4"></a>
<p><img src="http://software.intel.com/file/10889" border="0" alt="Основной цикл игры" width="625" height="294" /></p>
<a id="3.1.1" name="3.1.1"></a>
<p>Рисунок 4: Основной цикл игры</p>
<p>На первом этапе цикла игры происходит обработка всех ожидающих сообщений окон операционной системы, так как движок, как правило, выполняется в оконной среде. Без этого движок не реагировал бы на вызовы операционной системы. На следующем этапе планировщик назначает задачи систем с помощью менеджера задач. Более подробно данный этап рассматривается в разделе 3.1.1 ниже. На последующем этапе все изменения, обработанные менеджером состояний (подробное описание в разделе 3.2.2), передаются требуемым элементам движка. На заключительном этапе интегрированная среда проверяет статус выполнения, определяя, следует ли завершить работу движка либо продолжить выполнение каких-либо операций, например, для перехода к следующей сцене. Статус выполнения движка хранится в менеджере окружения, описание которого приводится в разделе 3.2.4.</p>
<a id="3.1.2" name="3.1.2"></a>
<h3>3.1.1. Планировщик</h3>
<p>Планировщик генерирует опорный тактовый сигнал выполнения с заданной частоты. Тактовый сигнал также может поступать в «свободном» режиме, например, для режима бенчмарка. В таком режиме следующая операция начинается сразу после выполнения предыдущей, без ожидания истечения времени такта.</p>
<p>Планировщик передает системы на выполнение через менеджер задач за один такт генератора. В свободном пошаговом режиме (раздел 2.1.1) планировщик опрашивает системы, определяя, сколько тактовых шагов им понадобится, чтобы завершить выполнение. На основании опроса, планировщик определяет, какие системы готовы к выполнению, а какие завершат работу в конкретный шаг тактового генератора. Количество шагов может быть изменено планировщиком в том случае, если какой-либо системе требуется больше времени на выполнение. В жестком пошаговом режиме (раздел 2.1.2) все системы начинают и заканчивают исполнение в один тактовый шаг, соответственно, планировщик ожидает, когда завершится выполнение всех систем.</p>
<a id="fig5" name="fig5"></a>
<h3>3.1.2. Универсальная сцена и объекты</h3>
<p>Универсальная сцена и объекты выполняют функцию контейнеров функциональных блоков, реализованных в рамках определенных систем. Сами по себе, универсальная сцена и объекты не имеют никаких функций, кроме способности взаимодействовать с движком. Тем не менее, они должны быть достаточно гибкими, чтобы поддержать все доступные в той или иной системе функции. Таким образом, универсальная сцена и универсальные объекты не привязаны к конкретной системе, и обеспечивают свободное взаимодействие систем. Преимущество такого подхода заключается в независимости систем друг от друга, а следовательно - возможности их параллельной работы.</p>
<p>На приведенной ниже схеме показаны контейнеры универсальной сцены и универсального объекта:</p>
<p><img src="http://software.intel.com/file/10890" border="0" alt="Универсальная сцена и универсальный  объект" width="626" height="294" /></p>
<a id="3.2" name="3.2"></a>
<p>Рисунок 5: Универсальная сцена и универсальный объект</p>
<p>Принцип работы надстройки можно проиллюстрировать на следующем примере: универсальная сцена включает параметры графики, физики и других систем. Графическая часть сцены в таком случае отвечает за инициализацию дисплея и другие графические процедуры, физическая часть - за взаимодействие твердых тел, силу тяжести и т.п. Сцена содержит объекты, поэтому в универсальной сцене будет присутствовать несколько универсальных объектов. Универсальные объекты также могут быть включать параметрами графики, физики и т.п. Таким образом, графическая часть объекта будет отвечать за прорисовку объекта на экране, физическая - за взаимодействие твердого тела объекта с другими твердыми телами.</p>
<p>Более подробная схема взаимодействия движка с системами приводится в Приложении B - «Схема связи движка и системы».</p>
<p>Следует заметить, что универсальная сцена и универсальный объект отвечают за регистрацию всех своих «надстроек» в менеджере состояний, с тем, чтобы все надстройки получали уведомления об изменениях, внесенных другими надстройками (т.е. другими системами). В качестве примера можно привести графическую часть, которая регистрируется в менеджере для получения данных об изменениях, вносимых физической частью координаты положения и ориентации.</p>
<p>Дополнительная информация о компонентах системы приводится в Разделе 5.2 «Компоненты системы».</p>
<h3>3.2. Менеджеры</h3>
<p>Менеджеры обеспечивают поддержку глобальных функций в рамках движка и реализуются в виде singleton-объектов, иными словами, менеджер каждого типа доступен только в одном экземпляре. Это обусловлено тем, что дублирование ресурсов менеджеров неизбежно приведет к избыточности и отрицательно скажется на производительности. Менеджеры также предоставляют общую функциональность, которая востребована всеми системами.</p>
<a id="3.2.1" name="3.2.1"></a>
<h3>3.2.1. Менеджер задач</h3>
<p>Менеджер задач отвечает за упорядочение системных задач в рамках пула потоков. В пуле потоков создается по одному потоку на процессор, чтобы обеспечить оптимальное n-кратное масштабирование и предотвратить назначение излишних потоков, исключая неоправданные издержки переключения задач в операционной системе.</p>
<p>Менеджер задач получает от планировщика список задач для выполнения, а также информацию о том, завершения каких задач необходимо дождаться. Планировщик, в свою очередь, получает список задач от разных систем. На каждую систему выделяется только одна главная задача - данный метод называется «функциональная декомпозиция». Однако, в рамках каждой главной задачи допускается порождать необходимое количество подзадач для обработки данных (что определяется спецификой системы), таким образом внутри системы вполне может быть реализована «декомпозиция по данным».</p>
<p>На приведенной ниже схеме приводится пример того, как задачи могут быть распределены менеджером задач между потоками для выполнения на четырехъядерной системе:</p>
<a id="fig6" name="fig6"></a>
<p><img src="http://software.intel.com/file/10891" border="0" alt="Пример пула потоков в менеджере  задач" width="625" height="264" /></p>
<a id="3.2.2" name="3.2.2"></a>
<p>Рисунок 6: Пример пула потоков в менеджере задач</p>
<p>Помимо обработки запросов планировщика, менеджер задач может опрашивать системы последовательно в каждом из потоков, в результате чего системы получают доступ к локальной памяти потоков.</p>
<p>Некоторые детали реализации менеджера задач можно найти в Приложении D – «Советы по реализации задач».</p>
<h3>3.2.2. Менеджер состояний</h3>
<p>Управление состояниями – это часть механизма обмена сообщениями, которые позволяет отслеживать внесенные системами изменения и распространять уведомления о них среди других задействованных систем. В целях сокращения числа уведомлений, системы должны быть зарегистрированы в менеджере состояний для отслеживания нужных им изменений. Данный механизм основывается на так называемой «модели наблюдателя» (observer design pattern), которая более детально рассматривается в Приложении C – «Модель наблюдателя». Вкратце, модель наблюдателя предполагает использование объекта-наблюдателя, который следит за изменениями в субъекте, при этом роль посредника между ними выполняет менеджер изменений.</p>
<p>Данный механизм работает следующим образом:</p>
<p>1) Наблюдатель регистрирует субъект, за изменениями в котором он планирует вести наблюдение, в менеджере изменений (или менеджере состояний);</p>
<p>2) когда субъект изменяет какое-либо из своих свойств, он направляет уведомление об изменении в менеджер изменений;</p>
<p>3) менеджер изменений выдает уведомление об изменении в субъекте наблюдателю по сигналу оболочки</p>
<p>4) наблюдатель запрашивает у субъекта фактически измененные данные.</p>
<p>Свободный пошаговый режим выполнения (Раздел 2.1.1) вносит в этот механизм некоторые сложности. Во-первых, вместе с уведомлением об изменении потребуется передать и данные, так как система, которая внесла изменение в общие данные, может все еще выполняться и поэтому у нее нельзя запросить итоговое значение. Во-вторых, если система еще не готова к тому, чтобы получить изменения в конце тактового шага, менеджеру состояний потребуется удерживать измененные данные до тех пор, пока все зарегистрированные для их получения системы не придут в состояние готовности.</p>
<p>В оболочке реализуется два менеджера состояний, один из которых оперирует изменениями на уровне сцены, а другой - изменениями на уровне объекта. Это обусловлено тем, что сцена и объекты, в большинстве случаев, используют различные сообщения, относящиеся к их работе, поэтому разделение менеджеров снимает необходимость обработки лишних сообщений. В то же время, любые изменения объекта, имеющие отношение к сцене, будут зарегистрированы в сцене, и таким образом она будет получать соответствующие уведомления об изменениях.</p>
<p>Чтобы устранить накладные расходы на синхронизацию, менеджер состояний создает очередь изменений для каждого потока, создаваемого менеджером задач. Поэтому при доступе к очереди никакой синхронизации не требуется. По завершении выполнения очереди могут быть объединены с помощью методов, рассмотренных в Разделе 2.2.</p>
<a id="fig7" name="fig7"></a>
<p><img src="http://software.intel.com/file/10892" border="0" alt="Уведомление о внутренних изменениях UObject" width="368" height="162" /></p>
<p>Рисунок 7: Уведомление о внутренних изменениях UObject</p>
<p>Хотя вам может показаться, что уведомления об изменениях придется распространять в последовательном режиме, существует возможность их распараллеливания. Когда системы выполняют свои задачи, они выполняют операции над всеми своими объектами. Например, физическая система управляет перемещением объектов, проверяя их на предмет столкновения и задавая новые параметры ускорения и т.п., по мере того, как физические объекты взаимодействуют друг с другом. Во время уведомления об изменении объект системы больше не взаимодействует с другими объектами в рамках своей системы, а взаимодействует с другими настройками универсального объекта, с которым он ассоциируется. Это значит, что универсальные объекты теперь независимы друг от друга, и каждый универсальный объект может обновляться в параллельном режиме. Следует заменить, что возможны некоторые нетипичные ситуации, которые следует учитывать в процессе синхронизации. Тем не менее, у вас все же появляется шанс добиться частично параллельной работы того, что на первый взгляд было возможно только в последовательном режиме.</p>
<a id="3.2.3" name="3.2.3"></a>
<h3>3.2.3. Менеджер сервисов</h3>
<p>Менеджер сервисов предоставляет некоторым системам доступ к определенным функциям, которые не реализованы внутри самих систем. Необходимо заметить, что менеджер сервисов реализует это опосредованно, через соответствующие интерфейсы. Таким образом, каждая система, содержащая функциональность предоставленного интерфейса, регистрируется в менеджере сервисов.</p>
<p>В менеджере сервисов доступен лишь небольшой набор сервисов, поскольку структура движка направлена на то, чтобы поддерживать как можно более дискретную работу систем. Кроме того, системы не могут предоставлять любой сервис по своему усмотрению, необходимо строгое использование менеджера сервисов.</p>
<a id="fig8" name="fig8"></a>
<p><img src="http://software.intel.com/file/10893" border="0" alt="Пример работы менеджера сервисов" width="405" height="135" /></p>
<p>Рисунок 8: Пример работы менеджера сервисов</p>
<p>Другой задачей менеджера сервисов является предоставление разным системам доступа к свойствам друг друга. Свойства – это специфичные для каждой системы значения, которые не передаются при обмене сообщениями. Например, такими свойствами является разрешение экрана в графической системе, или значение силы тяжести в физической системе. Менеджер сервисов предоставляет разным системам доступ к этим свойствам, в то же время, не позволяя непосредственно управлять ими. Он также следит за тем, чтобы все изменения свойств помещались в очередь и публиковались только в случае последовательного выполнения. Следует учитывать, что доступ к свойствам другой системы требуется достаточно редко и является исключительным случаем. Это может понадобиться, например, при открытии окна консоли, для того, чтобы включить/выключить режим каркасной сетки в графической системе, или для системы интерфейса пользователя, чтобы изменить требуемое разрешение экрана. Фактически, данная возможность используется для установки параметров, которые не изменяются от кадра к кадру.</p>
<a id="3.2.4" name="3.2.4"></a>
<h3>3.2.4. Менеджер среды</h3>
<p>Менеджер среды (окружения) обеспечивает функциональность среды выполнения движка. К числу предоставляемых менеджером среды функциональных групп относятся:</p>
<ul type="disc">
<li>Переменные – имена переменных и данные, совместно используемые в масштабах всего движка. Переменные обычно задаются при загрузке сцены или определенных настроек пользователя и запрашиваются движком или различными системами. </li>
<li>Выполнение – данные о статусе выполнения, например, о завершении сцены или завершении программы. Эти параметры могут быть заданы и запрошены как движком, так и системами. </li>
</ul>
<a id="3.2.5" name="3.2.5"></a>
<h3>3.2.5. Менеджер платформы</h3>
<p>Менеджер платформы обрабатывает все абстракции вызовов операционной системы, а также обеспечивает некоторую дополнительную функциональность. Преимуществом такого подхода является возможность поместить несколько типичных действий в рамки одного вызова, снимая необходимость отдельных имплементаций во всех вызывающих системах.</p>
<p>В качестве примера можно привести загрузку динамической библиотеки какой-либо системы. Помимо загрузки системы, менеджер также получает данные о точке входа функции и затем вызывает функцию инициализации библиотеки. В нем также предусмотрен дескриптор (handle) библиотеки. После завершения движка библиотека выгружается.</p>
<p>Менеджер платформы также отвечает за предоставление информации о процессоре, например, о поддерживаемых SIMD-инструкциях и подобных параметрах..</p>
<a id="4" name="4"></a>
<h2>4. Интерфейсы</h2>
<p>Интерфейсы являются средством взаимодействия оболочки, менеджеров и систем. Оболочка и менеджеры располагаются в самом движке, поэтому оболочка имеет прямой доступ к менеджерам. Системы же находятся за рамками движка и отличаются по функциональности. Таким образом, возникает необходимость общего способа работы с ними. С другой стороны, системы не могут напрямую работать с менеджерами, им необходим некий способ обращения к менеджерам, хотя и необязательно к полной их функциональности (поскольку некоторые элементы менеджеров доступны только для оболочки).</p>
<p>Интерфейсы предлагают функциональность, которая необходима для унификации обращений. Таким образом, оболочка «знает» детали каждой системы и может общаться с ней посредством определенного набора вызовов.</p>
<a id="4.1" name="4.1"></a>
<h3>4.1. Интерфейсы субъекта и наблюдателя</h3>
<p>Интерфейсы субъекта и наблюдателя используются для регистрации наблюдателя в субъекте и передачи уведомлений об изменениях от субъекта к наблюдателю. Также необходим «субъект по умолчанию», поскольку функциональность по управлению регистрацией/и исключением наблюдателя является общей для всех субъектов.</p>
<a id="4.2" name="4.2"></a>
<h3>4.2. Интерфейсы менеджеров</h3>
<p>Доступ к менеджерам, хоть они и являются одноэлементными объектами, напрямую имеет только оболочка. Системы имеют опосредованный доступ к менеджерам, так как иначе каждый менеджер должен был бы иметь специальный интерфейс. Такой интерфейс необходимо было бы передавать в каждую систему при ее инициализации, а это неэффективно.</p>
<p>Отметим, что интерфейс каждого менеджера специфичен для конкретного менеджера, а, следовательно, не является универсальным.</p>
<a id="4.3" name="4.3"></a>
<h3>4.3. Системные интерфейсы</h3>
<p>Системам необходимы интерфейсы, чтобы оболочка получила доступ к их компонентам. Без интерфейса оболочке пришлось бы поддерживать определенную реализацию каждой новой системы, которая добавляется в движок.</p>
<p>В системе содержатся четыре компонента, поэтому системе необходимо реализовать четыре интерфейса: сама система, сцена, объект и задача. Данные компоненты рассматриваются в разделе 5 «Системы». Интерфейсы – это средства доступа к таким компонентам. Системный интерфейс предлагает способы создания или уничтожения сцен. Интерфейсы сцен обеспечивают способы создания и уничтожения объектов, а также способ получения «главной задачи». Интерфейс задач используется менеджером задач при постановке задач в пул потоков.</p>
<p>Интерфейсы сцен и объектов также являются производными интерфейсов субъектов и наблюдателя, поскольку они являются частями системы, которые должны взаимодействовать друг с другом и с универсальной сценой и объектом, к которым они прикреплены.</p>
<a id="4.4" name="4.4"></a>
<h3>4.4. Интерфейсы изменений</h3>
<p>Также существуют некоторые особые интерфейсы, используемые для передачи данных между системами. Любые системы, производящие определенные изменения, также должны реализовать данный интерфейс. Примером интерфейса такого типа является геометрия. Интерфейс геометрии получает данные по положению, ориентации и масштабу по каждому элементу. Любые системы, вносящие изменения в геометрию, должны реализовать данный интерфейс, чтобы разные системы могли обращаться к изменениям геометрии, при этом им не будет нужно знать о других системах.</p>
<a id="5" name="5"></a>
<h2>5. Системы</h2>
<p>Системы – это то, что обеспечивает игровую функциональность движка. Чтобы избавить движок от необходимости знать все типы систем, они должны реализовать интерфейсы, описанные в пункте 4.3 «Системные интерфейсы». Это существенно облегчает процесс добавления новой системы в движок.</p>
<a id="5.1" name="5.1"></a>
<h3>5.1. Типы</h3>
<p>Движок должен иметь несколько предварительно заданных типов систем, которые подходят для стандартных компонентов игры. Например, - геометрия, графика, физика (столкновение твердых тел), аудио, ввод, ИИ и анимация.</p>
<p>Для систем, реализующих функциональность за рамками общих функциональных блоков игры, рекомендуется создавать специализированный тип. Отметим, что любые системы, которые изменяют конкретные данные специализированных типов, должны знать об интерфейсе специализированного типа, поскольку движок не предоставляет такую информацию.</p>
<a id="5.2" name="5.2"></a>
<h3>5.2. Компоненты системы</h3>
<p>Система содержит несколько компонентов, которые необходимо реализовать. Такими компонентами являются: система, сцена, объект и задача. Все компоненты используются для взаимодействия с различными частями движка.</p>
<p>На следующей схеме показана связь между компонентами:</p>
<a id="fig9" name="fig9"></a>
<p><img src="http://software.intel.com/file/10894" border="0" alt="Связь между компонентами системы" width="625" height="219" /></p>
<p>Схема 9: Компоненты системы</p>
<p>Более подробная схема связи систем с движком содержится в Приложении А «Схема связи движка и систем».</p>
<a id="5.2.1" name="5.2.1"></a>
<h3>5.2.1. Система</h3>
<p>Компоненты «система» отвечает за инициализацию системных ресурсов, которые будут оставаться более или менее постоянными в течение периода работы движка. Примером этого является графическая система, анализирующая все адреса ресурсов для определения места их нахождения для ускорения загрузки после использования ресурса. Разрешение экрана также может задаваться графической системой.</p>
<p>Система также является главной точкой ввода данных для оболочки и предоставляет информацию о себе (например, сведения о своем типе), а также обеспечивает способы создания и уничтожения сцен.</p>
<a id="5.2.2" name="5.2.2"></a>
<h3>5.2.2. Сцена</h3>
<p>Компонент «сцена», иногда называемый «системной сценой», отвечает за управление ресурсами, относящимися к текущей сцене. Универсальная сцена использует системные сцены для расширения своей функциональности, наследуя свойства, предлагаемые данной системной сценой. Примером данного компонента является физическая сцена, создающая новый мир и задающая гравитацию для мира при инициализации сцены.</p>
<p>Сцена также предлагает способы создания и уничтожения объектов. Она также управляет компонентом задач, который используется для работы на сцене, и предлагает способ его получения.</p>
<a id="5.2.3" name="5.2.3"></a>
<h3>5.2.3. Объект</h3>
<p>Компонент «объект», также называемый «системным объектом», представляет собой объект в сцене и обычно связан с тем, что пользователь видит на экране. Универсальный объект использует системные объекты для расширения своей функциональности, таким образом, свойства объектов системы доступны в универсальном объекте.</p>
<p>Примером: допустим, есть универсальный объект, унаследовавший свойства геометрии, графики и физики для создания на экране деревянного бруса. Геометрия отвечает за информацию о положении, ориентации и масштабе, система графики выводит его на экран с помощью заданной сетки, а физическая система применяет к нему алгоритм столкновения твердых тел, чтобы он взаимодействовал с другими твердыми брусьями и системой гравитации.</p>
<p>В определенных ситуациях системный объект может быть связан с изменениями другого универсального объекта или одного из его расширений. В этом случае можно создать ссылку с тем, чтобы системный объект мог наблюдать за другим объектом.</p>
<a id="5.2.4" name="5.2.4"></a>
<h3>5.2.4. Задача</h3>
<p>Компонент задач, именуемый системной задачей, отвечает за действия в сцене. Когда задача получает команду обновиться от менеджера задач, она выполняет функции системы в отношении объектов на данной сцене.</p>
<p>Задача также может разделить исполнение на подзадачи и спланировать подзадачи в менеджере задач для дальнейшего распараллеливания. Это позволяет движку легче масштабироваться под конфигурацию с несколькими процессорами. Данная техника называется декомпозицией данных.</p>
<p>Какие-либо изменения объектов записываются менеджером состояний в период обновления задачи сцены. Подробная информация о менеджере задач содержится в пункте 3.2.2.</p>
<a id="6" name="6"></a>
<h2>6. Связываем все вместе</h2>
<p>Даже относительно поверхностное изложение концепции параллельного игрового непросто воспринять за один раз, тем более, что различные его части очень тесно взаимодействуют друг c другом. Давайте зайдем с другой стороны, и рассмотри работу движка шаг за шагом.</p>
<a id="6.1" name="6.1"></a>
<h3>6.1. Инициализация</h3>
<p>Работа движка начинается с инициализации менеджеров и оболочки.</p>
<ul type="disc">
<li>Оболочка обращается к загрузчику сцен для загрузки сцены. </li>
<li>Загрузчик определяет, какие системы используются в сцене, затем обращается к менеджеру платформы для загрузки каждого из модулей. </li>
<li>Менеджер платформы загружает соответствующие модули и передает их менеджеру интерфейсов. Системный модуль возвращает загрузчику указатели на системы, которые содержат системный интерфейс. </li>
<li>Системный модуль также регистрирует в менеджере сервисов любые сервисы, которые он предлагает. </li>
</ul>
<a id="fig10" name="fig10"></a>
<p><img src="http://software.intel.com/file/10895" border="0" alt="Инициализация движка и оболочки" width="370" height="228" /></p>
<p>Схема 10: Инициализация движка и оболочки</p>
<a id="6.2" name="6.2"></a>
<h3>6.2. Этап загрузки сцены</h3>
<p>Управление возвращается загрузчику, который загружает сцену.</p>
<ul type="disc">
<li>Загрузчик создает универсальную сцену и обращается к каждому системному интерфейсу за системными сценами, расширяющими функциональность универсальной сцены. </li>
<li>Универсальная сцена проверяет каждую системную сцену на изменения общих данных и возможные запросы общих данных. </li>
<li>Затем универсальная сцена регистрирует в менеджере состояний соответствующие системные сцены, чтобы они получали уведомление об изменениях. </li>
<li>Загрузчик создает универсальный объект для каждого объекта в сцене и определяет, какая система будет расширять универсальный объект. Универсальный объект использует ту же модель регистрации системных объектов в менеджере, что и универсальная сцена. </li>
<li>Загрузчик создает системные объекты через интерфейсы системной сцены, которые он получил раньше, и «надстраивает» универсальные объекты системными объектами. </li>
<li>Затем планировщик запрашивает интерфейсы системных сцен в отношении их главных задач, поскольку он отвечает за их перенаправление менеджеру задач. </li>
</ul>
<a id="fig11" name="fig11"></a>
<p><img src="http://software.intel.com/file/10896" border="0" alt="Инициализация универсальной сцены и объекта" width="416" height="242" /></p>
<p>Схема 11: Инициализация универсальной сцены и объекта</p>
<a id="6.3" name="6.3"></a>
<h3>6.3. Цикл игры</h3>
<ul type="disc">
<li>Менеджер платформ вызывается для обработки всех оконных сообщений и (или) других системных вызовов, необходимых для работы на текущей платформе. </li>
<li>Затем исполнение передается планировщику, который ждет окончания такта для продолжения работы. </li>
<li>Планировщик в свободном шаговом режиме проверяет, какие из системных задач были исполнены в предшествующем такте. Все выполненные задачи передаются менеджеру задач. </li>
<li>Затем планировщик определяет, какие задачи будут завершены в текущем такте, и ждет их завершения. </li>
<li>При жестком шаговом режиме планировщик выдает менеджеру все задачи и ждет их выполнения в каждом такте. </li>
</ul>
<a id="6.3.1" name="6.3.1"></a>
<h3>6.3.1. Исполнение задач</h3>
<p>Исполнение менеджером задач.</p>
<ul type="disc">
<li>Менеджер задач выстраивает очередь из направленных ему задач и начинает обрабатывать каждую задачу, по мере появления свободных потоков. (Выполнение задач специфично для каждой системы. Системы могут работать, используя только одну или несколько задач. Во втором случае используется менеджер задач, создавая, таким образом, возможность параллельного исполнения.) </li>
<li>Задачи выполняются как на всей сцене, так и на определенных объектах, изменяя внутренние структуры данных. </li>
<li>Любые данные, которые считаются общими, например, положение и ориентация должны передаваться в другие системы. Системная задача осуществляет это посредством системной сценой или системного объекта (в зависимости от того, что менялось), информируя своего наблюдателя об изменении. В данном случае наблюдатель, по сути, является менеджером изменений. </li>
<li>Менеджер изменений ставит в очередь информацию об изменении. При этом те типы изменений, в которых наблюдатель не заинтересован, просто игнорируются. </li>
<li>Если задаче требуется какие-либо сервисы, она обращается к менеджеру сервисов. Менеджер задач также может использоваться для изменения свойств другой системы, не использующей механизм сообщений (например, система ввода пользователя меняет разрешение экрана графической системы). </li>
<li>Задачи также могут обращаться к менеджеру среды для получения переменных среды, изменения состояния исполнения (например, приостановка исполнения, переход к следующей сцене и т.д.). </li>
</ul>
<a id="fig12" name="fig12"></a>
<p><img src="http://software.intel.com/file/10897" border="0" alt="Менеджер задач и задачи" width="252" height="387" /></p>
<p>Схема 12: Менеджер задач и задачи</p>
<a id="6.3.2" name="6.3.2"></a>
<h3>6.3.2. Распределение</h3>
<p>После того, как все задачи текущего такта завершили выполнение, основной цикл вызывает менеджера состояний для распределения изменений среди всех объектов и систем.</p>
<ul type="disc">
<li>Менеджер состояний обращается к каждому из своих менеджеров изменений для распространения накопленных изменений. Это осуществляется посредством проверки каждого субъекта и поиска наблюдателей, следящих за такими субъектами. </li>
<li>Затем менеджер изменений обращается к наблюдателю, информируя его об изменении (наблюдателю также передается указатель на интерфейс субъекта). При свободном шаговом режиме наблюдатель получает измененные данные из контролера изменений, однако, при использовании фиксированного шагового режима наблюдатель обращается за данными непосредственно к субъектам. </li>
<li>Наблюдатели, заинтересованные в изменениях, осуществляемых системным объектом, обычно представляют другие системные объекты, которые все прикреплены к одному и тому же универсальному объекту. Это позволяет разбивать процесс распространения изменений на задачи для параллельного исполнения. Для ограничения синхронизации в задаче группируются связанные расширения любых универсальных объектов. </li>
</ul>
<a id="6.3.3" name="6.3.3"></a>
<h3>6.3.3. Динамическая проверка и выход</h3>
<p>Итоговый шаг основного цикла представляет собой проверку состояния рабочего цикла. Существует несколько состояний рабочего цикла: исполнение, пауза, следующая сцена и пр. Если состояние рабочего цикла установлено на исполнение, будет выполнена очередная итерация цикла игры. Если рабочий цикл установлен на выход, происходит выход из игры:, освобождаются ресурсы и приложение закрывается. Могут быть реализованы другие состояния рабочего цикла такие, как пауза, переход на следующую сцену и пр.</p>
<a id="7" name="7"></a>
<h3>7. Заключительные соображения</h3>
<p>Ключевым моментом всего вышесказанного является раздел 2 – «Состояние параллельного исполнения». Проектирование систем для функциональной декомпозиции в сочетании с декомпозицией данных позволит добиться значительного распараллеливания, а также обеспечит масштабируемость и поддержку будущих процессоров с еще большим количеством ядер. Не забывайте использовать менеджеры состояний вместе с механизмом сообщений для синхронизации всех данных с минимальными издержками.</p>
<p>«Модель наблюдателя» является, по сути, расширенным механизмом сообщений, необходимо потратить некоторое время на исследования, чтобы создать эффективную реализацию под конкретный движок. Наблюдатель должен обеспечивать эффективное взаимодействие различных систем для синхронизации общих данных.</p>
<p>Управление задачами играет важную роль в регулировании нагрузки. Следуя советам в Приложении D, вы сможете создать эффективный менеджер задач для своего движка.</p>
<p>Как вы видите, разработка движка с высокой степенью параллелизации является решаемой задачей, если использовать четко определенный механизм сообщений и структуру. Соответствующее встраивание параллелизма в ваш движок игры обеспечит существенное увеличение производительности на современных и будущих процессорах.</p>
<a id="8" name="8"></a>
<h2>8. Информация об авторе</h2>
<p>Джеф Эндрюз – Application Engineer Intel, занимающийся оптимизацией программного кода игрового ПО. Он также изучает различные технологии повышения производительности игр. Джф являлся ведущим архитектором демонстрационной оболочки Smoke компании Intel.</p>
<a id="A" name="A"></a>
<h2>Приложение A. Схема примерного движка</h2>
<p>Главный цикл игры начинает обработку (см. Схему 4, «Главный цикл игры»).</p>
<p><img src="http://software.intel.com/file/10898" border="0" alt="Схема связи движка и системы" width="625" height="594" /></p>
<a id="B" name="B"></a>
<h2>Приложение B. Схема связи движка и системы</h2>
<p><img src="http://software.intel.com/file/10899" border="0" alt="Схема связи движка и системы" width="631" height="796" /></p>
<a id="C" name="C"></a>
<h2>Приложение C. Модель наблюдателя</h2>
<p>Модель наблюдателя описана в книге “Design Patterns: Elements of Reusable Object-Oriented Software”, Эриха Гамма (Erich Gamma) и др., первоначально изданной Addison-Wesley в 1995 г.</p>
<p>Основной идеей данной модели является алгоритм, в котором, любые элементы, заинтересованные в изменениях данных или состояний других элементов, не обременяются задачей периодического опроса. Модель определяет субъект и наблюдателя, которые используются для уведомления об изменениях. Процесс работает так: наблюдатель наблюдает за субъектом на предмет каких-либо изменений. Менеджер изменений выступает в роли модератора между двумя данными компонентами. Данная связь отображена на следующей схеме:</p>
<a id="fig13" name="fig13"></a>
<p><img src="http://software.intel.com/file/10900" border="0" alt="Конструктивный шаблон наблюдателя" width="628" height="212" /></p>
<p>Схема 13: Конструктивный шаблон наблюдателя</p>
<p>Ниже приводится поток операций:</p>
<ol type="1">
<li>Наблюдатель регистрируется в субъекте, за изменениями которого он планирует наблюдать, посредством менеджера изменений.</li>
<li>Менеджер изменений в реальности является наблюдателем. Вместо регистрации наблюдателя в субъекте, он сам регистрируется в субъекте и ведет собственный перечень, где указывается, какой наблюдатель зарегистрирован в каком субъекте.</li>
<li>Субъект вносит наблюдателя (на самом деле менеджер изменений) в свой список наблюдателей, которые заинтересованы в его состоянии; иногда дополнительно применяется тип изменений, который определяет, в каких именно изменениях заинтересован наблюдатель, что позволяет оптимизировать процесс распространения уведомления об изменении.</li>
<li>Когда субъект осуществляет изменение своих данных или состояния, он уведомляет наблюдателя посредством механизма обратного вызова и передает информацию об измененных типах.</li>
<li>Менеджер изменений выстраивает в очередь уведомления об изменениях и ждет сигнала для их распределения по объектам и системам.</li>
<li>Во время распределения менеджер изменений обращается к реальным наблюдателям.</li>
<li>Наблюдатели запрашивают субъект в отношении измененных данных или состояния (или получают данные из сообщений).</li>
<li>Когда наблюдатель более не заинтересован в субъекте, он снимает свою регистрацию из субъекта посредством контроллера изменений.</li>
</ol><a id="D" name="D"></a>
<h2>Приложение D. Советы по реализации задач</h2>
<p>Хотя распределение задач может быть реализовано различными путями, лучше всего поддерживать количество рабочих потоков равным количеству доступных логических процессоров платформы. Избегайте привязки задач к определенному потоку, поскольку задачи из различных систем не будут завершаться одновременно, что может привести к дисбалансу нагрузки между рабочими потоками, по сути, сокращая степень параллелизма. Также стоит изучить библиотеки управления задачами, например, Intel® Threading Building Blocks, что может упростить разработку.</p>
<p>В менеджере задач возможны варианты оптимизации, которые могут использоваться для обеспечения беспроблемного выполнения центральным процессором различных задач. Вот эти варианты:</p>
<ul type="disc">
<li>Обратный порядок – если последовательность подаваемых первичных задач относительно статична, задачи могут подаваться в обратном порядке от кадра к кадру. Данные по последней задаче для исполнения в предшествующем кадре, скорее всего, сохранятся в кэше, поэтому подача задач в обратном порядке для следующего кадра будет почти гарантировать то, что кэш центрального процессора не придется вновь наполнять верными данными.</li>
<li>Совместное использование кэша – у некоторых многоядерных процессоров общая кэш-память разделена на секции с тем, чтобы два процессора могли пользоваться одной кэш-памятью, а два других – отдельной кэш-памятью. Подача подзадач из одной системы на процессоры, вместе использующих кэш, повысит вероятность того, что данные уже будут находиться в общей кэш-памяти.</li>
</ul>
<a id="list" name="list"></a>
<h2>Список схем</h2>
<p><a href="#fig1">Схема 1</a>: Состояние исполнения, используя свободный шаговый режим 5<br /><a href="#fig2">Схема 2</a>: Состояние исполнения, используя жесткий пошаговый режим 6<br /><a href="#fig3">Схема 3</a>: Высокоуровневая архитектура движка 8<br /><a href="#fig4">Схема 4</a>: Главный цикл игры 9<br /><a href="#fig5">Схема 5</a>: Расширение универсальной сцены и объекта 10<br /><a href="#fig6">Схема 6</a>: Пример пула потоков менеджера задач 11<br /><a href="#fig7">Схема 7</a>: Внутреннее уведомление об изменении универсального объекта 12<br /><a href="#fig8">Схема 8</a>: Пример менеджера сервисов 13<br /><a href="#fig9">Схема 9</a>: Компоненты системы 17<br /><a href="#fig10">Схема 10</a>: Инициализация менеджера движка и системы 19<br /><a href="#fig11">Схема 11</a>: Инициализация универсальной сцены и объекта 19<br /><a href="#fig12">Схема 12</a>: Менеджер задач и задачи 20<br /><a href="#fig13">Схема 13</a>: Конструктивный шаблон наблюдателя 25</p>
<a id="bibliography" name="bibliography"></a>
<h2>Литература</h2>
<p>Gamma, E., Helm, R., Johnson, R., Vlissides, J., (1995-2000). Design Patterns: Elements of Reusable Object-Oriented Software. USA: Addison-Wesley.</p>
<p>Домашняя страница <a href="http://www.threadingbuildingblocks.org">Intel® Threading Building Blocks (TBB)</a>.</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/designing-the-framework-of-a-parallel-game-engine</link>
      <pubDate>Tue, 17 Feb 2009 02:02:18 -0800</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/designing-the-framework-of-a-parallel-game-engine#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/designing-the-framework-of-a-parallel-game-engine</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Построение теней в реальном времени по методу Shadow Volumes</title>
      <description><![CDATA[ <h2>Введение</h2>
<p>Щекочущее нервы наслаждение эффектом присутствия в компьютерных играх рождается, в том числе, и при исследовании искусно смоделированных виртуальных миров – чем реалистичнее, тем лучше. Игры переносят нас в бесконечное множество локаций, от фантастических миров магии и тайн до полной опасностей и азарта виртуальной реальности. Совершенствование графических ускорителей позволило программистам преодолеть ограничения двухмерных игр и создавать трехмерные пространства с потрясающей реалистичностью. В условиях постоянного роста быстродействия процессоров и совершенствования технологий оптимизации графики, как аппаратных, так и программных, у разработчиков появляются новые возможности для повышения реалистичности трехмерной графики и выхода на новые уровни интерактивности.</p>
<p>Невзирая на богатство и яркость оттенков, замысловатые текстуры и потрясающие визуальные эффекты современных игр, мозг все-таки ощущает нехватку чего-то существенного. Человек осознает, что изображение на экране – просто трюк, изощренный обман разума совместными усилиями электронов, математики и светящегося люминофора. Несмотря на сложные алгоритмы перспективного деления и коррекции перспективы в текстурах, изображению на экране все-таки недостает настоящего ощущения глубины. Чего же не хватает? Недостающим звеном могут оказаться тени. Без них любая иллюзия трехмерности окажется весьма несовершенной.</p>
<!-- .code {padding: 10px 10px 5px; margin-bottom: 10px; background-color: #e3e3e3; border: 1px solid #bababa; } -->
<h2>Свет и тень в компьютерной графике</h2>
<p>В этой статье мы постарались снять покров тайны с процесса создания теней в трехмерных средах. Мы также предлагаем некоторые конкретные методы, с помощью которых программист может привнести в свой проект дополнительные элементы реализма, создаваемые рендерингом теней в реальном времени. Надеемся, что приведенные примеры и алгоритмы вдохновят программистов на новые эксперименты с предложенными методами и, может быть, на их адаптацию для конкретного приложения.</p>
<p>Совершенствование аппаратных средств ускорения и программных технологий обработки графики все больше расширяет спектр возможностей, доступных профессионалам. И сегодня, когда процессоры могут работать с ошеломляющей скоростью, а графические ускорители способны «строгать» треугольники быстрее, чем фабрика чипсов, мы можем воспользоваться преимуществами всех этих новых возможностей для создания весьма интересных приложений.</p>
<h2>Когда спускаются тени</h2>
<p>Сегодня существует множество методов расчета и отображения теней в реальном времени, включая проекции на плоскость (plane projections), наложение текстур (texture mapping), теневые объемы (shadow volumes) и трассировку лучей (ray tracing). Метод наложения текстур превосходно изложен в статье Хьюберта Нгуена «Построение теней на объемах» (Hubert Nguyen, "Casting Shadows on Volumes") в журнале «Game Developer» за март 1999 г. Наши первоначальные попытки реализовать тени в реальном времени были основаны на методе, весьма похожем на описанный в работе Нгуена. К сожалению, мы столкнулись с рядом негативных факторов, характерных для рассматриваемого метода, которые также были отмечены и описаны Нгуеном: низкая скорость рендеринга текстур, большие затраты вычислительных ресурсов при самозатенении, необходимость дополнительных итераций для сложных сцен и значительные размеры текстур, необходимые, чтобы избежать пикселизации. Наши поиски более эффективной технологии привели к методу отбрасывания теней (shadow casting).</p>
<p>Стремительное развитие технологий ускорения графики позволяет добиться на персональном компьютере такого же уровня быстродействия, как и на высокопроизводительной рабочей станции. Благодаря этому многие графические методы, первоначально разработанные для рабочих станций, были реализованы в трехмерных играх реального времени. Сегодня целый ряд видеокарт поддерживает 8-битные буферы шаблонов (stencil buffer), что позволяет использовать методы отбрасывания теней для создания теней в реальном времени при минимальном снижении производительности.</p>
<p>Алгоритм включает в себя три существенных компонента: построение внешнего ребра объекта, рисование полигонов с теневым объемом и рендеринг собственно тени. Мы рассмотрим каждый из этих компонентов в теории и затем, в последующих разделах, приведем подробные указания по их практической реализации.</p>
<p><a href="/articles/content/ru-ru/2325/fig1.htm" target="_blank"><img src="http://software.intel.com/file/9234" alt="" width="150" height="104" /></a><br /> <a href="/articles/content/ru-ru/2325/fig1.htm" target="_blank">Рис. 1 — увеличить</a></p>
<h2>Построение теневого объема</h2>
<p>Внешним ребрам объекта не всегда сопоставлена соответствующая выпуклая часть данного объекта. Необходимо определить все ребра объекта, описывающие силуэт этого объекта из точки текущего источника света. Когда ребра найдены, можно создать и спроецировать теневой объем. В местах, где ребра объекта пересекают конус света от источника в данной сцене, отбрасывается тень. Представьте себе луч света от карманного фонарика, но не заливающий сцену светом, а использующий объект для отбрасывания тени на сцену. <a href="/articles/content/ru-ru/2325/fig1.htm" target="_blank">Рис. 1</a> проливает немного света на эту концепцию (каламбур умышленный). После определения силуэтных ребер формируются новые полигоны путем продления граней в направлении, указанном текущим источником света. Совокупность этих полигонов обозначается термином «теневой объем» (shadow volume). Правильное сочетание полученного объема и операций с буфером шаблонов позволяет сформировать тени и разместить их на сцене.</p>
<p><a href="/articles/content/ru-ru/2325/fig2.htm" target="_blank"><img src="http://software.intel.com/file/9236" alt="Click for larger view of the stencil buffer" width="149" height="92" /></a><br /> <a href="/articles/content/ru-ru/2325/fig2.htm" target="_blank">Рис. 2 — увеличить </a></p>
<h2>Увеличение и уменьшение буфера шаблонов</h2>
<p>Сначала необходимо отрисовать всю сцену без учета затенения. Фокус в том, чтобы дважды отрисовать на сцене теневой объем (оба раза в буфер невидимых объектов). Первый раз объем рисуется на сцене путем увеличения значения буфера шаблонов для каждого пикселя, прошедшего проверку по Z-координате глубины. Затем необходимо сменить режим отбрасывания невидимых полигонов (cull mode) графической карты на отбрасывание передних ребер и повторно отрисовать объем. Буфер шаблонов уменьшается для каждого пикселя, который снова проходит нормальную проверку по Z-координате. Метод проиллюстрирован на <a href="/articles/content/ru-ru/2325/fig2.htm" target="_blank">Рис. 2</a>. В результате этих операций буфер шаблонов содержит положительные значения для всех пикселей, лежащих внутри объема. Это логически ведет к следующему шагу алгоритма – собственно прорисовке тени.</p>
<p>После выполнения той же серии операций для всех объектов сцены необходимо нарисовать полупрозрачный четырехугольник (alpha-blended quad) во весь экран. Графическая карта настраивается на отрисовку только тех пикселей, для которых в буфере шаблонов содержится положительное значение. В результате на сцене появляются задуманные тени. Далее необходимо очистить буфер шаблонов и повторить весь процесс для следующего источника света в этой сцене. Правильная конфигурация буфера шаблонов при визуальной отрисовке теней позволяет минимизировать затраты ресурсов, связанные с очисткой буфера шаблонов. Графическая карта может устанавливать значение буфера шаблонов равным нулю каждый раз, когда пройден тест шаблона и нарисован пиксель тени. Эта операция обеспечивает заполнение буфера шаблонов нулевыми значениями, после чего он готов к обработке следующего источника света или кадра.</p>
<h2>Практическая реализация: рождение теневого объема</h2>
<p>Первый шаг к формированию теневого объема – разработка эффективного метода для определения отбрасывающих тень ребер любого объекта. Согласно нашим выводам, из множества существующих методов определения ребер самым быстрым является метод предварительного расчета данных о соседних треугольниках. Данные о соседних треугольниках хранятся в форме внутреннего списка всех соседствующих граней для каждого треугольника.</p>
<p>В Примере 1 (ниже) приведен псевдокод, описывающий алгоритм расчета данных о соседних треугольниках. Этот расчет может проводиться при загрузке модели, либо данные могут быть обработаны заблаговременно и сохранены в файловом формате. После получения таких данных приложение может эффективно определить силуэтные ребра объекта. Ребра определяются путем отбрасывания (culling) граней, не видимых с текущей позиции источника света, и затем определения ребер, лежащих вдоль границы отброшенных и неотброшенных граней.</p>
<p>В Примере 2 (еще ниже) приведен псевдокод, описывающий эту процедуру. Демонстрацию процесса отбрасывания теней можно посмотреть, загрузив <a href="/en-us/articles/code-samples-license-2?target=http%3A%2F%2Fwww.intel.com%2Fcd%2Fids%2Fdeveloper%2Fasmo-na%2Feng%2F41054.htm" target="_blank">образец приложения (.zip, 739 KB)</a>.</p>
<div class="code">
<p>// Example 1</p>
<p>For (a = every face) {</p>
<p>//Edge 0</p>
<p>If ( The first edge does not already have a neighbor ) {</p>
<p>For (b = every other face) {</p>
<p>If ( The first edge of a = any edge in b ) {</p>
<p>They are neighbors !!!</p>
<p>Quit looking for a neighbor for this edge</p>
<p>}</p>
<p>}</p>
<p>Do the same for Edge 1</p>
<p>Do the same for Edge 2</p>
<p>}</p>
<p>}</p>
</div>
<p>После определения силуэтных ребер можно рассчитать полигоны, формирующие теневой объем. Это может оказаться проще или сложнее, в зависимости от подхода. В самом простом случае необходимо создать две новых вершины в направлении света по другую сторону от вершин текущего ребра. По получившимся четырем точкам можно построить два простых треугольника. В зависимости от того, насколько далеко вынесены новые точки, могут возникнуть определенные сложности.</p>
<p>Возможны следующие три варианта реализации:</p>
<p><strong>1. Вытянуть ребра на достаточное расстояние, чтобы гарантировать их выход за пределы пирамиды видимости (это также называют методом brute force).</strong> В Примере 2 (ниже) приведен пример реализации этого метода.</p>
<div class="code">
<p>// Example 2</p>
<p>Light Direction = Direction of the light in the object's local space</p>
<p> </p>
<p>Extension Vector = Light Direction * "Infinity"</p>
<p>// Length of the shadow volume</p>
<p> </p>
<p>//////////////////////////////////////////////////////////////////////</p>
<p> </p>
<p>For ( f = Every face in the Mesh ) {</p>
<p>if ( Face Normal * Light Direction = Visible ) {</p>
<p>Face is not culled</p>
<p>} else {</p>
<p>Face is culled</p>
<p>}</p>
<p>}</p>
<p> </p>
<p>/////////////////////////////////////////////////////////////////////</p>
<p> </p>
<p>For ( f = Every face in the Mesh ) {</p>
<p>if ( f = visible ) {</p>
<p>if (( f's first edge does not have a neighbor )</p>
<p>OR (f's first edge neighbor is NOT visible)) {</p>
<p>// This is a shadow casting edge</p>
<p>Add vertex 0</p>
<p>Add vertex 0 + Extension Vector</p>
<p>Add vertex 1</p>
<p>Add vertex 1 + Extension Vector</p>
<p>Add 2 faces</p>
<p>}</p>
<p>Do the same for edge 1</p>
<p>Do the same for edge 2</p>
<p>}</p>
<p>}</p>
</div>
<p>Хотя этот метод работает достаточно хорошо, необходимо отметить две проблемы, сказывающиеся на производительности. Во-первых, необходимо предусмотреть отсечение (clipping) этих полигонов на аппаратном уровне или с помощью специального кода отсечения. Это может привести к потенциальному снижению производительности. Во-вторых, сгенерированные таким образом полигоны теневого объема проникают сквозь всю геометрию сцены. Это может быть хорошо или плохо, в зависимости от степени использования теней в конкретном случае. Более подробно эта проблема рассмотрена в разделе 2.</p>
<p><strong>2. Отсекать вершины теневого объема при контакте с геометрией сцены.</strong></p>
<p><a href="/articles/content/ru-ru/2325/fig3.htm" target="_blank"><img src="http://software.intel.com/file/9238" alt="" width="150" height="118" /></a><br /> <a href="/articles/content/ru-ru/2325/fig3.htm" target="_blank">Рис. 3 — увеличить </a></p>
<p>Несколько слов по поводу отсечения по геометрии (Clipping to Geometry)</p>
<p>Этот подход полезен в том случае, если тени генерируются не для каждого объекта сцены. Пример использования этого метода приведен на <a href="/articles/content/ru-ru/2325/fig3.htm" target="_blank">Рис. 3</a>. Например, если объект находится с одной стороны стены, а при текущем положении камеры видна и другая сторона этой стены, тень объекта обычно проникает сквозь стену (если вы пользуетесь методом № 1). Это не создаст никаких проблем в том случае, если сама стена также отбрасывает тень.</p>
<p>При использовании этого метода зритель не увидит никаких артефактов - при условии, что тень отбрасывают все объекты сцены. В данном примере, если приложение не создает тени для стен, тени от каждого объекта должны быть отсечены по плоскости стены, чтобы избежать появления артефактов. Учтите, что при использовании метода отсечения по сцене (scene-clipping), если в стене есть отверстие, одного этого метода будет недостаточно, чтобы позволить тени проникнуть сквозь отверстие. Для этого потребуются дополнительные вычисления.</p>
<p><strong>3. Отсечение теневого объема по пирамиде видимости</strong></p>
<p>Этот подход представляет собой вариацию на тему описанного выше метода вытягивания ребер (edge-extension). Данный метод позволяет избежать падения производительности, возникающего из-за выполнения отсечения только с помощью аппаратных средств. Однако этот метод сопряжен с теми же проблемами, что и предшествующий.</p>
<p>Практическая реализация: движемся дальше</p>
<p>После того, как объем сгенерирован и сохранен в памяти, начинается самое интересное. Как мы упоминали при общем обзоре алгоритма, объем необходимо полностью отрисовать только в буфер шаблонов; никакая информация о цветах на экран не выводится.</p>
<p>В Примере 3 (ниже) показана реализация соответствующих настроек режима рендера (renderstate) в Direct3D. Полигоны отрисовываются в режиме плоского затенения (flat shading), чтобы не тратить циклы видеокарты на затенение по Гуро (Gouraud shading) с плавными цветовыми переходами для поверхностей, которые не будут отображаться на экране. Значения буфера шаблонов увеличиваются для каждого пикселя, отрисованного видеокартой за этот проход.</p>
<p>И вот, стоило вам поверить, что отрисовка объема уже позади, как приходится снова производить еще один проход рендеринга на тех же полигонах. На этот раз вам придется перевернуть все мироздание с ног на голову, и заодно поменять режим отбрасывания невидимых граней. В Примере 3 (Example 3 ниже) показана реализация в Direct3D настроек для правильного выполнения второго прохода рендеринга. Обратите внимание на изменения в функциях буфера шаблонов, а также на смену режима отбрасывания невидимых граней. Затем объем отрисовывается в буфер шаблонов так же, как и при первом проходе, но на этот раз значения буфера шаблонов уменьшаются, а не увеличиваются. Не забудьте вернуть правильные значения буфера глубины (z-buffer), буфера шаблонов и режима отбрасывания невидимых граней (cullmode) перед переходом к следующей сцене.</p>
<div class="code">
<p>// Example 3</p>
<p>//Draw the volume opening side</p>
<p>dev-&gt;SetRenderState(D3DRENDERSTATE_STENCILPASS, D3DSTENCILOP_INCR);</p>
<p>dev-&gt;SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CCW);</p>
<p>dev-&gt;DrawIndexedPrimitive</p>
<p>(</p>
<p>D3DPT_TRIANGLELIST,</p>
<p>D3DFVF_VERTEX,</p>
<p>VtxPool,</p>
<p>vnum,</p>
<p>FaceList,</p>
<p>fnum,</p>
<p>0</p>
<p>);</p>
<p> </p>
<p>//Draw the volume closing side</p>
<p>dev-&gt;SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_CW);</p>
<p>dev-&gt;SetRenderState(D3DRENDERSTATE_STENCILPASS, D3DSTENCILOP_DECR);</p>
<p>dev-&gt;DrawIndexedPrimitive</p>
<p>(</p>
<p>D3DPT_TRIANGLELIST,</p>
<p>D3DFVF_VERTEX,</p>
<p>VtxPool,</p>
<p>vnum,</p>
<p>FaceList,</p>
<p>fnum,</p>
<p>0</p>
<p>);</p>
</div>
<p>Приложение повторяет формирование и отрисовку объема для каждого отбрасывающего тень объекта, для текущего источника света, и только после этого отрисовывает собственно тень. Это не только увеличивает производительность (поскольку, как мы скоро увидим, отрисовка «настоящих» теней может потребовать очень больших затрат системных ресурсов), но и позволяет избежать артефактов – участков многократного падения освещенности в тенях.</p>
<p>На данном этапе можно отрисовывать видимое изображение тени. Принцип очень прост. Во весь экран рисуются два больших серых полупрозрачных треугольника. Операции с шаблонами настраиваются таким образом, чтобы рисовать только пиксели, которым в буфере шаблонов соответствует положительное значение. В Примере 4 (ниже) показаны переменные, описывающие режимы рендера (renderstates) для выполнения данной операции.</p>
<div class="code">
<p>// Example 4</p>
<p>static D3DTLVERTEX box[4];</p>
<p>static WORD box_faces[6] = {0,2,1,0,3,2};</p>
<p>static bool first = true;</p>
<p>static DWORD color = 0x00E0E0E0;</p>
<p> </p>
<p>m_dev-&gt;SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_DESTCOLOR);</p>
<p>m_dev-&gt;SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO);</p>
<p>m_dev-&gt;SetRenderState(D3DRENDERSTATE_STENCILFUNC, D3DCMP_LESSEQUAL);</p>
<p>m_dev-&gt;SetRenderState(D3DRENDERSTATE_STENCILPASS, D3DSTENCILOP_ZERO);</p>
<p> </p>
<p>if (first)</p>
<p>{</p>
<p>first = false;</p>
<p>Zero Memory for vertices</p>
<p>Assign 4 vertices to the 4 corners of your screen</p>
<p>}</p>
<p> </p>
<p>m_dev-&gt;DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX,</p>
<p>box, 4, box_faces, 6,</p>
<p>D3DDP_DONOTCLIP);</p>
</div>
<h2>Свет и тьма: за и против</h2>
<p>Отбрасывание теней в реальном времени в интерактивных трехмерных средах с помощью представленных в данной статье методов имеет свои преимущества и недостатки. В этом разделе мы рассмотрим и положительные, и отрицательные аспекты нашего метода. К положительным относится значительное увеличение реалистичности без манипуляций с текстурами или неоправданного падения скорости рендеринга. Среди отрицательных аспектов – вопросы поддержки буфера шаблонов, ограничение скорости заполнения сцены (fillrate), резкие краями теней, мелкие аномалиями полигонов и трудности с продвинутым управлением сценами.</p>
<p>Наиболее существенным преимуществом отбрасывания теней в реальном времени является значительное повышение реалистичности изображения. При полноценном отбрасывании теней вся сцена выглядит реалистично, при любом количестве полигонов и объектов. Возможно создание полностью динамических сцен без предварительных расчетов освещения (за исключением упоминавших выше данных о соседних треугольниках). Объекты также могут затенять сами себя, чего нелегко добиться путем наложения текстуры в связи с необходимостью интенсивных расчетов и многочисленных операций текстурирования.</p>
<p>Снижение необходимого для сцены числа проходов текстурирования является еще одним существенным преимуществом метода отбрасывания теней. Если тени строятся на основе текстур, как описано в предыдущих частях публикации, модификации текстуры и проходы рендера, необходимые для построения теней в сцене со множеством объектов, становится многочисленными и невероятно сложными. Производительность аппаратных графических ускорителей при рендеринге текстур на разных чипсетах непредсказуема. Метод отбрасывания теней больше привязан к скорости заполнения сцены, а этот показатель проще поддается оценке при программировании для широкого спектра ускорителей.</p>
<p>При всех своих достоинствах, отбрасывание теней, как и многие новые технологии, имеет и свою теневую сторону (на этот раз каламбур родился случайно). Основная проблема – зависимость от поддержки аппаратными графическими средствами 8-битного буфера шаблонов. В то время, когда были написаны коды примеров, этот фактор был особенно актуален. Однако, глядя в будущее, можно предположить, что поддержка 8-битных буферов шаблонов станет стандартом среди графических ускорителей нового поколения. Существенное значение также имеет скорость заполнения сцены, так как при отбрасывании теней количество используемых в расчетах полигонов резко возрастает. Рендеринг теней легко может стать критическим параметром, ограничивающим производительность приложения. Единственный положительный момент заключается в том, что больше циклов процессора может быть потрачено на выполнение других частей приложения без снижения частоты кадров ниже уровня, достигнутого при рендеринге теней.</p>
<p>Меньшие сложности связаны с формированием «резких» теней, что является побочным эффектом применяемого метода. Поскольку тени формируются ребрами полигонов, их граница абсолютно четкая. Во многих ситуациях «мягкие» тени, затухающие или рассеивающиеся по краям, лучше соответствуют освещению сцены. Поскольку собственно рендеринг полигонов производится равномерно по всему экрану, операции для смягчения теней чрезвычайно трудоемки и приводят к заметному снижению скорости обработки (вплоть до полной нецелесообразности их реализации). Кроме того, если объект имеет много мелких деталей или малый размер на экране, полигоны теневого конуса могут уменьшиться до ширины в один пиксель или менее. Это приводит к появлению на экране заметных артефактов в виде разрывов или мерцания теней.</p>
<p>Последняя потенциальная проблема отбрасывания тени обусловливается сложностью продвинутого управления сценой (advanced scene management), особенно в случаях, когда освещение не ограничивается простым верхним светом (обратите внимание, что в большинстве демо-роликов, иллюстрирующих отбрасывание теней, показан только простой случай). Эта и другие проблемы более подробно рассматриваются в следующем разделе, где приводятся рекомендации по их устранению.</p>
<h2>Путь к просветлению</h2>
<p>Базовый алгоритм и общие принципы эффективного отбрасывания теней кратки и просты. Надеемся, что нам удалось представить их достаточно наглядным образом. Однако, в сущности, мы коснулись лишь основных принципов отбрасывания теней. Мы могли бы с легкостью посвятить еще с полдюжины статей дополнительным возможностям и обсуждению смежных вопросов. В завершение этой статьи мы хотели бы затронуть ряд вопросов, касающихся практической реализации данного метода, о которых вам следует помнить, приступая к любому проекту, где используется отбрасывание теней. Многие из этих вопросов являются существенными ограничениями для практического применения метода отбрасывания теней.</p>
<p>Выше мы коснулись проблемы полигонов субпиксельного размера, появляющихся из-за создания теневых объемов для насыщенных сцен или мелких объектов. Избежать этой проблемы поможет расчет и отрисовка теневых объемов с модели невидимого уровня детализации (LOD, level of detail), что также приведет к сокращению времени вычислений и рендеринга. Хотя этот метод ведет к появлению определенных артефактов, особенно в случае моделей, затеняющих самих себя, но общий результат обычно вполне приемлем. Кроме того, этот метод значительно быстрее и позволяет избавиться от неприятных артефактов, часто возникающие при визуализации объектов субпиксельного размера. Большая часть системных затрат на отбрасыванием теней от упрощенных моделей может быть оптимизирована, если упрощенные модели используются приложением для других целей, например, для обнаружения столкновений.</p>
<p>Самая серьезная проблема, связанная с отбрасыванием теней, касается вопросов сцены и геометрии. Возможно, вы замечали, что в большинстве примеров отбрасывания теней метод демонстрируется с использованием одного верхнего источника света и неподвижной камеры. Это ловко задуманный способ вызвать восхищение зрителя (и будущего программиста), не учитывающего дополнительные проблемы при изменении точки зрения и источника света. Рано или поздно, во время или после просмотра демо, программист может задаться вопросом: «А что если камера находится внутри теневого объема?» Алгоритм отбрасывания тени основан на том, что луч, направленный от наблюдателя в любую затененную точку сцены, должен пройти и через переднюю, и заднюю сторону объема. Когда объем приближается к передней плоскости, этот эффект теряется. По сути, пользователь остается один на один с недостатками реализации теней.</p>
<p><a href="/articles/content/ru-ru/2325/fig4.htm" target="_blank"><img src="http://software.intel.com/file/9240" alt="" width="150" height="55" /></a><br /> <a href="/articles/content/ru-ru/2325/fig4.htm" target="_blank">Рис. 4 — увеличить </a></p>
<h2>Покрывание теневого объема по передней плоскости (Near Plane)</h2>
<p>Наше решение этой проблемы основано на «покрывании» (capping) теневого объема в каждом случае обнаружения данной ситуации. Чтобы реализовать данный эффект, геометрия объекта была преобразована в двухмерный вариант и затем трансформирована на переднюю плоскость, идеально покрывая открытый объем. Наглядный пример изображен на <a href="/articles/content/ru-ru/2325/fig4.htm" target="_blank">Рис. 4</a>.</p>
<p>Активное отсечение невидимых объектов в пирамиде видимости и в сцене высокого уровня также может привести к проблемам генерирования теней. Даже если геометрия и источники света находятся вне текущей пирамиды видимости, тени от геометрии все же могут попадать в пределы видимой сцены. Например, когда теневой объем приближается к параллельной плоскости земли, он может вытягиваться на огромное расстояние до фактического контакта с землей. Этот фактор следует так или иначе учитывать в менеджере сцены (scene manager), в зависимости от конкретного приложения. К возможным решениям относится ограничение расстояния падения тени (чтобы упростить отбрасывание невидимых объектов в менеджере сцены), а также проведение простых проверок, чтобы определить, не может ли какой-либо элемент затенить видимую сцену. Ошибки в реализации этого аспекта могут привести к появлению внезапно появляющихся теней от объектов, которые слишком поздно были распознаны как имеющие тень.</p>
<p>Передняя плоскость пирамиды видимости также может порождать подобные сложности. Даже если предположить, что приложение не дает объектам проникать сквозь видимую переднюю плоскость, все-таки существует частный случай, когда геометрия проникает сквозь невидимую переднюю плоскость, но при этом направление света приводит к тому, что теневой объем попадает в поле обзора. Это также создает ситуацию, в которой отдельные пиксели могут лежать за пределами обеих сторон объема, что приводит к появлению нежелательных эффектов. Распознавание и исправление таких ситуаций гораздо сложнее, чем при сценарии capping, вследствие пересечения с передней плоскостью. Одно из возможных решений – создание нового силуэта для отбрасывания тени с учетом передней плоскости. Другой вариант решения – предотвратить возникновение таких ситуаций на уровне менеджера сцены. Этот путь может привести к появлению внезапно появляющихся теней, но в то же время он обычно оказывается более простым.</p>
<h2>Спецэффекты на основе теней</h2>
<p>Алгоритм отбрасывания теней является источником не только потенциальных проблем, но и новых возможностей для спецэффектов. Так, одним из простых дополнений к алгоритму может стать окрашивание теней, что позволяет создавать чрезвычайно реалистичные или поразительные визуальные эффекты. Меняя цвет поверхности пересечения, показанный в наших примерах как базовый серый, можно получить участки теней с яркими цветами или замысловатыми текстурами. Этот эффект можно использовать для получения точных цветов тени в средах с многочисленными цветными источниками света, или даже для создания зловещих потусторонних эффектов, когда тени кажутся царством ужаса и тьмы.</p>
<p>Нигде не сказано, что для создания теней обязательно использовать именно метод теневых объемов. Выбирая режим альфа-смешивания видимых объектов (alpha blend mode) или даже подбирая текстуры, можно создавать интересные эффекты направленных лучей света, прожекторов или вспышек. Такой метод эффективен при выборе аддитивных режимов смешивания для перекрывающих полигонов, при этом в большей степени создаются реалистичные эффекты наложения освещения, а не теней.</p>
<h2>Об авторах</h2>
<p>Джейсон Бестимт (Jason Bestimt) окончил Технический Университет штата Виржиния (Virginia Tech) и начала работу в группе по связям с разработчиками трехмерных приложений. Недавно он присоединился к команде студии Firaxis Games, работающей над новыми продуктами компании.</p>
<p>Брайнт Фрайтаг (Bryant Freitag) является специалистом по прикладному программированию (Application Engineer) в Отделе по связям с разработчиками корпорации Intel. Если он не занят оптимизацией, анализом и вообще своей «настоящей» работой, то отдает все силы совершенствованию видеоигр на благо всего человечества. Похоже, для этого ему и самому приходится много играть.</p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/real-time-shadow-casting-using-shadow-volumes</link>
      <pubDate>Fri, 29 Aug 2008 16:38:05 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/real-time-shadow-casting-using-shadow-volumes#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/real-time-shadow-casting-using-shadow-volumes</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Просто об импостерах</title>
      <description><![CDATA[ <h2>Введение</h2>
<p>Рендеринг сложных динамических сцен в реальном времени – довольно сложная задача. Разработчики, как и любители компьютерных игр, предпочитают иметь дело с максимально реалистичной виртуальной средой, ради которой не приходилось бы жертвовать качеством геймплея или скоростью. Примером такой среды, часто используемой в современных играх и рассмотренной в нашей статье, являются открытые природные ландшафты. Природный ландшафт подразумевает рендеринг большого количества геометрических объектов, что сильно сказывается на производительности. Рельеф, вода, облака и растительность – лишь основные составляющие этой сложнейшей задачи. Однако, благодаря изобретательности и творческому подходу при использовании  3D API, например, OpenGL, Direct3D* или любого другого API, разработчик может «выжать» из современного оборудования просто поразительное быстродействие.</p>
<p>Наш пример посвящен рендерингу моделей деревьев и основан на применении Direct3D*, но предлагаемые идеи могут применяться к любой другой трехмерной сцене, содержащей множество объектов сходной геометрии и построенной на основе любого 3D API. Деревья являются любопытным примером, поскольку обладают всеми обязательными атрибутами действительно сложной задачи для рендеринга. Они имеют сложную геометрию, в изобилии присутствуют в природном ландшафте и подвергаются воздействию природных факторов (таких как притяжение, ветер и т.д.). При этом для них может требоваться весьма детальная прорисовка текстур. Поскольку деревья существуют в природе, люди знают, как они выглядят, как ведут себя и как взаимодействуют с окружающей средой. Соответственно, у людей имеются определенные представления о том, как должны выглядеть деревья в игре. Если поставлена задача создания максимально реалистичной среды, разработчикам следует учитывать эти представления при создании виртуальных пространств.</p>
<h2>Целесообразность рендеринга полной геометрии</h2>
<p>В реальном мире произрастает множество видов деревьев, и моделирование их всех было бы чрезвычайно трудной задачей, которая потребовала бы огромных затрат времени. Однако, большинство деревьев в одном географическом районе относительно похожи, поэтому детальных моделей всего лишь четырех деревьев, которые затем можно поворачивать и масштабировать, будет вполне достаточно, чтобы смоделировать действительно реалистичный лес. Тем более, что для этого не нужно искать талантливого художника или быть им. Каждое дерево в приводимом нами примере динамически генерируется с помощью программных алгоритмов и содержит более 10 000 полигонов. Количество деревьев на нужном участке земли, а также тип, масштаб, угол поворота и положение каждого дерева определяются с помощью функции шума (noise function). Порог, определяющий плотность деревьев в лесу, задается изменяемой константой, и в первой сцене нашего примера ее значение подобрано таким образом, чтобы создать в общей сложности до 400 деревьев.</p>
<p>Предположим, что все деревья в первой сцене определены и характеристики каждого дерева (тип дерева, масштаб, угол поворота и положение) заданы. Возникает вопрос, каким образом их следует рендерить. Ответ на него отнюдь не очевиден и, в сущности, меняется в зависимости от желаемого результата. Мы рассмотрим возможные подходы к решению данной проблемы, взвешивая все «за» и «против», а также расскажем подробнее о некоторых важных особенностях программной реализации. Желаемым результатом в нашем случае является максимально быстрый рендеринг реалистичных моделей деревьев.</p>
<p>Первый способ значительно медленнее остальных, и производительность в данном случае недостаточна для моделирования игровой среды в реальном времени. Его принцип прост: рендеринг полной геометрии всего, что есть в сцене. Четыреста деревьев, по десять с чем-то тысяч полигонов на каждое дерево, не говоря уже о земле, небе, воде – это немалый объем геометрии, более 4 миллионов треугольников на кадр! Конечно, объем вычислений, который должен быть выполнен на программном уровне, весьма незначителен. Но наш движок не так эффективен, как лучшие из существующих сегодня коммерческих игровых движков, и мы смогли получить всего 1 или 2 кадра в секунду, что абсолютно неприемлемо. При таком результате следует вплотную заняться оптимизацией, и, как мы увидим далее, вполне возможно добиться существенных улучшений не снижая количества полигонов в дереве или плотности деревьев в лесу.</p>
<p>Первая очевидная возможность оптимизации – применить один из методов отсечения невидимых объектов сцены (visibility culling). В нашем примере мир делится с помощью 2-мерной сетки, при этом каждая ячейка (quadrant) сетки содержит отдельный участок рельефа, отдельную плоскость на заданном уровне для моделирования воды, и связанный список деревьев. Все те ячейки, которые не попадают в пространство обзора камеры, просто исключаются из рендеринга. Конечно, это несколько упрощенный подход к отсечению невидимых объектов, и он создает дополнительную нагрузку на программную часть, однако он помогает добиться желаемого результата. Далее по тексту мы будем подразумевать, что режим отсечения невидимых объектов включен. Это небольшое, казалось бы, изменение позволяет отрисовывать лишь 40% ячеек сетки 10 х 10, что дает максимальную частоту кадров 3 fps. Более тонкая сортировка (например, деление сцены на большее количество мелких ячеек) позволит сократить процент отрисовываемых ячеек примерно до 25%. Тем не менее, рендеринг полной геометрии видимой сцены все еще является чрезвычайно ресурсоемкой задачей, и вопрос о том, что же все-таки нужно оставить в кадре, пока не решен.</p>
<h2>О пользе импостеров</h2>
<p>Как выясняется, вовсе необязательно рендерить полную геометрию дерева, которое находится так далеко от камеры, что занимает на экране лишь один пиксель. Пользователь в любом случае едва ли сможет его разглядеть. Более того, нет необходимости в рендеринге каждого дерева, которое не находится настолько близко к воображаемой камере, чтобы пользователь мог разглядеть разницу между трехмерным деревом и похожей на дерево текстурой, или импостером (impostor). Импостер, в данном контексте, представляет собой билборд (billboard, двухмерный прямоугольник), лицевая сторона которого всегда повернута к камере, с текстурой, имитирующей геометрический объект, который он заменяет, как показано на рис. 1 и 2.</p>
<p><img src="http://software.intel.com/file/9227" alt="" width="300" height="276" /></p>
<p><em>Рис. 1: Дерево и импостер в режиме отображения объемных объектов (solid view) (альфа-канал импостера позволяет пропускать темные участки при рендеринге).</em></p>
<p><img src="http://software.intel.com/file/9228" alt="" width="300" height="276" /></p>
<p><em>Рис. 2: То же дерево и импостер в режиме отображения сетки (wireframe view)</em></p>
<p>Использование импостеров радикально сокращает количество полигонов, но влечет за собой ряд новых вопросов:</p>
<ul>
<li>Как с помощью биллбордов представлять отдельные деревья под разными углами зрения?</li>
<li>Когда следует рендерить импостер, а когда – реальное дерево?</li>
<li>Как генерировать импостеры?</li>
</ul>
<br />
<p>Теперь начинается самое интересное с точки зрения разработчика. Представьте, что вы обходите по кругу дерево в реальном мире. Ветки дерева неподвижны по отношению к стволу. Иными словами, они не вращаются на стволе, чтобы постоянно быть у вас перед глазами. Теперь представьте, что камера в игре движется вокруг дерева – или любого похожего объекта. Если дерево будет выглядеть одинаково с любой точки обзора, цель симулирования реальности достигнута не будет. Чтобы избежать этого, следует отрисовывать полную геометрию любого дерева, находящегося в пределах определенного расстояния от камеры, а дальние деревья можно отображать в виде импостеров. Но и в этом случае остается одна проблема.</p>
<p>Как мы уже упоминали, каждое дерево в сцене обладает уникальными характеристиками, присвоенными ему при генерировании. Если для всех импостеров применять одинаковую текстуру, то все деревья, изображенные импостерами, будут выглядеть абсолютно одинаково, и в итоге ваш лес будет выглядеть совсем не натурально. Кроме того, если дистанция от камеры до дерева сократится до величины, при которой геометрия дерева должна быть отрисована полностью, обязательно проявится весьма заметный эффект внезапного появления. Однако еще не все потеряно, так как в нашем арсенале есть мощный инструмент, который поможет поддержать иллюзию: метод «рендеринг в текстуру» (render-to-texture).</p>
<h2>Умелое использование метода render-to-texture</h2>
<p>Рендеринг деревьев только с одной точки обзора (вида) нецелесообразен по причинам, упоминавшимся выше; следовательно, необходимо решить, сколько видов для каждого дерева нужно рендерить в текстуру, следует ли использовать одну текстуру для каждого вида или одну текстуру для всех выбранных видов. Секрет выбора количества видов - в тщательном подборе расстояния замены, т.е. расстояния от камеры, на котором вместо импостера рендерится уже полная геометрия дерева. Чтобы сократить объем занимаемой памяти и при этом сохранить иллюзию реальности, в нашем примере используется расстояние замены, при котором отсутствует заметный эффект внезапного появления. Мы используем всего восемь видов: север, северо-восток, восток, и так далее. Обычно этих восьми видов вполне достаточно, но вы можете экспериментировать с большим или меньшим количеством, в зависимости от потребностей вашего приложения. Конечно, при этом важно учитывать, что все зависит от масштабов виртуального мира, где должны расти деревья. Но после ряда экспериментов относительно нетрудно найти подходящую величину.</p>
<p>Рассмотрим вторую проблему: использовать по одной текстуре для каждого вида или одну текстуру, изображающую все восемь видов модели дерева. Подкачка текстур (texture swapping) в современных API может оказаться весьма ресурсоемкой, поэтому рендериг каждого вида дерева в отдельную текстуру может привести к существенным затратам ресурсов. Рендеринг всех восьми видов дерева в одну текстуру значительно сокращает объемы подкачки текстур. Следующий шаг, рендеринг всех восьми видов всех четырех деревьев в одну текстуру, вообще устраняет необходимость в подкачке текстур в интервалах обработки импостеров. В целях сохранения реалистичности при одновременном снижении нагрузки на ресурсы системы и повышении производительности в нашем примере используется именно последний метод.</p>
<p>Хотя данное решение и весьма эффективно, рендеринг всех возможных видов модели в одну текстуру по методу render-to-texture имеет свои недостатки. Первый недостаток связан с рендерингом в текстуру с альфа-каналом и присущ всем методам рендеринга в текстуру (альфа-канал необходим для того, чтобы сделать возможным альфа-тест на фоне импостеров за проход рендера). В приводимом в качестве примера коде создается область памяти для вывода изображения (render target, область рендеринга) с альфа-каналом, который, однако, поддерживается не всеми аппаратными графическими средствами. Мы протестировали наш пример на нескольких графических картах и получили хорошие результаты (с использованием последних доступных версий драйверов), но вовсе не исключаем, что на некоторых конфигурациях наш пример не будет запускаться правильно.</p>
<p>Если необходимо обеспечить совместимость с графическими картами, которые не поддерживают объекты типа «render target» с альфа-каналом, существует способ обойти эту проблему. Вместо того, чтобы создавать область рендеринга с альфа-каналом, создайте базовую (блокируемую) область рендеринга. Также создайте текстуру в системной памяти с тем же размером, что и область рендеринга, текстуру с альфа-каналом в системной памяти, и текстуру с альфа-каналом в видеопамяти. Этот метод проиллюстрирован на приводимой ниже схеме, и мы разберем его более подробно:</p>
<p><img src="http://software.intel.com/file/9229" alt="" width="466" height="96" /></p>
<p><em>Рис. 3: Создание импостера с альфа-каналом для графических карт, прямо не поддерживающих рендеринг в текстуры с альфа-каналом.</em></p>
<p>Сначала создайте объект в области рендеринга. Заблокируйте область рендеринга, скопируйте данные в текстуру в системной памяти, имеющую тот же размер, и разблокируйте область рендеринга. На этом этапе область рендеринга можно удалить, она больше не понадобится. Скопируйте данные из текстуры в системной памяти в текстуру с альфа-каналом в системной памяти, по необходимости устанавливая при этом значения альфа-канала (непрозрачные пиксели там, где отрисован объект, прозрачные в остальных областях). Наконец, заблокируйте текстуру с альфа-каналом в видеопамяти, скопируйте данные из системной текстуры с альфа-каналом и разблокируйте видео-текстуру с альфа-каналом. В результате должен получиться точный импостер объекта с установленными значениями прозрачности для альфа-теста при рендеринге импостера. Поскольку эти операции выполняются только во время запуска, потери производительности не существенны.</p>
<p>Второй недостаток метода рендеринга всех возможных видов в одну текстуру связан с возможной альтернативой импостерам – точечными спрайтами (point sprites). Если все восемь видов всех четырех деревьев отрисованы в одну текстуру, это означает, что для каждого импостера должен применяться какой-либо метод трансформации текстуры (см. рис. 4). В DirectX* 8.0 точечные спрайты не поддерживают трансформацию текстуры, поэтому, разрешив точечные спрайты, придется рендерить каждый вид каждого дерева в отдельную текстуру. Мы отвергли этот вариант по причинам, описанным выше, поэтому мы вынуждены отказаться от использования точечных спрайтов, хотя они и имеют преимущество в виде необходимости хранения только z-координаты (z-position).</p>
<p><img src="http://software.intel.com/file/9230" alt="" width="362" height="211" /></p>
<p><em>Рис. 4: Трансформации текстуры импостера (выбор координат текстуры)</em></p>
<p>При этом усложняется реализация текстур с MIP-картами (MIP-mapped textures), поскольку необходимо создавать буферы вокруг вида каждого дерева, чтобы избежать размытости на границах текстур.</p>
<p>После определения схемы текстурирования следует переходить к следующему важному аспекту, который необходимо учитывать при рендеринге сотен (возможно, тысяч) мелких объектов в Direct3D*: правильное использование буферов вершин. Поскольку все импостеры, по сути, представляют собой квадранты (quads) с координатами конкретной текстуры, рассчитываемыми на основе угла поворота каждого дерева, можно использовать</p>
<ul>
<li>единый буфер вершин на 32 вершины для всех импостеров или</li>
<li>буфер вершин на 4 вершины для каждого импостера </li>
</ul>
<br />
<p>В каждом из этих случаев придется «на лету» выбирать нужные координаты текстуры для каждого импостера, однако это справедливо для любой ситуации, когда одна текстура изображает несколько видов. Снижение производительности происходит из-за сотен вызовов функции DrawIndexedPrimitive(), причем за каждый вызов получается рендерить только 4 вершины.</p>
<p>Большей эффективности можно добиться за счет выполнения трансформаций для всех импостеров на программном уровне с последующим помещением всех трансформированных вершин в единый большой буфер вершин. В примере использован буфер вершин, способный вместить 1000 импостеров деревьев (4000 вершин), хотя потенциально возможна поддержка до 16 000 импостеров деревьев (64 000 вершин). В примере реализована поддержка только 1000 импостеров деревьев на буфер, поскольку прирост производительности при увеличении вместимости буфера свыше 4000 вершин ничтожно мал. Хотя может показаться, что это чересчур сложное решение для того, чтобы использовать лишь одну текстуру, советуем вам попробовать выполнять расчеты трансформаций импостеров (масштабирование, поворот, позиционирование, расчет координат текстуры) на программном уровне и использовать единый большой буфер вершин. Конечный результат будет весьма хорош как визуально, так и с точки зрения производительности. Производительность, измеряемая по частоте кадров, возрастает с жалких 3 fps до целых 90 fps, то есть почти на 1000%!</p>
<p><img src="http://software.intel.com/file/9231" alt="" width="233" height="159" /></p>
<p><em>Сцена, отрисованная без импостеров</em></p>
<p><img src="http://software.intel.com/file/9232" alt="" width="233" height="160" /></p>
<p><em>Аналогичная сцена, отрисованная с импостерами</em></p>
<h2>Выводы</h2>
<p>Как свидетельствуют факты, быстрый рендеринг простых импостеров представляет собой замечательный инструмент в арсенале разработчика. Сочетание таких методов, как «render-to-texture», с алгоритмическим созданием контента (procedural content) снижает потребность в дополнительных графических ресурсах и сокращает время разработки контента. Тщательное продумывание процессов отсечения невидимых объектов, текстурирования и использования API поможет увеличить общую скорость рендеринга в вашем графическом конвейере и в итоге повысит общее качество визуализации. Надеемся, что представленные здесь идеи пригодятся вам, когда вы в следующий раз столкнетесь со сложной проблемой виртуального представления реального мира.</p>
<p><strong><a href="/en-us/articles/code-samples-license-2?target=http%3A%2F%2Fwww.intel.com%2Fcd%2Fids%2Fdeveloper%2Fasmo-na%2Feng%2F17950.htm">Загрузить исходный код</a></strong></p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/impostors-made-easy</link>
      <pubDate>Thu, 24 Jul 2008 17:31:23 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/impostors-made-easy#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/impostors-made-easy</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Краткий справочник по интегрированным графическим ускорителям Intel® серии GMA *4500</title>
      <description><![CDATA[ <p><em>Данная статья содержит краткий обзор возможностей и технические характеристики интегрированных графических ускорителей Intel серии GMA *4500.</em></p>
<h2>Условные обозначения чипсетов</h2>
<p>Наборы системной логики Intel классифицируются с точки зрения платформы и рыночного сегмента, на который они ориентированы. В настоящий момент в нашем ассортименте представлены чипсеты для настольных ПК, ноутбуков, серверов и рабочих станций, для встроенных систем и устройств потребительской электроники. Данная статья рассматривает чипсеты для настольных ПК и ноутбуков и включает описание различий между интегрированными графическими ускорителями Intel®, входящих в состав рассматриваемых чипсетов.</p>
<p>Стандартные чипсеты для настольных систем выпускаются как с интегрированным графическим ускорителем (GMA, Graphics Media Accelerator), так и без него. Чипсеты без GMA имеют в названии префикс или суффикс «P», а чипсеты с GMA – соответственно «G» или «Q». Чипсеты серии «G» в первую очередь предназначены для потребительских настольных систем, в то время как серия «Q» ориентирована на системы для малого, среднего и крупного бизнеса. Например, Intel® G965 Express представляет собой продукт для потребительских настольных ПК, а Intel® Q965 Express – это решение для малого/среднего/крупного бизнеса. Чипсеты для ноутбуков, как правило, маркируются префиксом или суффиксом «М». В частности, аналогичная модель для ноутбука называется Intel® GM965 Express.</p>
<p>Вы можете ознакомиться с полным ассортиментом чипсетов Intel® и их техническими характеристиками, перейдя по приводимой ниже ссылке.</p>
<p><a href="http://www.intel.com/design/chipsets/express_flyer.htm">http://www.intel.com/design/chipsets/express_flyer.htm</a></p>
<h2>Графические ускорители Intel® серий GMA 4500, X4500 и X4500HD</h2>
<p>В приведенной ниже таблице показаны основные характеристики чипсетов серии Intel® 4 Series. В сочетании с процессорами Intel® Core2™ Duo, чипсеты серии Intel® 4 Series обеспечивают высокую производительность и низкое время отклика. В Таблице 1 приводится подробное описание графических функций, которые поддерживаются чипсетами с графическими ядрами GMA 4500, X4500 и X4500HD.</p>
<table class="tableformat1" border="0" cellspacing="0" cellpadding="5" width="624">
<tbody>
<tr>
<td width="139">
<p>Чип</p>
</td>
<td width="122">
<p>G45</p>
</td>
<td width="117">
<p>G43</p>
</td>
<td width="117">
<p>G41</p>
</td>
<td width="128">
<p>Q45/Q43</p>
</td>
</tr>
<tr>
<td width="139">
<p>Графическое ядро</p>
</td>
<td width="122">
<p>GMA X4500HD</p>
</td>
<td width="117">
<p>GMA X4500</p>
</td>
<td width="117">
<p>GMA X4500</p>
</td>
<td width="128">
<p>GMA 4500</p>
</td>
</tr>
<tr>
<td width="139">
<p>Аппаратное ускорение декодирования MPEG2</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Нет</p>
</td>
</tr>
<tr>
<td width="139">
<p>Аппаратное ускорение декодирования VC1</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="128">
<p>Да</p>
</td>
</tr>
<tr>
<td width="139">
<p>Аппаратное ускорение декодирования AVC</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="117">
<p>Нет</p>
</td>
<td width="128">
<p>Да</p>
</td>
</tr>
<tr>
<td width="139">
<p>Функции защиты HD-содержимого PAVP/HDCP</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Да</p>
</td>
</tr>
<tr>
<td width="139">
<p>Интерфейсы дисплея</p>
</td>
<td width="122">
<p>DisplayPort, HDMI, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
<td width="117">
<p>DisplayPort, HDMI, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
<td width="117">
<p>DisplayPort, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
<td width="128">
<p>DisplayPort, DVI, SDVO</p>
<p>Независимые выходы на два дисплея</p>
</td>
</tr>
<tr>
<td width="139">
<p>Разрешение HD</p>
</td>
<td width="122">
<p>1080p/i, 720p</p>
</td>
<td width="117">
<p>1080p/i, 720p</p>
</td>
<td width="117">
<p>1080p/i, 720p</p>
</td>
<td width="128">
<p>1080p/i, 720p</p>
</td>
</tr>
<tr>
<td width="139">
<p>Поддержка DirectX*</p>
</td>
<td width="122">
<p>DX 10</p>
</td>
<td width="117">
<p>DX 10</p>
</td>
<td width="117">
<p>DX 10</p>
</td>
<td width="128">
<p>DX 10</p>
</td>
</tr>
<tr>
<td width="139">
<p>Рейтинг совместимости Windows Vista*</p>
</td>
<td width="122">
<p>Premium</p>
</td>
<td width="117">
<p>Premium</p>
</td>
<td width="117">
<p>Premium</p>
</td>
<td width="128">
<p>Premium</p>
</td>
</tr>
<tr>
<td width="139">
<p>Поддержка OpenGL*</p>
</td>
<td width="122">
<p>2.0*</p>
</td>
<td width="117">
<p>2.0*</p>
</td>
<td width="117">
<p>2.0*</p>
</td>
<td width="128">
<p>2.0*</p>
</td>
</tr>
<tr>
<td width="139">
<p>Технология Intel® Clear Video</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Нет</p>
</td>
</tr>
<tr>
<td width="139">
<p>Постпроцессинг HD-содержимого</p>
</td>
<td width="122">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="117">
<p>Да</p>
</td>
<td width="128">
<p>Нет</p>
</td>
</tr>
</tbody>
</table>
<p>*Поддержка OGL 2.0 будет добавлена после обновления драйвера. Изначально поддерживается OGL 1.5.</p>
<p>Таблица 1: <strong>Функции графических ускорителей чипсетов Intel® 4 Series</strong></p>
<h2>Технология Intel® Clear Video</h2>
<p>Пользователи современных домашних кинотеатров систем ожидают от своего ПК отличного качества воспроизведения видео и высокой четкости изображения. Графические решения Intel с технологией Intel® Clear Video Technology имеют улучшенныесредства обработки видео и обладают богатым потенциалом для цифровых развлечений. Графические решения Intel также поддерживают новейшие форматы высокого разрешения, в том числе HD DVD и Blu-ray. В Таблице 2 указаны функции работы с видео, которые поддерживаются новейшими моделями интегрированных графических ускорителей Intel.</p>
<table class="tableformat1" border="0" cellspacing="0" cellpadding="5" width="624">
<tbody>
<tr>
<td width="94">
<p>Категория</p>
</td>
<td colspan="2" width="157">
<p>Функция</p>
</td>
<td width="60">
<p>G965</p>
</td>
<td width="53">
<p>G33<br /> G31</p>
</td>
<td width="53">
<p>G35</p>
</td>
<td width="69">
<p>G41</p>
</td>
<td width="69">
<p>G43</p>
</td>
<td width="69">
<p>G45</p>
</td>
</tr>
<tr>
<td rowspan="9" width="94">
<p> </p>
<p>Декодирование цифрового содержимого HD</p>
</td>
<td colspan="2" width="157">
<p>Аппаратная компенсация движения H.264</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Инверсное преобразование H.264</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Декодирование с переменной длиной H.264</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Аппаратная компенсация движения VC1</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Инверсное преобразование VC1</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Декодирование с переменной длиной VC1</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Аппаратная компенсация движения MPEG2</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Инверсное преобразование c кодированием расстояния (DC) MPEG2</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Декодирование с переменной длиной MPEG2</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td rowspan="10" width="94">
<p>Улучшение качества видео/пост-процессинг</p>
</td>
<td colspan="2" width="157">
<p>Поддержка Advanced DI (HD)</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Поддержка Advanced DI (SD)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Определение модуляции/режима Film Mode для HD</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>15.9.3*</p>
</td>
<td width="69">
<p>15.9.3*</p>
</td>
<td width="69">
<p>15.9.3*</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Определение модуляции/режима Film Mode для SD</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Фильтры Detail и Denoise</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Нелинейное анаморфное масштабирование</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>4x4 масштабирование с высоким качеством</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>6x6 масштабирование по полифазной матрице</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Управление цветом ProcAmp Color</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" width="157">
<p>Управление цветом ProcAmp для HD</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" rowspan="3" width="96">
<p>Защита цифрового содержимого</p>
</td>
<td width="156">
<p>COPP/OPM</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Защита от захвата экрана</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Protected Audio/Video Path (PAVP)</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" rowspan="2" width="96">
<p>Поддержка дисплея</p>
</td>
<td width="156">
<p>Поддержка разрешения Full HD 1080p</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Intel® TV Wizard</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td colspan="2" rowspan="6" width="96">
<p>Интерфейсы дисплея</p>
</td>
<td width="156">
<p>HDMI (встроенный)</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>HDMI (через SDVO)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>DisplayPort</p>
</td>
<td width="60">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="53">
<p> </p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>S-video (через SDVO)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>DVI / SDVO / VGA</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
<tr>
<td width="156">
<p>Независимые выходы на два дисплея (Dual Independent Display)</p>
</td>
<td width="60">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="53">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
<td width="69">
<p>X</p>
</td>
</tr>
</tbody>
</table>
<p>Таблица 2: <strong>Сравнение чипсетов с технологией Intel® Clear Video</strong></p>
<p>Перечисленные ниже ресурсы Intel помогут вам получить как общую, так и более подробную информацию о графических ускорителях и чипсетах Intel.</p>
<p>Описание возможностей графических ускорителей Intel: <a href="http://download.intel.com/products/graphics/intel_graphics_guide.pdf">http://download.intel.com/products/graphics/intel_graphics_guide.pdf</a></p> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/quick-reference-guide-to-intel-integrated-graphics</link>
      <pubDate>Tue, 22 Jul 2008 15:18:04 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/quick-reference-guide-to-intel-integrated-graphics#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/quick-reference-guide-to-intel-integrated-graphics</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Продукты семейства Intel® Threading Tools помогают повысить производительность ресурсоёмких приложений компьютерной графики</title>
      <description><![CDATA[ <p class="sectionHeading">Введение</p>
<p><em>Продукты семейства Intel&reg; Threading Tools помогают компании Autodesk оптимизировать программное обеспечение Maya*. В статье рассказывается о совместной работе Autodesk с инженерами Intel над реализацией проекта по распараллеливанию модуля Maya Fluid Effects*.</em></p>
<br />
<p>Для компании Autodesk из Торонто настали хорошие времена. Maya*, флагманский продукт компании, занимает ведущее положение на рынке программного обеспечения для создания цифрового контента (DCC, Digital Content Creation) в области трёхмерного моделирования, анимации, спецэффектов и рендеринга. Художники, использующие Maya, создают потрясающие изображения для самых различных областей индустрии, начиная от цифровой печати и компьютерного дизайна и заканчивая телевидением и компьютерными играми. <br />
</p>
<p>Отдельно стоит отметить киноиндустрию. Несмотря на достаточно скромное прошлое компании в Канаде, где она была основана, программы Autodesk использовались при создании визуальных эффектов для ряда голливудских блокбастеров, имевших огромный успех в мировом прокате, в числе которых трилогия &laquo;Властелин колец&raquo; и приквелы &laquo;Звездных войн&raquo;*.</p>
<br />
<p>При этом для Autodesk и других компаний сегмента DCC планка требований постоянно повышается. Любителей кино и компьютерных игр уже не удивишь фотореалистичной графикой и надо приложить значительные усилия, чтобы визуальные эффекты не вызывали у них недоверия. Поэтому создание и рендеринг максимально детализированных образов продолжают оставаться одними из самых ресурсоемких операций компьютерной графики.</p>
<br />
<p>&laquo;Ведущие компьютерные студии полагаются на программное обеспечение Maya в реализации самых современных проектов, и важнейшим фактором для них является производительность&raquo;, - поясняет инженер Autodesk Мартин Уотт (Martin Watt). &laquo;Ключевую роль для нас играет оптимизация любых процессов, например, повышение скорости интерактивного рисования или сокращение времени визуализации тысяч кадров&raquo;.</p>
<br />
<div style="TEXT-ALIGN: center"><a target="_blank" href="/file/9253"><img alt="" width="370" border="0" src="http://software.intel.com/file/9253" /></a><br />
<p>(Нажмите на изображение для увеличения)</p>
<br />
<p><em>Изображение предоставлено Данканом Бринсмидом (Duncan Brinsmead), Autodesk</em></p>
</div>
<br />
<p>Объединенная команда инженеров Autodesk и Intel провела серьезную работу, реализуя параллельные вычисления в Maya Fluid Effects. Данный ресурсоемкий набор инструментов включает полноценный трехмерный вычислительный модуль и интерактивный двухмерный модуль, которые позволяют симулировать двухмерное движение текучей среды в режиме, приближенном к реальному времени. Выше представлен пример атмосферного эффекта, созданного с помощью Maya. Атмосферные эффекты, включая дым от грибовидного облака, являются одним из типов поддающегося симулированию движения текучей среды.</p>
<br />
<p>Проблема заключается в том, что частота процессоров сегодня не растет с такой скоростью, как это было раньше. По мере уменьшения размеров чипов и роста числа транзисторов, задача охлаждения процессора становится все более трудно решаемой.</p>
<br />
<p>Для того, чтобы решить эту проблему, производители микропроцессоров внедряют параллельные алгоритмы на уровне чипов, главным образом, путем создания многоядерных архитектур. Вместо наращивания мощности и вывода на рынок более быстрых и, следовательно, сильно нагревающихся процессоров, производители решили развивать архитектуру качественно, разделив вычислительные задачи между несколькими ядрами.</p>
<br />
<p>Хорошая новость заключается в том, что решительный переход на многоядерные системы продолжит ту тенденцию, которая всегда была характерна для отрасли микрочипов, &ndash; создание в долгосрочной перспективе все более мощных аппаратных платформ. Сложность заключается в том, что для эффективного использования новых разработок от компаний-поставщиков ПО требуется увеличить степень распараллеливания программного кода. </p>
<br />
<p class="sectionHeading">Команда инженеров Autodesk-Intel решает проблему многопоточности</p>
<p>Учитывая перемены в отрасли производства микрочипов, весной 2005 года компания Autodesk решила попробовать использовать технологию параллельных вычислений в модуле Maya Fluid Effect*. Целью работ стало ядро системы Maya Fluid Effects &ndash; модуль вычисления движений текучей среды, пропускающий данные через уравнения Навье-Стокса(Navier-Stokes equations), хорошо известные специалистам в области физики в качестве средства описания движения текучих сред.</p>
<br />
<p>Autodesk сотрудничала с инженерами компании Intel при работе над проектом многопоточных вычислений в рамках программы Intel по содействию клиентам в области совершенствования ПО. И даже несмотря на присутствие на проекте специалистов по многопоточным технологиям из Intel, Уотт немного волновался.</p>
<br />
<p>&laquo;Устранение ошибок в параллельных приложениях является исключительно сложной задачей&raquo;, - говорит Уотт. &laquo;В прошлом мы потратили много времени на то, чтобы заставить части нашего программного кода корректно выполняться в многопоточной среде&raquo;.</p>
<br />
<p>Вычислительный модуль движения текучей среды выполняет ряд однородных преобразований непрерывного массива данных. Оказалось, он очень легко поддается распараллеливанию.Поскольку продукт Maya долгое время использовался на компьютерах с несколькими процессорами, существовал алгоритм, благодаря которому несколько процессоров могли работать параллельно над частью массива, не вмешиваясь в работу друг друга.</p>
<br />
<p>Успешная параллелизация программного обеспечения Maya преимущественно была достигнута благодаря использованию комплекта инструментов <a href="http://www.intel.com/cd/software/products/asmo-na/eng/threading/219785.htm">Intel&reg; Threading Tools</a>. Например, с помощью программы Intel&reg; Thread Checker быстро удалось найти несколько трудноуловимых проблем с параллельными операциями. В условиях приближения срока завершения проекта альтернатива в виде ручного устранения ошибок в крупной и сложной системе Maya казалась малопривлекательной и, возможно, даже нереальной.</p>
<br />
<p>Intel&reg; Thread Profiler помогла проанализировать узкие места и решить особенно важный недостаток, проявившийся уже на начальном этапе проекта. Одна часть распараллеленного модуля вычислений движения текучей среды работала медленнее, чем его первоначальный вариант.</p>
<br />
<p>&laquo; Продукт Intel&reg; Thread Profiler помог быстро выявить проблемные области и показал причины замедления работы, в результате чего мы смогли реструктурировать программный код для обеспечения более высокой производительности многопоточных вычислений&raquo;, - говорит Уотт.</p>
<br />
<p>Разработчики внесли поддержку дополнительных потоков, добавив несколько директив OpenMP* в код модуля движения текучей среды. Эти потоковые директивы выглядят как комментарии в других компиляторах (не использующих интерфейс OpenMP), которые просто игнорируют директивы компиляции. В отличие от этого компиляторы OpenMP, например Intel&reg; C++ Compilers, находят директивы и реализуют многопоточность.</p>
<br />
<p>&laquo;Интерфейс OpenMP является полезным средством создания прототипов при распараллеливании алгоритмов, поскольку его очень легко применять к существующему программному коду&raquo;, - говорит Уотт. &laquo;Его также легко включить и выключить, благодаря чему появляется возможность быстро сравнить результаты с включенной и выключенной поддержкой многопоточности&raquo;.</p>
<br />
<div style="FLOAT: left; WIDTH: 250px; HEIGHT: 185px"><img height="180" alt="" width="240" src="http://software.intel.com/file/9254" />
<p><em>Изображение предоставлено Мартином Уоттом, Autodesk</em></p>
</div>
<p>Мартин Уотт, инженер компании Autodesk, входил в состав команды инженеров Autodesk и Intel. &laquo;В прошлом мы потратили много времени на то, чтобы части нашего программного кода корректно работали в многопоточной среде&raquo; - говорит Уотт. &laquo;При работе над внедрением параллельных вычислений в Maya 7 мы смогли использовать программы Intel&reg; Thread Checker и Intel&reg; Thread Profiler для анализа нашего кода на предмет корректной параллельной работы и оценки полученной производительности&raquo;.</p>
<div style="CLEAR: both"></div>
<br />
<p class="sectionHeading">И победа присуждается...</p>
<p>Результаты работы команды по созданию прототипа были поразительными. По словам Уотта, многопоточный вычислительный модуль движения текучей среды заработал на 85 процентов быстрее на компьютере с двумя процессорами Intel&reg; Xeon&reg;. Кроме этого, скорость работы возросла более чем на 115 процентов при использовании программы на двухпроцессорной системе Intel Xeon с технологией Hyper-Threading.</p>
<br />
<p>От вложений в многопоточность будут получены сходные &laquo;дивиденды&raquo; при использовании данной технологии на многоядерных платформах, число которых, как ожидается, в будущем только вырастет. Например, по прогнозам компании Intel, к концу 2006 года существенная часть поставок серверных процессоров компании, а также процессоров для мобильных устройств и персональных компьютеров семейства Pentium&reg; будет приходиться на <a href="http://www.intel.com/multi-core/index.htm">многоядерные системы.</a></p>
<br />
<p>В число дополнительных средств, использованных командой инженеров Autodesk и Intel, входила программа Intel&reg; VTune&trade; Performance Analyzer, применявшаяся для определения тех операций, в которых вычислительный модуль движения текучей среды задействовал большую часть ресурсов процессора. Затем программный код был изучен на предмет степени его восприимчивости к технологии многопоточности. Эти данные позволили команде применить закон Амдаля (Amdahl's Law) для определения возможной степени повышения производительности за счет использования параллельных вычислений.</p>
<br />
<p>Закон Амдаля позволяет количественно оценить естественные закономерности выполнения программного кода: чем меньше программа зафиксирована на линейных и последовательных сегментах, тем больше возможностей повысить производительность за счет параллельных операций.</p>
<br />
<p>&laquo;Для чего применяется Закон Амдаля? Для того, чтобы понять, насколько еще можно повысить производительность&raquo;, - говорит Роберт Рид (Robert Reed), один из инженеров Intel, работавших над проектом.</p>
<br />
<p class="sectionHeading">Ожидания пользователей</p>
<p>Многопоточный и более производительный программный код был готов в срок для включения в релиз Maya 7. И хотя это пока единственный случай быстрого и очевидного успеха технологии многопоточных вычислений, пример сотрудничества Intel и Autodesk сулит большой потенциал для конечных пользователей, на которых вот-вот &laquo;обрушится&raquo; поток многоядерных платформ: от карманных компьютеров и ноутбуков до рабочих станций и серверов.</p>
<br />
<p>Для непрерывного роста производительности при работе на данных платформах пользователям будет необходим доступ к расширенному портфелю многопоточных программ. Одним из пользователей программного обеспечения Maya является Роб Ван ден Брагт (Rob van den Bragt), начальник отдела компьютерной графики лондонской компании &laquo;The Mill&raquo;, которая завоевала награду Оскар* за спецэффекты.</p>
<br />
<p>&laquo;Учитывая сложность симуляции движения текучей среды, нам нужна максимальная вычислительная мощность&raquo;, - говорит Ван ден Брагт. &laquo;Поэтому известия о приросте производительности за счет поддержки многопоточности модулем вычисления текучей среды в Maya 7 были встречены нами с распростертыми объятиями&raquo;.</p>
<br />
<p>Совместная работа с Intel произвела сильное впечатление на Уотта и его коллег-инженеров из Autodesk, задача которых заключается в том, чтобы такие нуждающиеся в высокой производительности клиенты, как Ван ден Брагт, оставались довольными.</p>
<br />
<p>&laquo;Мы понимаем, что будущее за системами с увеличенным количеством процессорных ядер, и для того, чтобы воспользоваться всей этой мощностью, потребуется поддержка многопоточности&raquo;, - говорит Уотт. &laquo;Мы хотим оптимизировать наш программный код, чтобы получить возможность в полной мере реализовать весь потенциал расчета стольких параллельных операций, сколько сможет поддерживать аппаратное обеспечение&raquo;.</p>
<br />
<p class="sectionHeading">Дополнительные ресурсы</p>
<ul>
    <li><a href="/isn/Home/Multicore.aspx">Сообщество разработчиков параллельных приложений</a> </li>
</ul>
<br />
<p><strong>Статьи</strong></p>
<ul>
    <li><a href="/ru-ru/articles/threading-basics-for-games">Основы разработки многопоточных игровых приложений</a> </li>
    <li><a href="/ru-ru/articles/transitioning-to-multi-core-chip-architecture">Переход на многоядерную архитектуру</a> </li>

</ul>
<br />
<p><strong>Центры разработки</strong></p>
<ul>
    <li><a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/enterprise/index.htm">Enterprise Developer Center</a> </li>
    <li><a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/tools/index.htm">Intel&reg; Software Tools Developer Center</a> </li>
    <li><a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/threading/index.htm">Threading Developer Center</a> </li>
</ul>
<br />
<p><strong>Обучение</strong></p>
<ul>
    <li><a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/18514.htm">Detecting Hyper-Threading Technology</a> </li>
</ul> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/intel-threading-tools-boost-performance-for-cpu-cycle-hungry-digital-artists</link>
      <pubDate>Sat, 07 Jun 2008 19:45:54 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/intel-threading-tools-boost-performance-for-cpu-cycle-hungry-digital-artists#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/intel-threading-tools-boost-performance-for-cpu-cycle-hungry-digital-artists</guid>
      <category>Параллельное программирование</category>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
    <item>
      <title>Распространенные заблуждения об интегрированной графике Intel®</title>
      <description><![CDATA[ <div class="sectionBody">
<p class="sectionHeading">Интегрированные графические адаптеры Intel® GMA X3000</p>
<p>Графические ускорители Intel® Graphics Media Accelerator (GMA)  X3000 удовлетворяют  большинство потребностей организаций и индивидуальных пользователей, которым не  нужны дорогостоящие решения для работы с трехмерной графикой. Графическое ядро GMA X3000 встроено в чипсет и интегрировано в системную плату. Впервые среди  интегрированных графических решений, данная серия поддерживает функцию  аппаратного расчета трансформаций и освещения (T&amp;L, HW Transform and Lighting). Встроенные в контроллер памяти, эти ускорители используют  разделяемую с операционной системой память, за счет чего достигается баланс производительности  системы. Интегрированное в чипсет графическое ядро Intel новейшего поколения  – Intel® X3000 – обеспечивает недостижимый  прежде уровень производительности графики при весьма привлекательной стоимости.  Такой взвешенный подход был по достоинству оценен покупателями, - встроенные  графические адаптеры Intel стали одними из самых выгодных решений для пользователей ПК.</p>
<br />
<p>В данной статье рассматриваются наиболее  распространенные заблуждения об интегрированной графике Intel и приводятся мнения  специалистов, которые не всегда находят отражение в отраслевой прессе. Статья  охватывает вопросы, которые обычно возникают у поставщиков программного  обеспечения, и включает сведения о чипсетах Intel X3000, в том числе описание их характеристик и поддерживаемых функций. В  статье объясняется, почему данные решения являются сильным аргументов в пользу  применения широко распространенных базовых графических технологий. Мы надеемся,  что представленные графические решения смогут завоевать широкое признание и еще  в большей степени оправдать ожидания пользователей.</p>
<br />
<p class="sectionHeading">Что представляет собой интегрированная графика  Intel?</p>
<p>Чипсет Intel X3000 поддерживает ключевые функции, доступные в предыдущих поколениях  графических ускорителей Intel, в частности технологию динамического управления  видеопамятью (DVMT, Dynamic Video Memory Technology ), а также аппаратное ускорение  трехмерной графики, использующей библиотеки Microsoft DirectX* 9.0C and OpenGL* 1.5X. Учитывая, что чипсеты серии Intel GMA 3x00 (946GZ, Q963, Q965, G31, Q33, Q35, G33) поддерживают программные вершинные шейдеры  (vertex shaders) и аппаратные пиксельные шейдеры (pixel shaders) модели 3.0, в Intel X3000 реализована шейдерная модель (Shader Model) 3.0 с полной поддержкой  аппаратных вершинных и пиксельных шейдеров при условии использования последней  версии драйверов. </p>
<br />
<p>Используемое в чипсете Intel X3000 графическое ядро Intel GMA является первой платформой, построенной на  основе данной архитектуры.  В дальнейшем,  для краткости, мы будем называть его «интегрированной графикой Intel X3000». В платформах следующих поколений будут  использоваться обновленные версии этой архитектуры с расширенным функционалом и  улучшенными характеристиками.</p>
<br />
<p class="sectionHeading">Подробности</p>
<p>При использовании совместно с процессорами Intel® Core™2 Duo, чипсет Intel X3000 обеспечивает необходимую производительность системного  уровня и быстроту обработки запросов.</p>
<br />
<p class="sectionHeading">Графические чипсеты серии Intel X3000</p>
<br />

<table cellspacing="0" cellpadding="5" class="tableformat1">
    <tbody>
        <tr>
            <td width="16.96%">
            <p>Графическое ядро</p>
          </td>
            <td width="23.54%" colspan="3">
            <p>GMA 3000</p>
            </td>
            <td width="21.38%" colspan="2">
            <p>GMA 3100</p>
            </td>
            <td width="9.44%">
            <p>GMA X3000</p>
            </td>
            <td width="12%">
            <p>GMA X3100</p>
            </td>
            <td width="16.68%">
            <p>GMA X3500</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Чипсет</p>
          </td>
            <td width="8.84%">
            <p>946GZ</p>
            </td>
            <td width="7.34%">
            <p>Q963</p>
            </td>
            <td width="7.36%">
            <p>Q965</p>
            </td>
            <td width="14.88%">
            <p>G31, Q33, Q35</p>
            </td>
            <td width="6.5%">
            <p>G33</p>
            </td>
            <td width="9.44%">
            <p>G965</p>
            </td>
            <td width="12%">
            <p>GM965, GL960</p>
            </td>
            <td width="16.68%">
            <p>G35</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Тактовая частота (МГц)</p>
          </td>
            <td width="8.84%">
            <p>667/400</p>
            </td>
            <td width="7.34%">
            <p>667</p>
            </td>
            <td width="7.36%">
            <p>667</p>
            </td>
            <td width="14.88%">
            <p>&nbsp;</p>
            </td>
            <td width="6.5%">
            <p>400</p>
            </td>
            <td width="9.44%">
            <p>667</p>
            </td>
            <td width="12%">
            <p>&nbsp;</p>
            </td>
            <td width="16.68%">
            <p>&nbsp;</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Модель вершинных шейдеров</p>
          </td>
            <td width="54.36%" colspan="6">
            <p>3.0</p>
            </td>
            <td width="28.68%" colspan="2">
            <p>4.0</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Модель пиксельных шейдеров</p>
          </td>
            <td width="23.54%" colspan="3">
            <p>2.0</p>
            </td>
            <td width="30.82%" colspan="3">
            <p>3.0</p>
            </td>
            <td width="28.68%" colspan="2">
            <p>4.0</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Пиксельные конвейеры</p>
          </td>
            <td width="23.54%" colspan="3">
            <p>Н/Д</p>
            </td>
            <td width="21.38%" colspan="2">
            <p>4</p>
            </td>
            <td width="38.12%" colspan="3">
            <p>Н/Д</p>
          </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Унифицированные шейдерные  процессоры</p>
          </td>
            <td width="44.92%" colspan="5">
            <p>Н/Д</p>
          </td>
            <td width="21.44%" colspan="2">
            <p>8</p>
            </td>
            <td width="16.68%">
            <p>8</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Аппаратные вертексные  шейдеры</p>
          </td>
            <td width="23.54%" colspan="3">
            <p>Официально не  поддерживается</p>
          </td>
            <td width="21.38%" colspan="2">
            <p>Нет</p>
            </td>
            <td width="38.12%" colspan="3">
            <p>Да</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Пиковая пропускная  способность шины памяти (ГБ/с)</p>
          </td>
            <td width="8.84%">
            <p>10.7</p>
            </td>
            <td width="14.7%" colspan="2">
            <p>12.8</p>
            </td>
            <td width="14.88%">
            <p>&nbsp;</p>
            </td>
            <td width="6.5%">
            <p>17.1</p>
            </td>
            <td width="21.44%" colspan="2">
            <p>12.8</p>
            </td>
            <td width="16.68%">
            <p>&nbsp;</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Максимальный объем  видеопамяти (МБ)</p>
          </td>
            <td width="44.92%" colspan="5">
            <p>256</p>
            </td>
            <td width="38.12%" colspan="3">
            <p>384</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Поддержка OpenGL</p>
          </td>
            <td width="44.92%" colspan="5">
            <p>1.4</p>
            </td>
            <td width="21.44%" colspan="2">
            <p>1.5</p>
            </td>
            <td width="16.68%">
            <p>2</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Поддержка DirectX</p>
          </td>
            <td width="54.36%" colspan="6">
            <p>9</p>
            </td>
            <td width="28.68%" colspan="2">
            <p>10</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Аппаратное ускорение MPEG-2</p>
          </td>
            <td width="44.92%" colspan="5">
            <p>Компенсация движения (MC)</p>
          </td>
            <td width="38.12%" colspan="3">
            <p>VLD + iDCT + MC</p>
            </td>
        </tr>
        <tr>
            <td width="16.96%">
            <p>Аппаратное ускорение VC-1</p>
          </td>
            <td width="44.92%" colspan="5">
            <p>Нет</p>
            </td>
            <td width="21.44%" colspan="2">
            <p>MC (только для WMV9)</p>
          </td>
            <td width="16.68%">
            <p>MC + In loop фильтр</p>
          </td>
        </tr>
    </tbody>
</table>
<br />
<p><strong>Таблица 1. Характеристики чипсетов  серии Intel® GMA X3x00</strong></p>
<br />
<p>Intel X3000 представляет собой  значительно более мощное графическое ядро по сравнению с разработками Intel предыдущих  поколений. В дискретных графических ускорителях графическая подсистема  преимущественно работает через шину PCI  Express. В случае с Intel X3000, графическая подсистема периодически  использует ресурсы ЦП как дополнение к собственному графическому процессору  (через контроллер-концентратор графической подсистемы и памяти (GMCH, Graphics and Memory Controller Hub ), системную память и интегрированное в чипсет графическое ядро). В  графических ускорителях серии 3x00 ресурсы ЦП задействуются для первого этапа обработки трехмерных сцен  (геометрические расчеты), в то время как остальные 3D расчеты выполняются  чипсетом, тем самым снижая нагрузку на ЦП. Учитывая, что системная память  используется совместно для системных и графических задач, интегрированная  графика Intel X3000 позволяет добиться  оптимального соотношения цены и производительности.</p>
<br />
<p>Ядро Intel X3000 (G/GM965) включает восемь унифицированных шейдерных  процессоров, работающих на частоте 667 МГц, по сравнению с четырьмя пиксельными  конвейерами (с частотой 400 МГц) в предшествующих моделях Intel® G945 и Intel® GM945. Как и предшествующие модели, Intel X3000 использует архитектуру разделяемой памяти. Учитывая, что память  разделяется между графическими и другими системными приложениями, важнейшим  фактором качества и производительности встроенной графики является пропускная  способность шины памяти. В обзоре, опубликованном на сайте <a href="http://www.hardwarezone.com/articles/view.php?id=2058&amp;cid=6">Hardware Zone</a>, говорится, что «работая  на высокой тактовой частоте 667 МГц, X3000 включает и поддерживает аппаратные блоки  расчета трансформаций и освещения (T&amp;L), вершинные шейдеры 3.0, пиксельные шейдеры 3.0,  шейдерную модель 3.0 (SM 3.0), расширенный динамический диапазон (HDR), а также полнофункциональные 32-битные вычисления  с плавающей запятой для обсчета графических эффектов – и все это в рамках  графического ядра».</p><br />

<p class="sectionHeading">Мифы об интегрированной графике Intel®</p>
<p>В течение нескольких лет корпорация Intel предлагает  графические решения, отличающиеся привлекательной стоимостью. В первую очередь  эти решения ориентированы на индивидуальных потребителей и  бизнес-пользователей, главным соображением для которых является цена. С  появлением графических ускорителей Intel  X3000, корпорация Intel намеревается  удовлетворить потребности большинства массовых пользователей. Эти пользователи  приобретают значительное количество программных продуктов и рассчитывают  получить достаточную производительность в компьютерных играх на протяжении  всего срока службы системы. Корпорация Intel заинтересована в разработке аппаратных  решений, которые предоставляют дополнительные преимущества и достаточную производительность  для этой категории покупателей. В данном разделе мы хотели бы рассмотреть  наиболее распространенные заблуждения об интегрированной графике Intel.</p>
<br />
<p><strong>Миф №1: На интегрированной графике </strong><strong>Intel невозможно играть в  трехмерные игры</strong> </p>
<p>Используя интегрированные графические решения Intel предшествующих  поколений, некоторые пользователи полагают, что на ускорителях Intel будет проблематично  запустить современные трехмерные игры. Графическое ядро Intel X3000 представляет собой интегрированное решение,  возможности которого позволяют запускать многие  популярные игры, обеспечивая приемлемую  частоту кадров. В качестве примеров можно привести:</p>
<br />

<ul>
    <li>Age of Empires 3: War Chiefs Expansion* (Ensemble/Microsoft), 27 FPS </li>
    <li>F.E.A.R *(Vivendi), 47 FPS </li>
    <li>Dungeons &amp; Dragons Online* (Turbine/Atari), 54 FPS </li>
    <li>Star Wars: Empire at War*(Lucas Arts), 32 FPS </li>
    <li>World of Warcraft*(Blizzard/Vivendi), 29 FPS </li>
</ul>
<br />

<p>Не подвергая сомнению тот факт, что для полной реализации потенциала  самых требовательных и современных игр потребуется отдельная видеокарта, аналитики  по потребительскому рынку сходятся во мнении, что графические чипсеты серии Intel X3000 показывают приемлемую производительность в большинстве  компьютерных игр.</p><br />

<p><strong>Миф №2: Intel занимает лишь небольшой  сегмент рынка графических ускорителей</strong> </p>
<p>По оценкам компании Mercury Research, в сегменте настольных компьютеров корпорация Intel уверенно занимает  большую часть рынка встроенных графических решений. В 2006 году корпорации Intel принадлежала  наибольшая доля рынка интегрированной графики (около 50%), что более чем в два  раза превышало рыночную долю ближайшего конкурента. На Рисунке 1 показаны  тенденции развития рынка настольных графических ускорителей с поддержкой 3D, в количественном  выражении, на период до 2011 года. (Источник: IDC, Mercury  Research PC Graphics Report, John Peddie.)</p><br />

<table cellspacing="0" cellpadding="5" width="580" class="tableformat1">
    <tbody>
        <tr>
            <td>
            <p>Графические решения для  настольных систем (тыс. шт.)*</p>
          </td>
            <td>
            <p>2006</p>
            </td>
            <td>
            <p>2007</p>
            </td>
            <td>
            <p>2008</p>
            </td>
            <td>
            <p>2009</p>
            </td>
            <td>
            <p>2010</p>
            </td>
            <td>
            <p>2011</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>Дискретные</p>
          </td>
            <td>
            <p>83,500</p>
            </td>
            <td>
            <p>75,117</p>
            </td>
            <td>
            <p>67,580</p>
            </td>
            <td>
            <p>64,459</p>
            </td>
            <td>
            <p>65,377</p>
            </td>
            <td>
            <p>66,873</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>Интегрированные</p>
          </td>
            <td>
            <p>137,351</p>
            </td>
            <td>
            <p>122,833</p>
            </td>
            <td>
            <p>112,078</p>
            </td>
            <td>
            <p>107,892</p>
            </td>
            <td>
            <p>108,961</p>
            </td>
            <td>
            <p>110,981</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>Всего для настольных систем</p>
          </td>
            <td>
            <p>220,851</p>
            </td>
            <td>
            <p>197,950</p>
            </td>
            <td>
            <p>179,658</p>
            </td>
            <td>
            <p>172,351</p>
            </td>
            <td>
            <p>174,338</p>
            </td>
            <td>
            <p>177,854</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>&nbsp;</p>
            </td>
            <td>
            <p>&nbsp;</p>
            </td>
            <td>
            <p>&nbsp;</p>
            </td>
            <td>
            <p>&nbsp;</p>
            </td>
            <td>
            <p>&nbsp;</p>
            </td>
            <td>
            <p>&nbsp;</p>
            </td>
            <td>
            <p>&nbsp;</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>Графические решения для  мобильных систем (тыс. шт.)*</p>
          </td>
            <td>
            <p>2006</p>
            </td>
            <td>
            <p>2007</p>
            </td>
            <td>
            <p>2008</p>
            </td>
            <td>
            <p>2009</p>
            </td>
            <td>
            <p>2010</p>
            </td>
            <td>
            <p>2011</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>Дискретные</p>
          </td>
            <td>
            <p>19,942</p>
            </td>
            <td>
            <p>25,108</p>
            </td>
            <td>
            <p>30,547</p>
            </td>
            <td>
            <p>33,555</p>
            </td>
            <td>
            <p>38,185</p>
            </td>
            <td>
            <p>40,919</p>
            </td>
        </tr>
        <tr>
            <td>
            <p>Интегрированные</p>
          </td>
            <td>
            <p>59,826</p>
            </td>
            <td>
            <p>75,324</p>
            </td>
            <td>
            <p>91,641</p>
            </td>
            <td>
            <p>112,336</p>
            </td>
            <td>
            <p>135,382</p>
            </td>
            <td>
            <p>163,676</p>
            </td>
        </tr>
        <tr>
            <td>
            <p><br />
            <img height="171" alt="" width="194" src="http://software.intel.com/file/9157" /><br />
            Всего для мобильных систем</p>
          </td>
          <td>
            <p>79,768</p>
            </td>
            <td>
            <p>100,433</p>
            </td>
            <td>
            <p>122,188</p>
            </td>
            <td>
            <p>145,891</p>
            </td>
            <td>
            <p>173,567</p>
            </td>
            <td>
            <p>204,595</p>
            </td>
        </tr>
    </tbody>
</table><br />

<p><strong>Таблица 2. Рыночная доля Intel и ожидаемый рост  сегмента интегрированной графики</strong> </p><br />

<p><img height="266" alt="" width="575" src="http://software.intel.com/file/9158" /> </p>
<p><strong>Рисунок 1. Рыночная доля Intel и ожидаемый рост  сегмента интегрированной графики</strong></p><br />

<p>В Таблице 2 и на Рисунке 1 показана рыночная доля Intel по сравнению с  другими компаниями и ожидаемый рост рынка интегрированной графики в ближайшие  годы. Раньше разработчики, приоритетом для которых была производительность  графики, вполне обоснованно полагали, что интегрированные графические решения  не обладают достаточной функциональностью для того, чтобы поддерживать  разработку игр для массовых пользователей. Тем не менее, благодаря поддержке  шейдерной модели 3.0 в ускорителях Intel  X3000 появились функции,  открывающие богатые графические возможности. Естественно, никто не возьмется  утверждать, что самые требовательные энтузиасты компьютерных игр в ближайшее  время начнут отказываться от дискретных графических решений, однако намечается  тенденция к тому, что интегрированные решения Intel смогут в большей степени удовлетворить  потребности пользователей систем бюджетного и среднего уровня. Intel продолжает увеличивать  свою долю рынка в сегменте настольных компьютеров. Таким образом, поддержка  графических решений Intel X3000 обеспечит  дополнительный источник доходов за счет расширения доступной аудитории, которая  получит богатые визуальные впечатления от использования вашего программного  продукта.</p><br />

<p><strong>Миф №3: Интегрированная графика Intel слишком медленно выполняет  операции Т&amp;L </strong></p>
<p>Transform and Lighting, или T&amp;L – это технология аппаратного  расчета эффектов трансформации и освещения. Разработчики приложений часто убеждены,  что необходимым условием для достижения определенного уровня производительности  является выполнение расчетов трансформации и освещения дискретным графическим  ускорителем. Однако драйверы графических ускорителей Intel X3000 позволяют оптимальным образом выполнять операции  T&amp;L либо аппаратными, либо программными средствами, в зависимости от того,  какие задачи отведены для графического или центрального процессора, при этом  обеспечивая хороший уровень производительности. Используя GPU или CPU для T&amp;L операций в зависимости от конкретных запросов,  вычислительная среда X3000 поддерживает оптимальный баланс графической нагрузки. </p>
<p>На самом деле, падение производительности в расчетах T&amp;L обычно не является истинной причиной медленной работы игрового  приложения. В большинстве случаев «узкие места» связаны с пиксельными операциями.  Если падение производительности связано с T&amp;L, скорее всего, это объясняется  существенными недостатками в архитектуре игрового приложения. Чтобы определить  суть проблемы и выяснить причину падения производительности, рекомендуется  воспользоваться средством Intel® VTune ™ Performance Analyzer. </p>
<p>Приведенный на Рис. 2 пример свидетельствует о том, что графические  решения Intel  продолжают совершенствоваться по сравнению с продуктами конкурентов.</p><br />

<p><img height="350" alt="General Graphics Performance" width="500" src="http://software.intel.com/file/9159" /> </p>
<p><strong>Рисунок 2. Сравнение производительности интегрированной  графики Intel</strong> </p><br />

<p><em>Источник: Anandtech (http://www.anandtech.com/cpuchipsets/showdoc.aspx?i=2942&amp;p=4)</em></p><br />

<p><strong>Миф №4: Видеодрайверы Intel имеют множество  недостатков</strong> </p>
<p>Действительно, графические драйверы Intel в прошлом имели определенные  недостатки. Однако разработчики драйверов приложили все усилия к исправлению  существующих проблем и предусмотрели специальную процедуру выявления и  устранения неполадок в приоритетном  порядке.  В группе Intel® Software Solutions Group за устранение неполадок отвечают специально  назначенные инженеры, а независимые поставщики программного обеспечения могут  сообщать о неполадках своим менеджерам по связям с Intel. Располагая  крупнейшей на сегодняшний день общей долей рынка и лучшей профессиональной  командой разработчиков, Intel надеется, что уже через пару лет видеодрайверы Intel станут «золотым  стандартом» для всей отрасли. Чтобы добиться столь высокого уровня, сообществу  разработчиков графических продуктов, независимым поставщикам ПО и любителям  компьютерных игр следует сообщать специалистам Intel обо всех обнаруженных ошибках в драйверах. Для  этого рекомендуется придерживаться следующей процедуры:</p>
<ul>
    <li>Загрузите последнюю версию драйвера Intel. </li>
    <li>Убедитесь, что ошибка воспроизводится только на графическом чипсете Intel X3000, проведя тесты на продуктах других производителей. </li>
    <li>Составьте подробное описание  проблемы, приложив снимки экрана/записи. </li>
    <li>Создайте воспроизводимый тестовый  файл ошибки (например, формата .PIXRun). </li>
    <li>Вы можете передать       ваши материалы менеджеру по связям с Intel Corporation       в вашей компании, а при его отсутствии - вашему издателю. Как       правило, им является то же контактное лицо, к которому вы обращаетесь за информацией       о процессорах и оптимизации. </li>
    <li>В качестве альтернативного варианта  разработчики могут воспользоваться нашим форумом, расположенным по адресу <a href="http://softwarecommunity-rus.intel.com/isn/Community/ru-ru/Forums/">http://softwarecommunity-rus.intel.com/isn/Community/ru-ru/Forums/</a> - <em>Графика</em>. </li>
</ul>
<br />
<p class="sectionHeading">Оптимизация приложений под графические чипсеты Intel® X3000</p>
<p>Чтобы оптимизировать ваше приложение для использования с Intel X3000 и добиться наилучшей производительности и  функциональности, следуйте  приведенным ниже  рекомендациям: </p>
<ul>
    <li>Используйте Intel® VTune™ Performance Analyzer для получения данных о  производительности как на системном уровне, так и на уровне исходного кода  приложения. Это поможет вам провести оптимизацию приложения для различных  платформ, операционных систем, и последних моделей процессоров Intel. Этот инструмент поможет определить время,  затрачиваемое на вычисления графическим драйвером и непосредственно  приложением. Кроме того, он позволяет вам с легкостью установить «10 главных  кандидатов» на оптимизацию. </li>
        <ul>
            <li>Загрузите последнюю версию комплекта для разработчиков Microsoft DirectX 9 SDK и соответствующие файлы Symbols. </li>
            <li>Установите        ассоциацию файлов символов в Intel® VTune™ Performance Analyzer. </li>
            <li>Убедитесь,        что файл символов соотнесен с двоичным файлом для Microsoft DirectX и исполняемым файлом игры. </li>
    	</ul>
        <li>Используйте средство Microsoft PIX, чтобы выявить       «узкие места» в вашем приложении и определить время, затрачиваемое на       обработку в прикладном программном интерфейсе DirectX. В комплекте       со многими графическими компонентами Intel поставляется плагин PIX для мониторинга       графической производительности самого чипсета и драйвера чипсета. </li>
</ul>
<br />
<p class="sectionHeading">Заключение</p>
<p>Теперь, когда вы  осведомлены о многих фактах, касающихся семейства продуктов Intel X3000 – и знаете, что они являются лидирующим решением на рынке и  способны обеспечить достойное качество графики и впечатляющую  производительность в популярных играх – вы сможете объяснить коллегам, что  выбор графических решений Intel X3000 в  качестве целевой платформы для ваших приложений позволит вам расширить  пользовательскую аудиторию. Узнайте больше о графике Intel, прочитав  руководство <a href="http://www3.intel.com/cd/ids/developer/asmo-na/eng/popular/334680.htm">GMA X3000 Development Guide</a>.</p>
<p>Надеемся, что в этой статье нам удалось развеять некоторые  бытующие среди разработчиков графических приложений заблуждения , касающиеся роли  Intel на  рынке графических ускорителей и возможностей предлагаемых корпорацией  технологий. Графические ускорители Intel  X3000, представители  последнего поколения интегрированной графики Intel, демонстрируют значительный  прирост  производительности и  функциональности. Уникальность решений Intel по сравнению с конкурирующими архитектурами  заключается в том, что они не просто предоставляют определенный набор  возможностей, а обеспечивают целостный баланс между всеми компонентами  платформы. Чипсеты Intel X3000 завоевывают все  большую долю рынка графических ускорителей, а благодаря последним достижениям корпорации,  интегрированные графические ускорители Intel теперь являются одними из самых продаваемых в  мире. В результате пользователи ПК среднего уровня получают высококачественный  продукт по доступной цене. Благодаря тому, что Intel занимает лидирующие позиции на рынке интегрированных  графических решений, независимые поставщики программного обеспечения получают  отличный стимул для того, чтобы добавить поддержку новых продуктов Intel в приложения,  ориентированные на массового пользователя. </p><br />

<p class="sectionHeading">Дополнительные ресурсы</p>
<p>Чтобы помочь вам развенчать  мифы о чипсетах Intel X3000 и расширить ваши знания по данной теме, советуем  ознакомиться с руководством <a href="http://www.intel.com/cd/ids/developer/asmo-na/eng/popular/334680.htm">Intel GMA X3000 Development Guide</a>.</p>
<ul>
    <li>Сравнительная таблица чипсетов  Intel: <a href="http://intel.com/design/chipsets/linecard.htm">http://intel.com/design/chipsets/linecard.htm</a>. </li>
    <li>Подробная информация о  графическом чипсете Intel X3000: <a href="http://www.intel.com/cd/products/services/emea/eng/150529.htm">http://www.intel.com/cd/products/services/emea/eng/150529.htm</a>. </li>
</ul>
<br />
<p class="sectionHeading">Об авторе</p>
<p>Чак ДеСильва работает в Intel Software Solutions Group на должности Менеджера по разработке программных  приложений. Он и его отдел отвечают за оптимизацию производительности  современного потребительского программного обеспечения на настольных системах Intel. До перехода на эту должность Чак ДеСильва  занимался разработкой драйверов в Intel Corporation. В  частности, он принимал участие в разработке/внедрении первых драйверов  устройств для USB, AGP (GART) и первых графических чипов Intel (i740/810(e)).</p>
</div> ]]></description>
      <link>http://software.intel.com/ru-ru/articles/common-misconceptions-of-intel-integrated-graphics</link>
      <pubDate>Tue, 03 Jun 2008 20:34:00 -0700</pubDate>
      <comments>http://software.intel.com/ru-ru/articles/common-misconceptions-of-intel-integrated-graphics#comments</comments>
      <guid isPermaLink="true">http://software.intel.com/ru-ru/articles/common-misconceptions-of-intel-integrated-graphics</guid>
      <category>Сообщество разработчиков графических приложений</category>
    </item>
  </channel></rss>