Быстрый софтовый Motion Blur (размытие)

Тема в разделе "WASM.A&O", создана пользователем Tronix, 7 окт 2010.

  1. Tronix

    Tronix Member

    Публикаций:
    0
    Регистрация:
    10 сен 2010
    Сообщения:
    122
    Привет, использую алгоритм, описанный древними в DEMO.DESIGN FAQ. bpp - 32, esi - массив 640x480x4, ecx: (640*460)*4
    Код (Text):
    1. @@1:
    2.     mov     eax, [esi-4]
    3.     mov     edx, [esi+4]
    4.  
    5.     and     eax, 0fcfcfcfch
    6.     and     edx, 0fcfcfcfch
    7.  
    8.     shr     eax, 2
    9.     shr     edx, 2
    10.  
    11.     add     eax, edx
    12.     mov     ebx, [esi-640*4]
    13.  
    14.     and     ebx, 0fcfcfcfch
    15.     mov     edx, [esi+640*4]
    16.  
    17.     shr     ebx, 2
    18.     and     edx, 0fcfcfcfch
    19.  
    20.     shr     edx, 2
    21.     add     esi, 4
    22.  
    23.     add     eax, edx
    24.  
    25.     add     eax, ebx
    26.     sub     ecx, 4
    27.  
    28.     mov     [esi-4], eax
    29.     jne     @@1
    Дело в том, что этот алгоритм срезает цвета. Более честный алгоритм должен быть примерно такой:
    Код (Text):
    1. @1:
    2.    xor      eax,eax
    3.    mov      bl,[edi-4]
    4.    add      eax,ebx
    5.    mov      bl,[edi-640*4]
    6.    add      eax,ebx
    7.    mov      bl,[edi+640*4]
    8.    add      eax,ebx
    9.    mov      bl,[edi+4]
    10.    add      eax,ebx
    11.  
    12.    shr      eax,2
    13.    mov      [edi],al
    14.    inc      edi
    15.    loop     @1
    Но естественно, что он адово тормозит. Интересует простой вопрос - можно ли как-то убыстрить второй вариант? Напрмер использую MMX/SSE расширения?
     
  2. Ravager

    Ravager New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    34
    Можно попробовать использовать mmx, но тут всплывает распаковка/запаковка...
    Код (Text):
    1. mov esi,src;адрес исходного массива
    2. mov edi,dst;адрес массива назначения
    3. mov ecx,640*(480-2);для верхней и нижней строчек размытие не делаем
    4. add edi,640
    5. add esi,640;пропускаем первую строку
    6. @1:
    7. ;[esi] - текущий пиксел
    8. punpcklbw mm0, [esi-4];теперь старшие байты 4-х слов регистра mm0 содержат цветовые
    9. ;компоненты соседнего левого пиксела
    10. psrlw mm0, 8;переводим их в младшие байты, т.е. теперь 4 слова mm0 содержат цветовые
    11. ;компоненты соседнего левого пиксела
    12.  
    13. punpcklbw mm1, [esi+4];аналогично загоняем соседний правый в mm1
    14. psrlw mm1, 8
    15.  
    16. paddw mm0, mm1;складываем покомпонентно, результат накапливаем в mm0
    17.  
    18. punpcklbw mm1, [esi+640*4];добавляем туда же верхний и нижний
    19. psrlw mm1, 8
    20. paddw mm0, mm1
    21.  
    22. punpcklbw mm1, [esi-640*4]
    23. psrlw mm1, 8
    24. paddw mm0, mm1
    25.  
    26. psrlw mm0, 2;покомпонентно делим на 4
    27. packuswb mm0, mm0;теперь 4 младших байта mm0 содержат результирующий пиксел
    28. movd [edi], mm0;записываем результат
    29. add esi,4
    30. add edi,4
    31. loop @1
    Можно, конечно, один массив пикселей использовать как исходный и результирующий одновременно, но это не совсем корректно.
     
  3. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Tronix
    Motion Blur это размытие в движение когда предыдущие и последующие кадры размываются.
    Тут просто Blur. Правда странная разновидность. С перекосом. Да [esi] не использует. Видимо за скорость боролись.

    Насколько сильно тормозит и насколько быстро надо? Надеюсь, ты не с видео памятью работаешь?
     
  4. Tronix

    Tronix Member

    Публикаций:
    0
    Регистрация:
    10 сен 2010
    Сообщения:
    122
    Ravager Спасибо, попробую разобраться... А вы не могли бы пару-тройку комментов к коду привести, был бы признателен. С MMX я просто не знаком, понять бы просто логику основную.. Ну или буду пробовать читать маны )) Спасибо еще раз.

    Pavia Эээ, да, наверное неправильно выразился. Это простое размытие по четырем окружающим точкам, ну вы и сами это уже поняли. Ну на современных компьютерах конечно не тормозит, а вот на процессорах уровня Celeron 433Mhz подтормаживает. Нет, работаю конечно не с видеопамятью напрямую, просто с буфером в памяти работаю. Чтобы не быть голословным прикреплю сейчас мою программку (win32) - вращает тор из точек и размывает его. Blur 1 - это первый алгоритм, Blur 2 - это второй алгоритм. В заголовке окна выводится количество FPS...
     
  5. Ravager

    Ravager New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    34
    Tronix
    Ну вот, подредактировал немного. Дожно быть всё же побыстрее, чем побайтовое усреднение.

    Неужели 2 срезанных бита дают столь отчётливо видимое различие? Потрясающе.
     
  6. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Ravager "Всего" 2 бита увеличивают глубину цвета в 4 раза :)) это всё равно что сравнивать 10 и 1000 где "всего-то два нуля" приписалось :))
     
  7. Ravager

    Ravager New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    34
    Y_Mur
    Тем не менее, разницу между изображением с глубиной цвета, к примеру, в 16 и 24 бит заметить довольно непросто.
     
  8. Tronix

    Tronix Member

    Публикаций:
    0
    Регистрация:
    10 сен 2010
    Сообщения:
    122
    Ravager О, спасибо, теперь все понятно. Буду пробовать.
    А действительно, этот алгоритм (первый который срезает биты), наверное для 24-битной палитры был задуман, там разница не будет так отчетливо видна.
     
  9. Ravager

    Ravager New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    34
    Обязательно выложи демку с тремя алгоритмами, интересно же. ;)
     
  10. Tronix

    Tronix Member

    Публикаций:
    0
    Регистрация:
    10 сен 2010
    Сообщения:
    122
    Да, с MMX стало работать побыстрее. Демку с тремя алгоритмами прикладываю. Единственное пока нет проверки на cpuid, поэтому если вдруг кто-то решит затестить на чем-то вроде 486 с галкой на Blur MMX, получит соответственно ексепшен.