Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > skyman000

Рейтинг: 5.00. Голосов: 3.

Molehill 3D API вводный курс статей. часть 2. Усложнение задач.

Запись от skyman000 размещена 28.05.2011 в 17:56
Обновил(-а) skyman000 28.05.2011 в 20:25

Содержание:

Molehill 3D API вводный курс статей. часть 1. Что такое Molehill?
Molehill 3D API вводный курс статей. часть 2. Усложнение задач.
Molehill 3D API вводный курс статей. часть 3. Работа с матрицами.
Molehill 3D API вводный курс статей. часть 4. Первый 3D объект с простой текстурой.

Усложнение задач.

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

Для начала заметим что одна эта строка
Код AS3:
"m44 op, va0, vc0 \n"
Эквивалентна этим четырем строкам
Код AS3:
"dp4 op.x, va0, vc0 \n" + 
"dp4 op.y, va0, vc1 \n" +
"dp4 op.z, va0, vc2 \n" +
"dp4 op.w, va0, vc3 \n" +
Но так можно более подробно рассмотреть процесс умножения вершин на матрицу преобразований

dp4 – это операция скалярного умножения векторов
описание операции взято с
http://labs.jam3.ca/asdocs/incubator...Program3D.html

Код AS3:
destination = source1.x*source2.x + source1.y*source2.y + source1.z*source2.z + source1.w*source2.w
Как видите в первой строке мы по всем правилам векторной математики уможаем строку на 1 столбец матрицы используя при этом оператор скалярного умножения. Далее мы то же проделываем с оставшимися 3 столбцами. Стоит заметить что каждый столбец матрицы представлен в виде вектора со свойствами XYZW.

Итак а теперь представим что нам понадобилось инвертировать все цвета внутри треугольников. Цвет у нас представлен 3 числами от 0 до 1. Чтоб инвертировать такой цвет нужно от единицы отнять каждое из этих трех чисел.
Оператор вычитания в AGAL называется sub
Таким образом мы можем модифицировать шейдер фрагментов следующим образом

Код AS3:
"sub ft0, 1, v0    \n" + 
"mov oc, ft0"
Тут ft0 это одна из встроенных переменных AGAL которую мы используем как посредник в передаче цвета. Переменная ft0 имеет тип Vector3D и следовательно 4 свойства XYZW
В коде выше цвет rgb хранится в ft0 в свойствах xyz
Но на самом деле приведенный выше код не будет работать, так как нельзя напрямую писать в коде числа (почему так нельзя делать я так и не разобрался)

Для того чтоб что то отнять от единицы надо записать эту единицу в свободную переменную возьмем к примеру переменную ft1. Не забываем что ft1 так же имеет тип Vector3D.

context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.<Number>( [ 1, 1, 1, 1 ] ) );
второй параметр функции показывает что мы имеем в виду именно ft1
третий параметр назначает всем свойствам XYZW единицу.
Эту строку вы можете вписать либо в код установки либо в цикл растеризации в зависимости от ситуации.

А теперь давайте пойдем дальше и сделаем фильтр «старой фотографии».
Эта задача выполняется в 2 этапа
Вначале преобразуем цвета в черно-белые
Затем добавляем цветовой тон старой бумаги.

Начнем с перевода цветов в черно-белый цвет
Для этого мы возьмем все три цвета и каждый умножим на его «вес» а затем сложим
Проделаем это с помощью операции скалярного умножения.
Но мы не хотим умножать и складывать параметр W так как у нас нет параметра прозрачности
Поэтому вместо оператора dp4 будем использовать dp3
Подробности: http://labs.jam3.ca/asdocs/incubator...Program3D.html

Итак вводим вектор веса цветов ft1
Код AS3:
 context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.<Number>( [ 0.1, 0.5, 0.9, 1 ] )); 
//P.S. коофиценты веса цветов взяты с потолка для большей наглядности
и записываем в AGAL
Код AS3:
"dp3 ft5.x, fc1, v0 \n" +
Далее тупо умножаем ft5.x на «вес» цветов у старой бумаги
что дает нам эффект старой бумаги
Код AS3:
"mul ft4, fc2, ft5.x \n" +
Не забываем ввести наш вектор веса fc2
Код AS3:
context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.<Number>( [ 1.2, 1.0, 0.8, 1 ] ) );
и выводим цвета на экран
Код AS3:
"mov oc, ft4"

