2014-01-23 4 views
0

Я создал переходный шейдер.Transition shader

Это то, что делает:

On each update the color that should be alpha changes. 
Then preform a check for each pixel. 
    If the color of the pixel is more that the 'alpha' value 
     Set this pixel to transparent. 
    Else If the color of the pixel is more that the 'alpha' value - 50 
     Set this pixel to partly transparent. 
    Else 
     Set the color to black. 

EDIT (DELETED старых частей):

Я попытался преобразовать мой GLSL в гал (используя http://cmodule.org/glsl2agal):

Фрагмент шейдеры:

const float alpha = 0.8; 
varying vec2 TexCoord; //not used but required for converting 
uniform sampler2D transition;//not used but required for converting 

void main() 
{ 
    vec4 color = texture2D(transition, TexCoord.st);//not used but required for converting 

    color.a = float(color.r < alpha); 

    if(color.r >= (alpha - 0.1)){ 
     color.a = 0.2 * (color.r - alpha - 0.1); 
    } 

    gl_FragColor = vec4(0, 0, 0, color.a); 
} 

И я настроил вывод и добавил, что к (пользовательскому) St arling filter:

var fragmentShader:String = 
    "tex ft0, v0, fs0 <2d, clamp, linear, mipnone>     \n" + // copy color to ft0 
    "slt ft0.w, ft0.x, fc0.x          \n" + // alpha = red < inputAlpha 
    "mov ft0.xyz, fc1.xyzz           \n" + // set color to black 
    "mov oc, ft0"; 

mShaderProgram = target.registerProgramFromSource(PROGRAM_NAME, vertexShader, fragmentShader); 

Это работает, и когда я устанавливаю фильтры alpha, он обновит материал. Остается только частично прозрачная вещь, но я понятия не имею, как я могу это сделать.

+0

Я знаю, что почти нул про скворцов, но я бы предложил вам использовать http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filters/ColorMatrixFilter.html для обработки переходов цвета. Я уверен, что если вы правильно построите матрицу, вы можете получить тот же эффект в 1000 раз больше скорости по методу петли. –

+0

Да, у скворца тоже есть фильтры, так что в основном это одно и то же, хотя я понятия не имею, как бы добиться такого поведения с помощью фильтра цветной матрицы. – Duckdoom5

ответ

4

Поменяйте цикл на координаты Y и X. Используя X во внутреннем цикле, вы оптимизируете кеш L1 и prefetcher CPU.

Некоторые незначительные намеки:
Удалите нули для более чистого кода:

const c:uint = a << 24 

Убедитесь, что 255/50 свернут в одну константу компилятором.

+0

Можете ли вы предоставить какие-либо подробности или ссылки, которые предполагают, что этот раздел кода хранится в кеше L1? А также подробности о том, как обменивать петли, принудительное использование в кеше L1. –

+0

Переключение петель действительно помогло, теперь 23 FPS вместо 20. (Я отредактировал код в своем сообщении) Хотя его все еще не так быстро, как хотелось бы. Возможна ли такая функциональность по-другому? Я сделал это перед использованием GLSL, но ничего не знаю об AGAL. – Duckdoom5

+0

Возможно, что большую часть времени потрачено внутри getPixel и setPixel, вы измеряли максимальную теоретическую скорость с помощью: tempBitmapData.setPixel32 (x, y, bitmapData.getPixel (x, y))?; Постскриптум редактируя код, мой ответ может считаться «неправильным» сейчас (!) –

1

Не сходите с ума, делая это с помощью BitmapData, когда вы используете Starling.

Я не получил, если вы снимаете его самостоятельно или нет. В не просто создать Starling filter для полутоновых (пиксельный шейдер ниже будет делать трюк)

tex ft0, v0, fs0 <2d,linear,clamp> 
add ft1.x, ft0.x, ft0.y 
add ft1.x, ft1.x, ft0.z 
div ft1.x, ft1.x, fc0.x 
mov ft0.xyz, ft1.xxx 
mov oc ft0 

А для альфа-перехода просто расширить класс изображения, осуществлять IAnimatable добавить его к Жонглер. в advanceTime просто сделайте this.alpha -= VALUE;

Простой как это :)

+0

Это не так просто: P Давайте возьмем это изображение в качестве примера: [Battle.png] (https://www.dropbox.com/s/4l7tulsduas242b/Battle.png) При каждом обновлении цвет это должны быть альфа-изменения. Затем заготовьте чек для каждого пикселя. Если цвет пикселя больше, чем значение «альфа». Установите этот пиксель в прозрачный. Else. Установите цвет в черный цвет. – Duckdoom5

+0

Вам просто нужно сделать чек для пикселя и убить этот пиксель в шейдере. Позже я могу опубликовать шейдер AGAL ... прямо сейчас у меня нет времени. Ps .: ты сказал, что сделал это с GLSL, просто переведите его в агаль и используйте его; вот glsl2agal converter http://www.cmodule.org/glsl2agal/ Cheers –

+0

: O GLSL to AGAL: O Спасибо: D – Duckdoom5

1

Просто собирается разработать немного на @ Paxel отвечают. Я обсуждал с другим разработчиком Jackson Dunstan о кешировании L1, откуда приходит улучшение скорости, и какие другие улучшения могут быть сделаны для кода, подобного этому, чтобы увидеть прирост производительности.

После чего Джексон отправил запись в блоге, который можно прочитать на здесь: Take Advantage of CPU caching

я выложу некоторые относительные элементы. Сначала данные растрового изображения хранятся в памяти по строкам. Адреса строк памяти может выглядеть примерно так:

row 1: 0 1 2 3 4 5 
    row 2: 6 7 8 9 10 11 
    row 3: 12 13 14 15 16 17 

Теперь работает ваш внутренний цикл по строкам позволит вам использовать преимущество кэша L1, так как вы можете прочитать память в порядке.Таким образом, внутренняя перекручивание X сначала прочту первую строку как:

0 1 2 3 4 5 

Но если вы должны были сделать это Y сначала вы бы читать как:

0 6 12 1 7 13 

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

Что касается оптимизаций, которые можно было бы сделать, рекомендуется использовать кеширование ваших геттеров ширины и высоты, сохраняя свойства в локальных переменных. Также использование Math.round() довольно медленно, заменив это, чтобы увидеть увеличение скорости.