Molehill 3D API вводный курс статей. часть 2. Усложнение задач.
Содержание:
Molehill 3D API вводный курс статей. часть 1. Что такое Molehill?
Molehill 3D API вводный курс статей. часть 2. Усложнение задач.
Molehill 3D API вводный курс статей. часть 3. Работа с матрицами.
Molehill 3D API вводный курс статей. часть 4. Первый 3D объект с простой текстурой.
Усложнение задач.
Давайте более подробней рассмотрим AGAL, поиграем с этим языком и под конец попробуем натянуть текстуру на наш полигон.
Для начала заметим что одна эта строка
Эквивалентна этим четырем строкам
"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
destination = source1.x*source2.x + source1.y*source2.y + source1.z*source2.z + source1.w*source2.w
Итак а теперь представим что нам понадобилось инвертировать все цвета внутри треугольников. Цвет у нас представлен 3 числами от 0 до 1. Чтоб инвертировать такой цвет нужно от единицы отнять каждое из этих трех чисел.
Оператор вычитания в AGAL называется sub
Таким образом мы можем модифицировать шейдер фрагментов следующим образом
Тут 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
context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, Vector.<Number>( [ 0.1, 0.5, 0.9, 1 ] )); //P.S. коофиценты веса цветов взяты с потолка для большей наглядности
Далее тупо умножаем ft5.x на «вес» цветов у старой бумаги
что дает нам эффект старой бумаги
Не забываем ввести наш вектор веса fc2
context3d.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, Vector.<Number>( [ 1.2, 1.0, 0.8, 1 ] ) );
Вот код собранный вместе
"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)
Итак, наш новый буфер вершин
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 ] );
так как теперь va1 будет содержать только 2 цифры
//добавляем в описание главного класса private var texture:Texture; //загружаем текстуру перед входом в цикл рендера texture = context3d.createTexture(256, 256, Context3DTextureFormat.BGRA, false); var bitmap:Bitmap = event.target.content as Bitmap; texture.uploadFromBitmapData(bitmap.bitmapData);
Все остальное изложено ниже в коде
Где ко всему прочему я сразу добавил фильтр старой фотографии для текстур
Всего комментариев 5
Комментарии
29.05.2011 14:13 | |
Учи лучше Kernel, по нему и референс хороший есть и тулкит должен нормальный выйти...
|
29.05.2011 20:16 | |
Цитата:
- поясните, пожалуйста, не понятно.
Цитата:
Kernel хорошо, но и низкий уровень тоже не помешает знать.
|
|
Обновил(-а) Sintesis 29.05.2011 в 20:31
|
16.06.2012 23:50 | |
А как бы все это выглядело в случае использования Pixel Bender-а?
|
Последние записи от skyman000
- Molehill 3D API вводный курс статей. часть 4. Первый 3D объект с простой текстурой. (28.05.2011)
- Molehill 3D API вводный курс статей. часть 3. Работа с матрицами. (28.05.2011)
- Molehill 3D API вводный курс статей. часть 2. Усложнение задач. (28.05.2011)
- Molehill 3D API вводный курс статей. часть 1. Что такое Molehill? (28.05.2011)