Как загрузить изображение, создать текстуру, визуализировать и сохранить изображение асинхронно с WebGL? - PullRequest
3 голосов
/ 02 сентября 2011

Я пытаюсь написать приложение, которое использует очень большие текстуры.Идея состоит в том, что вы работаете с масштабированной версией текстуры в изменяющих шейдерах в реальном времени, и по завершении приложение применяет ваши изменения к исходной немасштабированной (большой) текстуре.Проблема в том, что профилирование показывает что-то вроде следующего:

  • img.src = имя файла (500 мс)
  • texImage2d (...) (1500 мс)
  • bind/ рендеринг (100 мс)
  • readPixels (300 мс)
  • Поместить на холст (1000 мс)
  • Сохранить холст в файл (300 мс)

По существуэто означает, что браузер блокируется почти на четыре секунды при сохранении более крупной немасштабированной текстуры, когда пользователь не может ничего сделать.Возможно ли сделать это асинхронно, чтобы браузер оставался отзывчивым?Все это должно быть сделано в javascript и на стороне клиента, так как я использую локальные файлы (файл / файловая система HTML5).

Веб-работники звучат как хорошая идея, но они не могут получить доступ к DOM,поэтому я не могу использовать функцию загрузки и сохранения изображений в браузере, и у них нет доступа к контексту WebGL, поэтому они не могут вызвать texImage2d, что занимает больше всего времени.

Из-за размера и количестваизображения Я не могу загрузить их все в память в качестве текстур при первоначальной загрузке страницы.

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

Ответы [ 2 ]

2 голосов
/ 03 сентября 2011

Загрузка изображения должна происходить в фоновом режиме, и вы не будете знать, как это сделать, но вы можете использовать texSubImage2D для постепенной загрузки текстуры. Это, вероятно, займет немного больше времени, но вы сможете дать пользователю некоторую обратную связь и ответить на другие события.

Кроме того, вы можете просто нарисовать холст webgl прямо в холст 2D. drawImage() принимает в качестве аргументов элементы изображений, видео и холста (2D или webgl). Это должно произойти почти мгновенно и сэкономить около 1300 мс.

1 голос
/ 25 мая 2019

Этот вопрос старый, но для тех, кто находит его, есть обновленная информация

  • Вы можете использовать OffscreenCanvas, который поставляется в Chrome с января2019. К сожалению, он не доставляется куда-либо еще. ATM

  • Эти 3 синхронных шага

    readPixels (300ms)
    Put into canvas (1000ms)
    Save canvas to file (300ms)
    

    можно превратить в 1 асинхронный шаг

    gl.canvas.toBlob((blob) => {
      const url = URL.createObjectURL(blob);
      // url is now something you can give the user to download
    });
    
  • для рендеринга действительно больших изображений (скажем, 16k на 16k), вы можете рендерить меньшие части и собирать их в большие изображения.

    Здесь есть библиотека для этого: https://greggman.github.io/dekapng/

...