Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   [Stage3D] как затекстурить прямоугольник без PerspectiveMatrix3D? (http://www.flasher.ru/forum/showthread.php?t=192004)

loover 08.01.2013 23:56

как затекстурить прямоугольник без PerspectiveMatrix3D?
 
возможно ли текстурирование прямоугольника (двух треугольников) без использования матрицы проекции? один треугольник текстурится легко, но с двумя все не так гладко: либо текстура помещается только а один из них, либо она сильно искажается.

Nooob 09.01.2013 02:55

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

loover 09.01.2013 04:56

Nooob, да, дело оказалось в перепутанных значениях uv. поправил и текстура отображается нормально. но возникла другая проблема. текстура непропорционально растягивается, т.к. выходной буфер имеет размер сцены (550х400), битмапдата для текстуры имеет тот же размер, а вот текстура - 1024х512 (т.к. ее размеры должны быть кратны 2). явно не соответствие. пока просто увеличил буфер до размера текстуры, но это явно не то. матрица сможет этому помочь?

Код AS3:

var vertices:Vector.<Number> = Vector.<Number>([
                                                                                -1, -1, 0, 0, 1,
                                                                                -1, 1, 0, 0, 0,
                                                                                1, 1, 0, 1, 0,
                                                                                1, -1 , 0, 1, 1]);
vertexbuffer = context3d.createVertexBuffer(4, 5);
vertexbuffer.uploadFromVector(vertices, 0, 4);
 
var indices:Vector.<uint> = Vector.<uint>([0, 1, 2, 2, 3, 0]);
indexbuffer = context3d.createIndexBuffer(6);
indexbuffer.uploadFromVector (indices, 0, 6);

насчет производительности. vertex shader и fragment shader заполняю так:
Код AS3:

vertexShader.assemble(Context3DProgramType.VERTEX, "mov op, va0 \n" + "mov v0, va1");
fragmentShader.assemble(Context3DProgramType.FRAGMENT,  "tex oc, v0, fs0 <2d,linear>");


nuToH 09.01.2013 12:53

возможно, это наведет вас на мысль:
крайний u = 550 / 1025
крайний v = 400 / 512

loover 10.01.2013 01:15

nuToH, спасибо, все работает.

а что скажете по поводу производительности? не быстрее ли будет с матрицей?

можно ли как то ускорить отрисовку объектов на сцене через занесение их в текстуру? есть тест из 1000 вращающихся картинок. если отключить видимость root и отрисовывать весь root каждый ENTER_FRAME в BitmapData (которая загружается в текстуру), то никакого ускорения от использования Stage3D не наблюдается, т.к. процессор загружен преимущественно BitmapData.draw() и фпс все равно проседает.

Nooob 10.01.2013 10:16

Быстрее с матрицей, а лучше возьми и сам проверь.
Ускорит отрисовку уменьшение вызовов drawTriangles с помощью батчинга.
Процесс батчинга прост. нужно все свои прямоугольники (до 16383 на 1 вызов drawTriangles) хранить и изменять в одном буфере.
Демо 1 Демо 2
К примеру для 2 прямоугольников (x=716, y=516, w=256, h=256) и (x=490, y=507, w=256, h=256)
буферы будут такие
Код:

vertexes = [716,772,716,516,972,516,972,772,490,763,490,507,746,507,746,763]
indexes = [0,1,2,0,2,3,4,5,6,4,6,7]
uvs = [0,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1]

Матрица камеры, с началом координат от верхнего левого угла:
Код AS3:

cameraMatrix.identity();
cameraMatrix.appendScale(2 / stage.stageWidth, -2 / stage.stageHeight, 1);
cameraMatrix.appendTranslation(-1, 1, 0);

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

Плюсы:
высокая производительность 16к прямоугольников при стабильных 60 fps на среднем компьюторе
Минусы:
на одну отрисовку можно использовать только 1 текстуру, либо использовать тест глубины (если нет прозрачных изображений)

Можно в одном шейдере использовать до 8 семплов текстуры, но тогда производительность упадёт.
Пример шейдера:
Код AS3:

 
var vertextCode:String  = <![CDATA[
        m44 op, va0, vc0
        mov v0, va1
        mov v1, va2
        mov v2, va3
]]>;
var fragmentCode:String = <![CDATA[
  tex ft0, v0, fs0 <2d>
  mul ft0, ft0, v1.xxxx
 
  tex ft1, v0, fs1 <2d>
  mul ft1, ft1, v1.yyyy
  add ft0, ft0, ft1
 
  tex ft2, v0, fs2 <2d>
  mul ft2, ft2, v1.zzzz
  add ft0, ft0, ft2
 
  tex ft3, v0, fs3 <2d>
  mul ft3, ft3, v1.wwww
  add ft0, ft0, ft3
 
  tex ft4, v0, fs4 <2d>
  mul ft4, ft4, v2.xxxx
  add ft0, ft0, ft4
 
  tex ft5, v0, fs5 <2d>
  mul ft5, ft5, v2.yyyy
  add ft0, ft0, ft5
 
  tex ft6, v0, fs6 <2d>
  mul ft6, ft6, v2.zzzz
  add ft0, ft0, ft6
 
  tex ft7, v0, fs7 <2d>
  mul ft7, ft7, v2.wwww
  add ft0, ft0, ft7
 
  mov oc, ft0
]]>;

Есть ещё один вариант (если используется профиль BASELINE_EXTENDED): это использовать в шейдере инструкции условий ife,els и тд
Пример:
Код AS3:

var vertextCode:String    = <![CDATA[
        m44 op, va0, vc0
        mov v0, va1
        mov v1, va2
]]>;
var fragmentCode:String = <![CDATA[
        mov ft0, fc0
        ife v1.x, fc0.x
                tex ft0, v0, fs0 <2d>
        els
                ife v1.x, fc0.y
                        tex ft0, v0, fs1 <2d>
                els
                        ife v1.x, fc0.z
                                tex ft0, v0, fs2 <2d>
                        els
                                ife v1.x, fc0.w
                                        tex ft0, v0, fs3 <2d>
                                eif
                        eif
                eif
        eif
        ife v1.x, fc1.x
                tex ft0, v0, fs4 <2d>
        els
                ife v1.x, fc1.y
                        tex ft0, v0, fs5 <2d>
                els
                        ife v1.x, fc1.z
                                tex ft0, v0, fs6 <2d>
                        els
                                ife v1.x, fc1.w
                                        tex ft0, v0, fs7 <2d>
                                eif
                        eif
                eif
        eif
        mov oc, ft0
]]>;


zuxul 10.01.2013 10:21

BitmapData.draw не использует видеокарту для отрисовки. О каком ускорении Вы говорите?

nuToH 10.01.2013 12:11

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

loover 10.01.2013 21:21

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

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

Nooob 10.01.2013 21:42

не будет профита никакого

loover 14.01.2013 04:06

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

zuxul 14.01.2013 11:24

Nooob вроде бы же описал.
Но в исходниках посмотреть будет гораздо полезней: https://github.com/PrimaryFeather/St...y/QuadBatch.as


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

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