Реализация эффектов Douyin в Интернете

JavaScript WebGL

Самое популярное короткое видео приложение в данный момент - Дуюн. С его богатыми видео особыми эффектами Дуйин привлек пользу многих молодых пользователей. Сегодня давайте посмотрим на то, как в Интернете реализуются специальные эффекты Дуйина.

основной принцип

Принцип реализации относительно прост, и его можно свести к следующим трем шагам:

  • 1. Используйте предварительно обработанный холст для рисования каждого кадра видео.
  • 2. Перенести предварительно отрендеренный холст в видеопамять как текстуру.
  • 3. Программа-шейдер выполняет постобработку текстуры.

Шаги кажутся простыми, но второй и третий шаги требуют некоторых знаний о WebGL и шейдерах, поэтому не беспокойтесь о том, чего вы не понимаете, вы можете добавить некоторые соответствующие знания.

Основная реализация

Каждый специальный эффект нуждается в поддержке программы JS и программы шейдера, я объясню на примере программы JS и программы шейдера соответственно.

Следующие спецэффекты призваны продемонстрировать мощь и очарование шейдерных программ, поэтому спецэффекты в основном реализованы на стороне шейдеров, так что же делает программа JS?

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

1. Сначала посмотрите на структуру html

  <canvas id="canvas"></canvas>
  <canvas id="canvasBg" width="256" height="256"></canvas>
  <video id="video" src="../img/movie.mp4" controls></video>

Мы разместили два Canvas, первый Canvas используется для отображения спецэффектов, а второй Canvas используется для отрисовки видеокадров, что относительно просто.

2. Затем посмотрите на основной код логики JS.

  • Прочитайте видеокадр, визуализируйте его во временном Canvas и передайте временный Canvas в видеопамять в виде текстуры.
  ctxBg.drawImage(video, 0, 0, 256, 256);
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvasBg);
  gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.uniform1i(u_Texture, 0);
  • Запустите таймер и каждый раз передавайте переменную времени в видеопамять.
function loop() {
      if (video.ended) {
        return;
      }
      computeFrame();
      time = time + interval;
      gl.uniform1f(u_Time, time);
      // 清除画布
      gl.clear(gl.COLOR_BUFFER_BIT);
      if (positions.length <= 0) {
        return;
      }
      //绘制图元设置为三角形。
      var primitiveType = gl.TRIANGLES;
      //因为我们要绘制6个点,所以执行6次顶点绘制操作。
      gl.drawArrays(gl.TRIANGLES, 0, positions.length / 3);
      timer = requestAnimationFrame(loop);
    }

3. Та часть, которая собственно реализует спецэффекты находится на шейдерной программе.Конечно, исходный код шейдера тоже перенесен из JS в видеопамять.Мы не будем приводить эту часть кода, а только покажем вам различные спецэффекты.

Изображение немного пустое, вы можете не видеть его четко, но вы можете перейти на веб-страницу с образцом, чтобы почувствовать это~

  • зум

  • мигающий белый

  • остаточный образ

  • ДУША

  • Сбой

Эпилог

Кодовая реализация приведенного выше примера включает в себя некоторые основные операции WebGL, которые довольно объемны.Студенты, которые хотят увидеть пример, могут перейти к моемуgithubчтобы проверить это.

Дружеское напоминание: лучше всего просматривать его на ПК. При просмотре на мобильном терминале все еще возникают некоторые проблемы ~

В конце немного кликните ручонкой и обратите внимание на официальный аккаунт [внешний стек E]~