Вот код собранный вместе
Код AS3:
"dp3 ft5.x, fc1, v0 \n" +
"mul ft4, fc2, ft5.x \n" + 
"mov oc, ft4"; 
	context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.<Number>( [ 1.2, 1.0, 0.8, 1 ] ) );
   context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.<Number>( [ 0.1, 0.5, 0.9, 1 ] ));
Натягиваем на треугольник текстуру

Мы будем использовать тип UV наложения текстур
Как вы помните в UV наложении необходимо указать для каждой вершины треугольника соответствующую ей на текстуре точку (где U=X а V=Y). Текстура вне зависимости от ее настоящей ширины и длинны будет иметь в UV координатах конечную длину и ширину равную 1.
Так что получается мы должны составить для каждой вершины нашего треугольника новый буфер вершин
Где вначале будет идти 3 машинных слова для XYZ координат и
+ 2 слова для UV координат текстуры
(UV координаты будут представлены 2 числами с плавающей точкой от 0 до 1)

Итак, наш новый буфер вершин
Код AS3:
 
   vertexBuffer=context3d.createVertexBuffer(3, 5); //5 машинных слов на точку
 
   var vertexData:Vector.<Number>=Vector.<Number>(
    [
     -1,-1, 0,	0, 0,	//<- первая вершина x,y,z,u,v
      0, 1, 0,	1, 0,	//<- вторая вершина x,y,z,u,v
      1,-1, 0,	1, 1 	//<- третья вершина x,y,z,u,v
    ]
   );
Меняем в связи с этим сразу в цикле рендера формат данных
Код AS3:
 context3d.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
так как теперь va1 будет содержать только 2 цифры

Код AS3:
//добавляем в описание главного класса 
  private var texture:Texture;
 
//загружаем текстуру перед входом в цикл рендера
	texture = context3d.createTexture(256, 256, Context3DTextureFormat.BGRA, false);
	var bitmap:Bitmap = event.target.content as Bitmap;
	texture.uploadFromBitmapData(bitmap.bitmapData);
Теперь пара слов о самой текстуре. Отметим про себя, что текстура должна содержать равное количество пикселей по сторонам кратное степени 2 и числом до 256. Это ограничение существует из-за желания Adobe поддерживать большее количество карт.

Все остальное изложено ниже в коде
Где ко всему прочему я сразу добавил фильтр старой фотографии для текстур
Вложения
Тип файла: rar MoleHill21.rar (2.5 Кб, 192 просмотров)
Всего комментариев 5

Комментарии

Старый 29.05.2011 14:13 Sintesis вне форума
Sintesis
 
Аватар для Sintesis
Учи лучше Kernel, по нему и референс хороший есть и тулкит должен нормальный выйти...
Старый 29.05.2011 15:13 Котяра вне форума
Котяра
 
Аватар для Котяра
Kernel хорошо, но и низкий уровень тоже не помешает знать.
Я тоже против изобретений своего велосипеда, но мало ли ребята сделают что-то крутое)
Если бы велосипеды не изобретали, то так бы и сидели на перфокартах до сих пор) А то и на счётах)
Старый 29.05.2011 17:04 -De- вне форума
-De-
 
Аватар для -De-
Спасибо за статьи!
Цитата:
текстура должна содержать равное количество пикселей по сторонам кратное степени 2 и числом до 256
- поясните, пожалуйста, не понятно. Для таких же целей встречал правило "сторона текстуры - степень 2" - это оно? Т.е. 2х2, 2048х64 - ок.
Старый 29.05.2011 20:16 Sintesis вне форума
Sintesis
 
Аватар для Sintesis
Цитата:
- поясните, пожалуйста, не понятно.
Это уже не так важно, в последнем билде инкубатора можно любой размер текстуры использовать
Цитата:
Kernel хорошо, но и низкий уровень тоже не помешает знать.
После Кернела и AGAL легче понимается как-то...
Обновил(-а) Sintesis 29.05.2011 в 20:31
Старый 16.06.2012 23:50 TanaTiX вне форума
TanaTiX
 
Аватар для TanaTiX
А как бы все это выглядело в случае использования Pixel Bender-а?
 

 


Часовой пояс GMT +4, время: 21:07.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.