Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Ваш игровой движок сейчас может похвастаться шейдерами, мешами , движением, GUI и всей инициализацией, требуемой для быстрого рендеринга Stage3D. Самое время для перехода на следующий уровень и эксперимента с продвинутыми текстурными эффектами. Пока всё идёт хорошо. Мы достигли многого в нашем квесте по созданию 3D видеоигры во Flash. Теперь, позаботившись об основах, мы можем сосредоточиться на вещах, которые действительно выглядят хорошо. От блестящих эффектов, таких как металлическое оружие, до эффектов прозрачности, таким как пар, дым или взрывы, Stage3D API может рендерить текстуры всех видов, различными способами. В этой главе мы начнём изучать, как обрабатывать bitmap-данные, как преобразовывать текстуры в специализированные форматы, которые полезны для эффектов, а также существенно эффективнее на ограниченных аппаратных средствах. В этой главе мы изучим :
Orion45
08.05.13 в 22:21
|
|
Использование множества текстур и нескольких мешей; Рендеринг текстур со специальными режимами перехода прозрачности; Рендеринг спецэффектов, таких как взрывы. Меняются ли задние грани меша, которые отсекаются; Учёт z-буфера при рендеринге; Обнаружение нажатий клавиш, для пользовательского контроля действий.
Orion45
08.05.13 в 22:28
|
|
Время для проекта: создаём «настоящую» игру. Мы двигаемся дальше, от простой технической демки к настоящей игре. Теперь, когда мы отважились погрузиться в глубины Molehil, это хороший момент для вас начать мозговой штурм какого вида игру вы хотите сделать с помощью Stage3D API. У вас, вероятно, осталось что-нибудь в памяти с самого начала, но если нет, сейчас, чтобы иметь свет в конце туннеля, вы также можете придумать план.
Orion45
08.05.13 в 22:43
|
|
Важная задача данного этапа – сделать вашу первую 3D игру настолько простой, насколько это возможно. Любой разработчик-ветеран знает, что даже вещи, которые кажутся простыми, могут оказаться гораздо более сложными, чем ожидалось. Помня об этом, выберете жанр игры, который, как вам кажется, потребует минимум работы; что-нибудь в аркадном стиле, упрошённое и лёгкое в создании. Ваши будущие игры могут с каждым разом расти в размерах и сложности, так что пока начнём с визуализации наиболее базовой игры, которую вы захотите сделать.
Orion45
08.05.13 в 22:44
|
|
На этом этапе успех определяется просто завершением вашей игры, которую вы сможете показать вашим друзьям. Будет наивно пытаться написать многопользовательскую ролевую онлайн игру (MMORPG), например. Однажды вы достигнете этапа, имея завершённую, играбельную 3D игру за поясом и сможете быстро и просто перейти к улучшенным играм. Простой с виду пример игры, который будет создан в оставшейся части этой книги, это аркадный шутер. Он был вдохновлён “Galaxian 1942”, “R-Type”, “Giga Wing”, “Ikaruga”, «Тигр Хели Рейдн», «Геометрические Войны» и даже «Космические захватчики». Многие люди называют эту разновидность игр играми «bullet hell».
Orion45
08.05.13 в 22:49
|
|
Аркада "перестреляй их всех" (SHMUP - shoot-em-up) идеально подходит для наших будущих экспериментов. Кроме того для неё не требуется сложных технических решений, таких как физический движок, продвинутый искусственный интеллект или работа по сети. Зато для подобных игр характерно много действия, куча взрывов, и изобилие приятных глазу вещей. Начиная с текущего момента, в процессе создания учебного проекта Stage3D, который мы будем обновлять от главы к главе, выберите текстуры и сетки (полигональные сетки), которые вы хотите поместить в свою игру. Использование текстур в Stage3D Самым простым способом использования текстуры является следующий: 1. Добавить изображение в SFW 2. Создать в коде объект Texture 3. Загрузить текстуру в оперативную видео память (VRAM) 4. Сгенерировать миникарты и так же их загрузить 5. Создать программу вершин на AGAL, которая использует координаты текстуры 6. Создать программу фрагментов на AGAL, которая использует саму текстуру 7. Научить Flash использовать эту текстуру при рендринге
MuChan
09.05.13 в 08:11
|
|
Для того, чтобы поместить изображение во Flash вы будете либо используете flex-команду [embed], либо добавите его в вашу библиотеку в Flash IDE. Затем вы создаёте объект Texture путём создания экземпляра нового класса этого типа функцией context3D.createTexture(). Для того, чтобы отправить bitmap-данные изображения в вашу видеократу для использования во врем я рендеринга, вы должны загрузить его и, желательно, создать mip-уровни (его маленькие версии, используемые для перспективной коррекции) и загружаете их тоже, используя вашу функцию Texture.uploadFromBitmapData().
Orion45
09.05.13 в 13:56
|
|
Теперь вы должны скомпилировать AGAL программы, которые используют эти данные. В вашей фрагментной программе вы используете команду подобную “tex ft0, v1, fs0<2d,linear, repeat,miplinear>” чтобы сделать выборку текстуры для достижения надлежащего цвета. Наконец, в вашем цикле рендеринга вы используете функцию context3D.setTextureAt(), чтобы выбрать эту текстуру первой в рендеринге ваших мешей функцией context3D.drawTriangles().
Orion45
09.05.13 в 14:13
|
|
Кратность двойке. В предыдущих главах мы дали толкование использования текстур и дали как можно более простое объяснение как это делается. Также мы использовали только отдельные текстуры в нашем демо, и они всегда были размером 512 х 512. Почему мы выбрали этот странно звучащий размер для нашего изображения? Хотя не все видеокарты требуют, чтобы текстуры были не больше определённого размера, математика, участвующая при рендеринге текстур в 3D, работает быстрее, когда вы используете текстуры определённых размеров. На некоторых машинах текстуры даже не будут работать, если они не в определённом диапазоне размеров. Поэтому необходимо, чтобы все текстуры, которые вы используете в вашей игре, имели размер кратный двойке.
Orion45
09.05.13 в 14:21
|
|
Что это значит? Это значит, что текстуры должны иметь ширину и высоту, которая укладывается в эти значения: 2, 4, 16, 32, 64, 128, 256, 512, 1024 и т.д. Кроме того, во многих случаях ваши текстуры лучше должны быть квадратными (т.е. высота должна быть равна ширине), чем прямоугольными. Иногда вы можете выбрать текстуру и 64 х 256, но в основном, вы вынуждены использовать квадратные, кратные степени двух текстуры, такие как изображения размером 256 х 256 пикселей. Чем больше ваши текстуры, тем больше видеопамяти они будут занимать, и на определённом железе они, соответственно, будут рендериться немного медленнее. Поэтому всегда будет мудрым выбором использовать текстуры, которые будут большими ровно настолько, чтобы выглядеть хорошо.
Orion45
09.05.13 в 14:39
|
|
Тогда, создавая, например, игральные кости, если вы знаете, что они не будут занимать весь экран, будет очень глупо использовать гигантские 1024х1024 текстуры для них. Крошечные объекты в вашем мире, такие как эти, будут выглядеть также точно с размером текстур 64х64 или 128х128. Важные объекты и текстуры, используемые для стен и пола, которые можно рассматривать с близкого расстояния, идеальные кандидаты для больших текстур; 256х256 или 512х512 являются нормой. Не будет ошибкой использовать малое количество по-настоящему больших текстур, но как и все вещи в программировании игр, это будет компактнее и быстрее запускаться. Если каждая текстура, используемая вашей игрой, 1024х1024, ваш SWF-файл потребует действительно много времени на загрузку и может даже не загрузить текстуры в RAM.
Orion45
09.05.13 в 14:43
|
|
Поэтому, создавая текстуры, работайте в высоком разрешении (4096х4096), но затем сохраняйте их как 128х128 для использования в вашей игре. Во время тестирования, если вы обнаружили, что требуемая текстура выглядит размыто, попробуйте 26х256 или 512х512. Так как источник изображения сохранён в формате высокой чёткости, у вас есть дополнительные пиксели для работы и тогда вы измените размер ваших картинок так, чтобы конечное изображение не было размыто. Всегда благоразумно работать в высоком разрешении , но экспортировать в низкое разрешение и повышать точность только когда вы заметили, что это необходимо. Это поможет сохранить ваши файлы крошечными и запускаться вашей игре сглаженной.
Orion45
09.05.13 в 14:45
|
|
Распространенная ошибка – включать текстуры больше, чем требуется: разумеется, вы хотите, чтобы ваша игра, выглядела так хорошо, как только возможно. Поэтому, хорошая метрика, которая поможет вам избежать этого, это оценить максимальное количество реального места вашего внутриигрового экрана, которое ваш меш будет использовать. Если требуемая текстура предназначена, чтобы покрыть крошечный внутриигровой объект, такой как скрепка или выключатель, тогда никогда не нужно брать более чем 50 пикселей на покрытие, нет причин использовать текстуру, которая имеет размер 1024х1024; 64х64 в этом примере хватит.
Orion45
09.05.13 в 14:48
|
|
UV-координаты. Как вы знаете, текстуры – это картинки, которые оборачиваются вокруг 3D-меша подобно обёрточной бумаге подарка на день рождения. Как она оборачивается, контролируется UV-координатами, которые загружаются как вершинный буфер рядом с x, y, z-координатами для каждой вершины. UV-координаты для любой данной вершины определяются двумя числами (u и v) и обычно в диапазоне от 0 до 1. Координата U – горизонтальная ось в текстуре, а V представляет вертикальную ось. Поэтому нижняя часть текстуры имеет V равные 1 и правый нижний угол будет иметь U равное 1.
Orion45
09.05.13 в 14:52
|
|
Например, при простом повороте квадратного меша, мы использовали в первых нескольких главах верхний левый угол квадрата (первую вершину), имевший UV-координату, определённую как 0, 0. Это значит, что пиксели, которые рисуются на экране вашим фрагментным шейдером, приходят из левого верхнего угла вашего текстурного изображения. Нижний правый угол этой битмап-картинки будет доступен при получении вершины с UV-координатами 1, 1.
Orion45
09.05.13 в 15:05
|
|
Вы можете использовать числа выше, чем 1. Например, если вы хотите повторить текстуру 16 раз по горизонтали вдоль поверхности полигона, вы можете получить UV-координаты вершины (16, 1), так что в такой особенной вершине текстура наложится 16 раз в U и раз на оси V. Вы также можете использовать числа, которые меньше, чем 1. Например, если вы начнёте с 0.25, тогда вы пройдёте четверть пути вдоль текстуры. Это происходит во многих мешах, когда вы хотите поверхность только с небольшой частью общей текстуры.
Orion45
09.05.13 в 15:06
|
|
Прозрачные текстуры. Вы не должны использовать .jpg картинки в качестве вашего источника изображений. Вы можете использовать .png-файл, выполненный с различной прозрачностью. Это может быть действительно великолепно для таких эффектов как взрывы, искры и дым, а также прозрачных окон. Кроме того, вы можете симулировать сложную геометрию (таких как изгородь, решётка или листья и ветви дерева) , рисуя сложные формы на вашей текстуре, но используя простой четырёхугольник (квадратный полигон).
Orion45
09.05.13 в 15:08
|
|
Предыдущая текстура полностью прозрачная в областях, не покрытых зелёным листком. Это .png-файл, который сохранён со включённой альфа-информацией (информацией о прозрачности). Вместо моделирования мегасложного дерева, где каждый лист включает сотни полигонов, вы можете симулировать сложную геометрию используя текстуру, такую как этот простой квадрат. Группы этих простых «спрайтов-рекламных щитов» могут быть использованы во множестве эффектов, давая впечатление сцены с миллионами полигонов, где на самом деле используется только несколько дюжин.
Orion45
09.05.13 в 15:10
|
|
Анимация UV-координат в шейдерах. Одна из полезных технологий, которая используется во множестве игр – это прокрутка или колебание текстурных UV-координат меша на основе времени. Например, вы можете наложить текстуру, которая выглядит похожей на воду, на полоску полигонов в форме реки и затем, вместо настоящего движения полигонов, просто немного увеличивайте UV-координаты в каждом кадре.
Orion45
09.05.13 в 15:11
|
|
Для того, чтобы сделать это, вы должны будете написать короткую AGAL вершинную программу, которая утверждает вершинные константы, которые вы установите для каждого кадра. Перед выводом UV-координат вы должны будете использовать опкод ADD, чтобы сместить их в одном или обоих измерениях, так что каждый кадр часть текстуры, которая назначается вашей фрагментной программе берётся из различных частей вашей текстуры. В этом примере с текущей водой, всё, что мы должны будем сделать – это добавить небольшой код в наш цикл рендеринга. Во-первых, мы увеличиваем переменную немного в каждом кадре и отправляем это значение в вершинную программу с помощью метода setProgramConstantsFromVector(). Например, предположим, что во время инициализации вы создали объект Vector со списком чисел, вызвавший uvOffsets, во время вашего цикла рендеринга, вы могли сделать что-нибудь подобное, прокручивая текстуру по горизонтали понемногу в каждом кадре.
Orion45
09.05.13 в 15:14
|
|
Время для действий: Обновляем UV-координаты каждый кадр. //увеличиваем первое число в нашем списке //каждая фрагментная программа добавит в UV-координаты uvOffsets[0] +=0.01; //отправляем этот вектор в AGAL переменную vc4 context3D.setProgramConstantsFromVector ( Context3DProgramType.VERTEX, 4, uvOffsets, true); Затем, в вашей вершинной программе AGAL вы добавите этот вектор к сохранённым UV-координатам, которые загружаются вместе с вашим мешем. Допустим, что они сохранены в AGAL регистре va1 и посылаются в вашей фрагментной программе в v1, мы сначала добавим значение, которое мы установили ранее (в vc4) к тем координатам по умолчанию, так что v1 теперь содержит новые координаты. add v1, va1, vc4
Orion45
09.05.13 в 15:15
|
|
Что же произойдет? В каждом кадре, сразу перед тем как мы отрендерим наш меш, мы обновляем значение, которое было отправлено в Stage3D для использования в нашей нашей вершинной программе как vc4. Это значение добавляется к существующим UV-данным нашего меша, так что для каждого кадра U (горизонтальная) координата сдвигается немного в сторону. Эта техника может быть использована для сдвига текстур на постоянную величину, таких как когда прокручиваются текстуры подобные воде понемногу в каждом кадре или когда анимируются текстуры или используются карты текстур, чтобы выбрать тот «кадр» (или часть текстур) который мы хотим использовать.
Orion45
09.05.13 в 15:17
|
|
Карты текстур.
Замечательная технология, чтобы увеличить вашу игровую частоту кадров и позволить большему числу мешей быть отренедеренными, используя сам шейдер это упаковывать различные текстуры в большой битмап, называемый текстурным атласом. Например, представьте, что вам нужно 16 различных видов драгоценных камней для сокровищ как игровых элементов в вашей игре. Вместо создания 16 крошечных текстур вы можете, используя Photoshop или любой другой графический редактор, упаковать их в одну большую текстуру и затем моделировать различные 3D-меши таким способом, когда разные модели используют разные UV-координаты в самой текстуре. Это замечательно для частоты кадров, потому что вы можете группировать целые связки различных текстурных моделей в один гигантский вызов drawTriangles. Кроме того, есть небольшие накладные расходы каждый раз, когда вы сменяете текстуры или шейдеры во время рендеринга, и если вы можете избежать рендеринга большего числа мешей между вызовами context3D.setTextureAt(), вы можете сохранить время подобных результатов с лучшим fps.
Orion45
09.05.13 в 16:57
|
|
Использование атласов текстур, определённо, лучшая практика для рендеринга шрифтов в вашем 3D мире. Почти каждая игра, которая нуждается в рендеринге букв в 3D (когда не выходит просто наложить на вашу Stage3D) используются текстурные атласы битмап-шрифтов. Как вы можете видеть, предыдущие текстуры – это более эффективный способ текстурирования четырёхугольников для использования как текста внутри вашего 3D мира по сравнению с альтернативным, который создаёт и загружает сотню или более крошечных текстур, одна для каждой буквы. Так как медленнее переключить активные текстуры, чем использовать такую же текстуру для множества мешей, использование карт текстур, повысит производительность.
Orion45
09.05.13 в 17:07
|
|
Анимированные текстуры. Есть множество способов программировать анимированные текстуры и множество ситуаций, где это совершенный метод, чтобы достичь потрясающих эффектов. Вообразите, например, что вы хотите «спроектировать» потоковое видео или круто выглядящую анимацию на поверхности в вашей игре. Это может быть виртуальный кинотеатр или просмотр какого-нибудь футуристического видео на экране смартфона или другой спецэффект.
Orion45
09.05.13 в 17:09
|
|
Одним способом сделать это будет просто загрузить серию текстур и пройтись циклом по ним, основываясь на времени прохождения. Например, в вашем цикле рендеринга вы могли сменять текстуры, отправляя context3D.setTextureAt() каждые несколько кадров. Это удобно для небольших анимаций, таких как зацикленная водная рябь, экранная статика или даже для простых взрывов. Вы можете также создавать карты текстур, которые охватывают различные кадры видео, так что вся анимация сохранена на одной текстуре. Затем просто используйте технику UV-анимации выше, чтобы обновлять UV-координаты четырёхугольника с течением времени. В качестве примера возьмём эту текстуру:
Orion45
10.05.13 в 20:00
|
|
Используя текстуру подобно этой, вы будете сначала создавать простой квадратный меш (четыре вершины квадрата) с UV-координатами, которые покрывают весь квадрат только первый кадр анимации. Затем, используя пример AGAL выше, мы просто отправляем новое смещение в вызов SetProgramConstantsFromVector(), чтобы сдвинуть текстурные координаты на следующий кадр. В примере картинки выше каждый кадр - 1/13 смещения от каждого другого. Так, кадр 1 будет использовать U 0.0 , затем каждый следующий кадр будет увеличивать U-координату на 0.077.
Orion45
10.05.13 в 20:01
|
|
Манипуляция текстурными данными. Для анимированных текстур, которые получаются из видео или даже Flash анимации, может потребоваться слишком много видеопамяти, чтобы сохранить каждый кадр досрочно. В этом случае вы должны будете загружать пиксели каждый кадр путём копирования битмап-данных, которые вы хотите для вашей текстуры, и повторно вызывая uploadFromBitmapData() всякий раз, когда кадр изменился. На самом деле это плохо для FPS, особенно если вам нужно генерировать mip-уровни каждый кадр, так что лучше избежать этого, если только ваш проект абсолютно не нуждается в этом. Когда используется умеренно, эта технология открывает все разновидности возможностей для «динамических текстур».
Orion45
10.05.13 в 20:04
|
|
Так как вы можете загружать ваши текстуры сразу, как только захотите, бесконечное множество крутых эффектов становится доступным для вас. Например, вы можете сгенерировать динамические текстуры используя функции шума Перлина Flash, фрактальные и битмап-фильтры. В AS3 коде у вас под рукой есть всё, что может генерировать битмап-данные, которые могут быть использованы как источник пикселей для вашей текстуры. Вы можете не только копировать битмап-данные из каждого кадра FLV-видео, но также можете захватывать снимки с веб-камеры и помещать их в ваш 3D-мир! Возможности бесконечны.
Orion45
10.05.13 в 20:06
|
|
Установки рендеринга. Точно также текстуры могут быть установлены, чтобы рендериться различными способами, полигоны также следуют правилам по умолчанию, которые начинают нарушаться!Flash по умолчанию рендерит меши самым быстрым и наиболее эффективным из возможных способов. Это, как правило, то, что вам нужно, но, естественно, игра не будет классной, если она не содержит превосходных спецэффектов. Вы можете изменить «установки рендеринга» в Stage3D API, чтобы установить продвинутое ручное поведение, которое откроет бесконечное число возможностей для визуализации.
Orion45
11.05.13 в 22:05
|
|
Отбор поверхностей. Отбор поверхностей – это процесс в котором меши рендерятся только с одной стороны полигона, являющейся видимой. Это помогает ускорить визуализацию т.к., например, в кубе с непрозрачными сторонами вы никогда не сможете увидеть внутренние стенки. Когда отбор поверхностей включён, что является состоянием по умолчанию, эти внутренние поверхности (задние поверхности) никогда не рендерятся. Как правило, это работает великолепно, но есть случаи, когда вы хотите, чтобы обе стороны каждого полигона были отрисованы.
Orion45
11.05.13 в 22:07
|
|
Время для действий: рендеринг задних поверхностей меша. Например, если вы используете прозрачные текстуры на кубе, как в этом примере, вы, скорее всего, захотите увидеть внутренние стенки позади тех, что ближе к камере. Для того, чтобы сделать это, вы просто должны инструктировать Flash рендерить обе стороны меша следующим образом: //не выбираем поверхности: рисуем обе стороны //каждого полигона, включая задние стороны Conext3D.setCulling(Contex3DTriangleFace.NONE); Что же произойдёт?
Orion45
11.05.13 в 22:09
|
|
Мы инструктируем Stage3d API остановить отбор (пропустить рисование) задних поверхностей, какой бы меш мы не рендерили следующим. Это значит, что «внутренние» стороны будут рисоваться вместе с теми, которые кажутся «внешними». Различные параметры доступа для функции setCulling следующие: Contex3DTriangleFace.NONE (не отбираем ничего) Contex3DTriangleFace.BACK (по умолчанию, задние стенки отбираются) Contex3DTriangleFace.FRONT( противоположность нормальному поведению, передние стенки не будут отрисованы) Contex3DTriangleFace.BOTH (который бесполезен на практике, поскольку обе стороны каждой поверхности в вашем полигоне будут отобраны, в результате ничего не отобразится). Эти виды настроек, называются «установками рендеринга». Как только вы примерно установите их, они останутся в эффекте до тех пор, пока вы не установите их как-то иначе. Только вы должны установить их однажды заранее, если вы рендерите несколько мешей одним способом.
Orion45
11.05.13 в 22:11
|
|
Проверка глубины. Когда Flash рендерит вашу сцену, имеет значение как далеко каждый полигон располагается от камеры. Например, стена, которая близко к камере, не будет интуитивно скрывать ничего за собой. Для того, чтобы определить, что перед, а что за, каждый раз пиксели рендерятся в Stage3D, rgb-данные сохраняются в соответствии с глубиной компонентов. Данные, которые хранятся в глубине каждого пикселя на экране, называются буфером глубины (z-буфером). По умолчанию в Stage3D рендерятся только пиксели, которые ближе всего к камере, что имеет смысл, как было показано в предыдущем примере со стеной. Обычно, есть множество случаев, когда вы не хотите сохранять информацию глубины для детальных мешей (например, когда используете спецэффекты, такие как взрывы, прозрачные области подобно оконному стеклу) или когда вы не хотите проверять буфер глубины при визуализации (для рентгеновского зрения, где вы можете видеть меш, даже если он полностью скрыт за стеной).
Orion45
12.05.13 в 12:40
|
|
Время для действий: Создание меша не влияет на z-буфер. Для того, чтобы изменить то, что Flash делает с проверкой глубины, вы можете инструктировать его либо не писать в z-буфер, либо не проверять его, или комбинировать и то и другое, используя функцию setDepthTest(). context3D. setDepthTest(false, Context3DCompareMode.LESS); Что же произойдет?
Orion45
12.05.13 в 12:42
|
|
Эта функция принимает два параметра. Первый это булевое (true или false) значение, которое является true, если вы хотите следующий меш, который вы рендерите, записать в буфер глубины. Второй параметр может быть одним из следующих: Context3DCompareMode.ALWAYS Context3DCompareMode.EQUAL Context3DCompareMode.GREATER Context3DCompareMode.GREATER_EQUAL Context3DCompareMode.LESS Context3DCompareMode.LESS_EQUAL Context3DCompareMode.NEVER Context3DCompareMode.NOT_EQUAL
Orion45
12.05.13 в 12:43
|
|
Запрашиваемый пиксель будет рендериться когда сравнение между ним и целевым пикселем даёт TRUE, основываясь на предыдущем критерии. По умолчанию в Stage3D рендерятся только пиксели, которые имеют значение глубины меньше (LESS ) чем те, что уже на экране, ближе к камере.
Orion45
12.05.13 в 12:44
|
|
Предыдущий пример удобен, если вы собираетесь рендерить прозрачный меш подобно окну, которое вы не хотите рисовать в z-буфере (так, что другие объекты всегда видимы за ним), но вы хотите, чтобы оно скрывало обстановку в комнате, которая находится перед ним. Как и с другими состояниями рендеринга, они будут в эффекте до тех пор, пока вы не установите их как-нибудь иначе. Вы должны вызвать их только однажды, и эти критерии будут использоваться до тех пор, пока вы не проинструктируете Flash по-другому.
Orion45
12.05.13 в 12:47
|
|
Режимы наложения. Stage3D API предоставляет мощный массив режимов наложения, которые действуют как текстуры при рендеринге. Например, вы можете инструктировать его рисовать текстуру, используя прозрачность или смешать цвета в вашей текстуре с теми, что позади неё, так что они подсветят или затемнят экран. Этими видами режимов наложения – сложения, смешивания, вычитания – в современных играх рисуются системы частиц, такие как дым, огонь, взрывы, искры и т.п.
Orion45
12.05.13 в 13:08
|
|
Перед тем, как вы нарисуете меш, вы можете использовать функцию Context3D.setBlandFactors(), чтобы инструктировать Flash как вы хотите рисовать текстуру. Чтобы установить режим наложения, вы отправляете два коэффициента наложения в функцию. Первый коэффициент это исходный коэффициент, и второй – это целевой коэффициент. Результирующий пиксель на экране вычисляется следующим образом: framebuffercolor = (fragmentcolor * srcBlend) + (framebuffercolor * destBlend).
Orion45
12.05.13 в 13:20
|
|
В следующем разделе «Время для действий» есть три обобщённых примера режимов наложения в действии: рендеринг непрозрачного меша, рендеринг меша с прозрачными областями (такой как лист) и рендеринг меша так, чтобы он освещал сцену (такой как взрыв).
Orion45
12.05.13 в 13:20
|
|
Время для действий: рендеринг непрозрачного меша. //это Molehill по умолчанию: хорошо для непрозрачных текстур //все цвета на экране получены из фрагментных цветов context3D.setBlendFactors( Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO); Что же произойдёт?
Orion45
12.05.13 в 13:21
|
|
Мы инструктируем Stage3D взять цвет из результата вашего фрагментного шейдера и пропустить цвет из буфера кадра (который позади меша). Это будет выглядеть наподобие как на следующем скриншоте: Время для действий: рендеринг меша с прозрачными областями. //Эту настройку следует использовать для .png текстур, //которые имеют прозрачные области //подходит для листвы/изгородей/шрифтов context3D.setBlendFactors( Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_ SOURCE_ALPHA);
Orion45
12.05.13 в 13:24
|
|
Что же произойдёт? Мы просто инструктируем Stage3D, чтобы следующий рендерящийся меш взял всю цветовую информацию из выходных данных нашего фрагментного шейдера, где альфа (прозрачность) в нашей текстуре это чистый белый, и накладывается на цвет из буфера кадра позади меша в количестве, пропорциональном содержанию чёрных пикселей в текстурном альфа-канале. В примере с нашей картинкой листа зелёные биты листвы имеют чисто-белую альфу, и прозрачные области в текстуре будет чисто чёрными, если мы будем смотреть только альфа-данные, зашифрованные в изображении.
Orion45
12.05.13 в 13:27
|
|
Время для действий: рендеринг меша так, чтобы он освещал сцену. //эти настройки заставят его освещать только сцену //хорошо для частиц, сохранённых как .jpg //(только белые части добавляются на экран – чёрные не рисуются) context3D.setBlendFactors( Context3DBlendFactor.SOURCE_COLOR, Context3DBlendFactor.ONE);
Orion45
12.05.13 в 13:38
|
|
Что же произойдёт? Мы просто инструктируем Stage3D, что мы хотим, чтобы следующий меш, рендерясь, добавлял цвет пикселя нашей текстуры на сцену, так что каждый пиксель рендерясь, будет приближать изображение к чисто-белому. Используйте творчески режимы наложения, необходимые для системы частиц и других спецэффектов. Вот ещё один, последний, пример из нескольких для множества возможных режимов наложения.
Orion45
12.05.13 в 13:41
|
|
Следующие три картинки изображают режимы наложения DESTINATION_COLOR, ZERO, ONE, ONE и SOURCE_COLOR, ONE соответственно: В качестве параметров для функции context3D.setBlendFactors() у вас есть следующие варианты, каждый из которых имеет типы Context3DBlendFactor: Context3DBlendFactor.DESTINATION_ALPHA Context3DBlendFactor.DESTINATION_COLOR Context3DBlendFactor.ONE Context3DBlendFactor.ONE_MINUS_DESTINATION_ALPHA Context3DBlendFactor.ONE_MINUS_DESTINATION_COLOR Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA Context3DBlendFactor.ONE_MINUS_SOURCE_COLOR Context3DBlendFactor. SOURCE_ALPHA Context3DBlendFactor. SOURCE_COLOR Context3DBlendFactor. ZERO
Orion45
12.05.13 в 13:43
|
|
Режимы наложения, отбор поверхностей, проверка глубины - это все состояния рендеринга, значения которых вы только однажды должны установить, и поведение которых будет продолжаться до тех пор, пока вы не установите их как-нибудь иначе. Иногда это может быть источником незнакомых ошибок: если вы обнаружите, что после экспериментов с режимами наложения, другие модели теперь нечаянно рендерятся прозрачными, значит, вы могли забыть переустановить задний режим наложения по умолчанию (ONE, ZERO). Чтобы вернуть им «полностью непрозрачный» режим наложения, который активируется при первой инициализации Stage3D, вы должны использовать этот код: context3D.setBlendFactors( Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
Orion45
12.05.13 в 13:45
|
|
Увеличиваем производительность. Хотя Stage3D API невероятно быстр и может обрабатывать сотни тысяч полигонов в режиме реального времени, вы должны избегать кусков больше, чем ваша видеокарта способна разжевать. Это особенно важно при ориентации на маломощные системы, такие как дешевые нетбуки или мобильные устройства. Некоторые общие методы для получения наилучшей производительности (и в результате получения высокой частоты кадров) это следовать вечному правилу поцелуя (будь проще, глупый!)
Orion45
12.05.13 в 13:48
|
|
Непрозрачные быстрее. Например, можно использовать непрозрачные. JPG текстуры как можно чаще, так как прозрачные полигоны рендерятся гораздо медленнее. Почему? Потому что ваша видеокарта должна взять первый образец цвета пикселей под полигоном, который вы в настоящее время рендерите, чтобы смешать его с новым цветом. Если ваш полигон полностью непрозрачен, то этого расчета можно избежать.
Orion45
12.05.13 в 13:50
|
|