ИСПОЛЬЗОВАНИЕ АФФИННЫХ ПРЕОБРАЗОВАНИЙ ДЛЯ УЛУЧШЕНИЯ СКОРОСТИ РЕНДЕРИНГА ВЕБ-ГРАФИКИ

USING AFFINE TRANSFORMATIONS TO IMPROVE VISUALIZATION IN WEB GRAPHICS
Цитировать:
Коновалик Е.А. ИСПОЛЬЗОВАНИЕ АФФИННЫХ ПРЕОБРАЗОВАНИЙ ДЛЯ УЛУЧШЕНИЯ СКОРОСТИ РЕНДЕРИНГА ВЕБ-ГРАФИКИ // Universum: технические науки : электрон. научн. журн. 2025. 10(139). URL: https://7universum.com/ru/tech/archive/item/21038 (дата обращения: 15.12.2025).
Прочитать статью:

 

АННОТАЦИЯ

Целью исследования является разработка и оценка метода применения аффинных преобразований для веб-визуализации и интеграции данных машинного обучения. Методология основана на формализации аффинных преобразований в однородных координатах и их реализации средствами TensorFlow.js и THREE.js с использованием батч-обработки тензоров на GPU. Проведён сравнительный анализ производительности классического покомпонентного метода Vector3.applyMatrix4 и предложенного батч-подхода. Экспериментальные результаты показали более чем десятикратное ускорение вычислений, снижение задержки отображения и повышение стабильности визуализации в AR/VR-приложениях. Полученные результаты подтверждают эффективность использования аффинных преобразований для оптимизации браузерных ML-интерфейсов. Они создают основу для дальнейшего развития технологий WebGPU и WebXR. 

ABSTRACT

The study aims to develop and evaluate a method for applying affine transformations in web visualization and machine learning data integration. The methodology is based on formalizing affine transformations in homogeneous coordinates and implementing them through TensorFlow.js and THREE.js using GPU-accelerated batch tensor processing. A comparative performance analysis was conducted between the classical point-by-point Vector3.applyMatrix4 approach and the proposed batch method. Experimental results demonstrate more than a tenfold computation speedup, reduced rendering latency, and improved visualization stability in AR/VR applications. The obtained results confirm the effectiveness of affine transformations for optimizing browser-based ML interfaces and provide a foundation for further advancements in WebGPU and WebXR technologies.

 

Ключевые слова: аффинные преобразования, веб-графика, TensorFlow.js, THREE.js, WebGL, WebGPU, компьютерное зрение, визуализация, AR/VR.

Keywords: affine transformations, web graphics, TensorFlow.js, THREE.js, WebGL, WebGPU, computer vision, visualization, AR/VR.

 

Введение

Современные веб-технологии активно развиваются в сторону интеграции интерактивной графики и технологий машинного обучения. На сегодняшний день визуализация в браузере охватывает широкий спектр приложений: от простых анимаций в CSS до сложных трехмерных сцен в WebGL и интерактивных интерфейсов в системах дополненной и виртуальной реальности (AR/VR). Одним из ключевых вызовов в этой области является необходимость постоянного преобразования графических объектов: их масштабирования под разные устройства, поворотов в трехмерном пространстве, переноса в новые координаты сцены и совмещения с данными, полученными из систем компьютерного зрения.

Для решения этой задачи используется универсальный математический аппарат — аффинные преобразования, выражаемые в матричной форме. Они позволяют единообразно описывать все базовые операции над объектами: перемещение, вращение, масштабирование и перспективные проекции. Их преимущества заключаются в компактности записи и возможности объединять несколько преобразований в одно за счет матричного умножения. Именно это свойство делает их незаменимыми в рендеринге графики и обработке данных в реальном времени.

Однако традиционная реализация аффинных преобразований в веб-графике имеет ряд ограничений. В частности, библиотека THREE.js предоставляет удобный интерфейс для применения матриц преобразований (Vector3.applyMatrix4), но он рассчитан на последовательную обработку точек и не масштабируется на большие наборы данных. Это приводит к значительным издержкам при работе с облаками точек, например, при преобразовании координат лицевых лендмарков (facemesh), которые могут насчитывать сотни или тысячи точек. При попытке применения таких подходов в реальном времени, особенно в приложениях AR/VR, наблюдается падение производительности и увеличение задержек отображения.

С другой стороны, современная практика разработки веб-приложений активно движется в сторону интеграции с технологиями машинного обучения. Одним из таких инструментов является TensorFlow.js, предоставляющий возможность выполнять тензорные вычисления в браузере с использованием GPU. Применение тензоров позволяет переходить от покомпонентной обработки к батч-операциям, что в корне меняет производительность графических пайплайнов. В этом контексте реализация аффинных преобразований средствами TensorFlow.js становится не только удобным, но и принципиально более эффективным подходом, способным объединить математику линейной алгебры и практику веб-визуализации.

Научная значимость исследования заключается в том, что работа формализует использование аффинных преобразований для задач веб-графики, связывает классический аппарат линейной алгебры с практическими задачами компьютерного зрения и AR/VR-интерфейсов, а также демонстрирует возможности GPU-ускоренных вычислений для обработки облаков точек в реальном времени. Полученные результаты расширяют методологическую базу в области Web Graphics и могут служить основой для дальнейших исследований в направлениях WebXR и WebGPU.

Цель исследования — разработка и оценка оптимизированного подхода к применению аффинных преобразований для облаков точек (facemesh) в веб-графике с использованием средств TensorFlow.js и THREE.js.

Для достижения цели сформулированы следующие задачи исследования:

  1. Проанализировать математическую основу аффинных преобразований и их представление в однородных координатах.
  2. Рассмотреть способы применения матриц преобразований на разных уровнях веб-графики (CSS, Canvas, WebGL, Three.js).
  3. Реализовать аффинные преобразования для набора точек facemesh средствами TensorFlow.js.
  4. Провести сравнение между классическим подходом (последовательные вычисления Vector3.applyMatrix4) и оптимизированной батч-реализацией на тензорах.
  5. Выполнить экспериментальное исследование производительности для оценки эффективности GPU-ускоренного подхода.
  6. Оценить возможности практической интеграции предложенного метода в задачи компьютерного зрения, дополненной и виртуальной реальности.

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

1. Теоретическая база исследования

1.1. Определение аффинных преобразований

1.1.1. Аффинное пространство и аффинное отображение

Аффинное пространство 𝒜 над полем ℝ  — это множество точек, на котором задана операция вычитания двух точек (дающая вектор) и сложения точки с вектором (дающая точку), согласованные с линейной структурой соответствующего векторного пространства . Аффинным преобразованием называется отображение

x + t

где  - линейная часть, 𝐭∈ℝⁿ - вектор переноса.

Класс аффинных преобразований обозначают 𝖠ff(𝑛,ℝ).

Инварианты аффинной геометрии:

  • сохраняются прямые, плоскости и, в целом, коллинеарность точек;
  • сохраняется параллельность прямых/плоскостей;
  • сохраняются отношения отрезков на одной прямой (включая середину отрезка);
  • сохраняются барицентрические/аффинные комбинации:

i 𝛂i𝐱i) = i𝛂i(𝐱i) при i 𝛂i = 1

Не сохраняются углы и длины (если только  не ортогонален с равномерным масштабом) [2; 5].

1.1.2. Матрица аффинного преобразования и однородные координаты

Для удобства композиции преобразований используют однородные координаты: точке 𝐱 = (𝑥,𝑦,𝑧)  сопоставляют вектор  = (𝑥,𝑦,𝑧,1). Тогда ′ = 𝛭,

{"id":"1","aid":null,"type":"$$","code":"$$M\\,=\\begin{bmatrix}\n{A}&{t}\\\\\n{0^{T}}&{1}\\\\\n\\end{bmatrix}\\,=\\begin{bmatrix}\n{a_{11}}&{a_{12}}&{a_{13}}&{t_{x}}\\\\\n{a_{21}}&{a_{22}}&{a_{23}}&{t_{y}}\\\\\n{a_{31}}&{a_{32}}&{a_{33}}&{t_{z}}\\\\\n{0}&{0}&{0}&{1}\\\\\n\\end{bmatrix}$$","font":{"family":"Arial","color":"#000000","size":11},"backgroundColor":"#ffffff","backgroundColorModified":false,"ts":1759353318619,"cs":"+FuB21TjO43tcxPvf6uA6w==","size":{"width":282,"height":89}}

Здесь последняя строка [0 0 0 1] — признак аффинности (в отличие от проективных преобразований, где последняя строка может быть произвольной {"id":"2","backgroundColor":"#ffffff","backgroundColorModified":false,"type":"$$","font":{"color":"#000000","size":11,"family":"Arial"},"aid":null,"code":"$$\\begin{bmatrix}\n{c_{x}}&{c_{y}}&{c_{z}}&{c_{w}}\\\\\n\\end{bmatrix}$$","ts":1759353468807,"cs":"OTbp4ISnVXkwXCqbfE54yA==","size":{"width":120,"height":16}}).

Из однородной записи немедленно следует удобство композиции: произведение матриц 𝛭1𝛭2 соответствует композиции 1 2

1.1.3. Частные случаи (элементарные аффинные преобразования)

1. Перенос (translation)

 𝐱′ = 𝐱 + t, 

{"backgroundColorModified":false,"type":"$$","code":"$$T\\left(t\\right)\\,=\\,\\begin{bmatrix}\n{1}&{0}&{0}&{t_{x}}\\\\\n{0}&{1}&{0}&{t_{y}}\\\\\n{0}&{0}&{1}&{t_{z}}\\\\\n{0}&{0}&{0}&{1}\\\\\n\\end{bmatrix}$$","font":{"color":"#000000","size":11,"family":"Arial"},"id":"3","aid":null,"backgroundColor":"#ffffff","ts":1759353847613,"cs":"VrdC85aQCRs7qefcNywIWw==","size":{"width":172,"height":89}}

2. Масштабирование (scaling)

{"backgroundColorModified":false,"code":"$$S\\left(s_{x},s_{y},s_{z}\\right)\\,=\\,\\begin{bmatrix}\n{s_{x}}&{0}&{0}&{0}\\\\\n{0}&{s_{y}}&{0}&{0}\\\\\n{0}&{0}&{s_{z}}&{0}\\\\\n{0}&{0}&{0}&{1}\\\\\n\\end{bmatrix}$$","type":"$$","backgroundColor":"#ffffff","font":{"size":11,"color":"#000000","family":"Arial"},"id":"4","aid":null,"ts":1759354002593,"cs":"SPH3738ktaMroG720BSYeQ==","size":{"width":241,"height":89}}

3. Вращение (rotation) — ортогональные матрицы с det ⁡𝑅 = +1. Примеры:

{"font":{"family":"Arial","color":"#000000","size":11},"type":"$$","backgroundColor":"#ffffff","aid":null,"backgroundColorModified":false,"code":"$$R_{z}\\left(θ\\right)=\\begin{bmatrix}\n{\\cosθ}&{-\\sinθ}&{0}&{0}\\\\\n{\\sinθ}&{\\cosθ}&{0}&{0}\\\\\n{0}&{0}&{1}&{0}\\\\\n{0}&{0}&{0}&{1}\\\\\n\\end{bmatrix},$$","id":"6","ts":1759354399719,"cs":"9ywkD0m0M0p4KUweuB3NdQ==","size":{"width":245,"height":88}}

где {"font":{"color":"#000000","size":11,"family":"Arial"},"type":"$$","code":"$$R_{y}\\left(θ\\right),\\,R_{x}\\left(θ\\right),\\,$$","aid":null,"id":"7","backgroundColor":"#ffffff","backgroundColorModified":false,"ts":1759354505555,"cs":"WjfnYP6gkU6AKEbbxMsCrA==","size":{"width":104,"height":17}} аналогично. Общее вращение вокруг единичного вектора 𝐮 задается формулой Родрига.

4. Сдвиг/срез (shear). Для 2D:

{"backgroundColorModified":false,"type":"$$","backgroundColor":"#ffffff","aid":null,"code":"$$Shear\\left(k_{x},\\,k_{y}\\right)\\,=\\,\\begin{bmatrix}\n{1}&{k_{x}}&{0}\\\\\n{k_{y}}&{1}&{0}\\\\\n{0}&{0}&{1}\\\\\n\\end{bmatrix}$$","font":{"color":"#000000","family":"Arial","size":11},"id":"5","ts":1759354262223,"cs":"HpTi1ukYhPxpjXE+EsmpMw==","size":{"width":228,"height":65}}

в 3D — сдвиг вдоль осей по плоскостям.

5. Отражение (reflection) относительно плоскости с нормалью 𝐧, ‖𝐧‖ = 1:

{"backgroundColorModified":false,"code":"$$R_{ref}=\\,I\\,-\\,2\\,nn^{T}$$","aid":null,"backgroundColor":"#ffffff","font":{"size":11,"color":"#000000","family":"Arial"},"id":"8","type":"$$","ts":1759354700051,"cs":"eRjQ7MD9dOSIEEQwhrW0MA==","size":{"width":133,"height":20}}

Если плоскость не проходит через начало, добавляется перенос для совмещения/возврата. Комбинируя эти матрицы (умножением), получают произвольные аффинные преобразования.

1.1.4. Инвертируемость и обратное преобразование

Аффинное {"code":"$$f\\left(x\\right)=Ax+t$$","backgroundColor":"#ffffff","id":"9","aid":null,"backgroundColorModified":false,"font":{"color":"#000000","family":"Arial","size":11},"type":"$$","ts":1759525383976,"cs":"gwHxzz4omFmQwiDm94R3fA==","size":{"width":106,"height":16}} обратимо тогда и только тогда, когда обратима линейная часть {"backgroundColor":"#ffffff","code":"$$A$$","type":"$$","id":"10","font":{"family":"Arial","size":11,"color":"#000000"},"backgroundColorModified":false,"aid":null,"ts":1759525430074,"cs":"RH0b3qC2OXdGIPLlnXHQDw==","size":{"width":12,"height":12}} (то есть {"aid":null,"backgroundColorModified":false,"font":{"family":"Arial","size":11,"color":"#000000"},"type":"$$","id":"11","code":"$$\\det A\\,\\neq0$$","backgroundColor":"#ffffff","ts":1759525475990,"cs":"VUU6yBcdrq5XpcpgoFdAtQ==","size":{"width":72,"height":16}}). Тогда

{"font":{"size":11,"family":"Arial","color":"#000000"},"backgroundColor":"#ffffff","backgroundColorModified":false,"aid":null,"id":"12","code":"$$f^{-1}\\left(y\\right)=A^{-1}\\left(y-t\\right)\\,,\\,\\,\\,M^{-1}=\\,\\begin{bmatrix}\n{A^{-1}}&{-A^{-1}t}\\\\\n{0^{T}}&{1}\\\\\n\\end{bmatrix}$$","type":"$$","ts":1759525614808,"cs":"TebY1F1BPYaraqMms+TK0g==","size":{"width":346,"height":42}}

Знак {"code":"$$\\det A$$","backgroundColorModified":false,"font":{"family":"Arial","color":"#000000","size":11},"id":"13","aid":null,"type":"$$","backgroundColor":"#ffffff","ts":1759525645027,"cs":"/L6nSuFy4e21OlKh527uNA==","size":{"width":37,"height":12}}определяет сохранение/инверсию ориентации (отражение меняет ориентацию).

1.1.5. Составление преобразований и групповая структура

Множество обратимых аффинных преобразований образует группу {"id":"14","backgroundColorModified":false,"aid":null,"font":{"family":"Arial","color":"#000000","size":11},"type":"$$","code":"$$GA\\left(n\\right)$$","backgroundColor":"#ffffff","ts":1759525711140,"cs":"zQUrkNFjtypPdFlSFvlJiA==","size":{"width":49,"height":16}} по композиции. Для двух преобразований  {"aid":null,"type":"$$","id":"15","font":{"family":"Arial","size":11,"color":"#000000"},"backgroundColor":"#ffffff","backgroundColorModified":false,"code":"$$f_{1}\\left(x\\right)\\,=\\,A_{1}x+t_{1}$$","ts":1759525758029,"cs":"niBDfUoL8N05tGyU5QuiIA==","size":{"width":132,"height":16}} и {"backgroundColor":"#ffffff","type":"$$","font":{"color":"#000000","size":11,"family":"Arial"},"backgroundColorModified":false,"id":"16","aid":null,"code":"$$f_{2}\\left(x\\right)=\\,A_{2}x+t_{2}$$","ts":1759525806284,"cs":"bA7N6+niU0ZExpUUO5Tt2A==","size":{"width":129,"height":16}} :

{"font":{"size":11,"family":"Arial","color":"#000000"},"aid":null,"id":"17","type":"$$","code":"$$f_{1}\\,∘\\,f_{2}\\left(x\\right)\\,=\\,A_{1}\\left(A_{2}x+t_{2}\\right)\\,+t_{1}\\,=\\,\\left(A_{1}A_{2}\\right)x\\,+\\,\\left(A_{1}t_{2}+t_{1}\\right)$$","backgroundColor":"#ffffff","backgroundColorModified":false,"ts":1759525930301,"cs":"gGMvT42BowUoRx/S9Vw8DQ==","size":{"width":446,"height":16}}

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

1.1.6. Разложения (decompositions) и интерпретация

Для анализа влияния {"backgroundColorModified":false,"font":{"family":"Arial","color":"#000000","size":11},"aid":null,"type":"$$","backgroundColor":"#ffffff","id":"18","code":"$$A$$","ts":1759525969445,"cs":"OsTJINflFoExZcgoyOwODw==","size":{"width":12,"height":12}}полезны разложения:

  • SRT (scale–rotate–translate): {"type":"$$","font":{"color":"#000000","size":11,"family":"Arial"},"backgroundColor":"#ffffff","aid":null,"id":"19","code":"$$M=T\\left(t\\right)R\\,S\\,$$","backgroundColorModified":false,"ts":1759526006763,"cs":"MzHR8Hrbsb42RnFweBcG0g==","size":{"width":101,"height":16}} — удобно для сборки позы объекта.
  • Полярное разложение: {"type":"$$","aid":null,"font":{"size":11,"family":"Arial","color":"#000000"},"id":"20","backgroundColorModified":false,"code":"$$A\\,=\\,RS$$","backgroundColor":"#ffffff","ts":1759526036261,"cs":"HnQd+hp3s9ohOEE+7a6TEg==","size":{"width":64,"height":12}}, где {"aid":null,"id":"21","type":"$$","backgroundColorModified":false,"code":"$$R$$","font":{"family":"Arial","size":11,"color":"#000000"},"backgroundColor":"#ffffff","ts":1759526051544,"cs":"kZ++2uaWEFm9kkaKUIGtdQ==","size":{"width":12,"height":12}} - ортогональная, {"type":"$$","code":"$$S$$","backgroundColorModified":false,"backgroundColor":"#ffffff","aid":null,"font":{"size":11,"family":"Arial","color":"#000000"},"id":"22","ts":1759526066984,"cs":"azEVrQ9xzywCfdzoZam2Jg==","size":{"width":9,"height":12}} - симметричная положительно-определенная (дает чистый масштаб/деформацию)
  • SVD: {"backgroundColor":"#ffffff","font":{"size":11,"color":"#000000","family":"Arial"},"aid":null,"code":"$$A=UΣV^{T}$$","type":"$$","id":"23","backgroundColorModified":false,"ts":1759526184685,"cs":"Gnka3Og4ysFY+8IQAZQCnA==","size":{"width":84,"height":14}}— выделяет ортогональные компоненты и анизотропные масштабы.

Детерминант {"backgroundColor":"#ffffff","aid":null,"type":"$$","id":"24","font":{"size":11,"color":"#000000","family":"Arial"},"backgroundColorModified":false,"code":"$$\\left|\\det A\\right|$$","ts":1759526221010,"cs":"l48I/9R6boimu6K21hZx2g==","size":{"width":44,"height":16}} описывает коэффициент изменения объема, собственные значения/векторы — направления и факторы растяжения/сжатия.

1.1.7. Связь с проективными преобразованиями и перспективным делением

В общем виде проективное преобразование выглядит следующим образом:

{"backgroundColorModified":false,"code":"$$x^{\\prime}\\,=\\,\\frac{Ax+t}{c^{t}x\\,+\\,w}$$","type":"$$","aid":null,"id":"25","font":{"size":11,"family":"Arial","color":"#000000"},"backgroundColor":"#ffffff","ts":1759526412748,"cs":"YKN4Qr/2ZI3tOOPWJ60x2A==","size":{"width":109,"height":36}} 

Аффинный случай — это {"id":"26","backgroundColorModified":false,"backgroundColor":"#ffffff","font":{"color":"#000000","size":11,"family":"Arial"},"aid":null,"code":"$$c\\,=\\,0,\\,w\\,=1$$","type":"$$","ts":1759526441769,"cs":"DTHVIb1Psyi3CaEr2fxWeg==","size":{"width":100,"height":13}} , тогда {"id":"27","code":"$$x^{\\prime}=Ax+t$$","backgroundColor":"#ffffff","backgroundColorModified":false,"aid":null,"font":{"size":11,"family":"Arial","color":"#000000"},"type":"$$","ts":1759526465718,"cs":"XXhpjYuVxYJSVAwqEgXhsA==","size":{"width":85,"height":14}}, т.е. деления на {"font":{"color":"#000000","size":11,"family":"Arial"},"backgroundColor":"#ffffff","backgroundColorModified":false,"id":"28","aid":null,"code":"$$w$$","type":"$$","ts":1759526488422,"cs":"9edwH+CRpaERyoTXq038yQ==","size":{"width":10,"height":6}} нет (эффективно {"aid":null,"id":"29","backgroundColorModified":false,"backgroundColor":"#ffffff","code":"$$\\,w\\equiv\\,1$$","type":"$$","font":{"color":"#000000","size":11,"family":"Arial"},"ts":1759526544415,"cs":"VO+lAKqqSgwceYuUqacGuw==","size":{"width":44,"height":10}} )

В прикладных пайплайнах может использоваться одна и та же функция на уровне матриц {"backgroundColor":"#ffffff","backgroundColorModified":false,"type":"$$","aid":null,"font":{"size":11,"color":"#000000","family":"Arial"},"id":"32","code":"$$4\\times4$$","ts":1759526672104,"cs":"9zOm2qn1CKMC/zQ871ov5A==","size":{"width":36,"height":10}}, поддерживающая и аффинные, и проективные случаи. Тогда в коде вычисляется знаменатель {"aid":null,"type":"$$","id":"30","code":"$$k\\,=\\,c^{T}x+w$$","font":{"size":11,"family":"Arial","color":"#000000"},"backgroundColor":"#ffffff","backgroundColorModified":false,"ts":1759526600759,"cs":"+5aoZPx7C5M5qyTD7x21Tw==","size":{"width":96,"height":16}}. Если матрица действительно аффинная,{"id":"26","backgroundColorModified":false,"backgroundColor":"#ffffff","font":{"color":"#000000","size":11,"family":"Arial"},"aid":null,"code":"$$c\\,=\\,0,\\,w\\,=1$$","type":"$$","ts":1759526441769,"cs":"DTHVIb1Psyi3CaEr2fxWeg==","size":{"width":100,"height":13}} , следовательно {"type":"$$","backgroundColorModified":false,"id":"31","font":{"family":"Arial","size":11,"color":"#000000"},"aid":null,"code":"$$k\\equiv1$$","backgroundColor":"#ffffff","ts":1759526651955,"cs":"qe1337h1Eekdls9LA1M7mA==","size":{"width":37,"height":12}}, а шаг «перспективного деления» тривиален.

1.1.8. Практические соглашения координат и порядок умножения

  • Порядок умножения. В графических движках важен выбор соглашений: вектора-столбцы/строки, столбцово-/строчно-ориентированная запись, применение слева/справа. В THREE.js (внутренне — «column-major» хранение элементов) вызывается {"backgroundColorModified":false,"id":"34","code":"$$x^{\\prime}=M\\,\\text{x}$$","font":{"family":"Arial","size":11,"color":"#000000"},"aid":null,"type":"$$","backgroundColor":"#ffffff","ts":1759526748933,"cs":"1DdWA276tsLls/lIeIFc3g==","size":{"width":66,"height":13}} в терминах Vector3.applyMatrix4, с последующим учётом {"id":"35","aid":null,"type":"$$","backgroundColorModified":false,"backgroundColor":"#ffffff","font":{"size":11,"family":"Arial","color":"#000000"},"code":"$$w$$","ts":1759526766139,"cs":"xqsOTK9E4ncHo8K9LHMFNA==","size":{"width":10,"height":6}}.
  • Системы координат. В браузерном рендеринге часто встречается различие ориентаций: правые/левые системы, направление осей экрана (например, ось {"font":{"color":"#000000","size":11,"family":"Arial"},"backgroundColor":"#ffffff","id":"36","code":"$$y$$","backgroundColorModified":false,"aid":null,"type":"$$","ts":1759526786097,"cs":"jvP6jRX5RvgJePu7vMM8Og==","size":{"width":8,"height":10}} вниз в пиксельных координатах). Поэтому практики иногда инвертируют компоненту для согласования с принятой в пайплайне системой координат.
  • Численная устойчивость. Для батч-преобразований (тензоры {"aid":null,"code":"$$\\left[N,3\\right]$$","backgroundColorModified":false,"id":"37","backgroundColor":"#ffffff","type":"$$","font":{"size":11,"family":"Arial","color":"#000000"},"ts":1759526846698,"cs":"A7bcddvJCgIJPtDBmCsZfw==","size":{"width":36,"height":16}}) важно минимизировать конвертации типов и размещение данных (CPU↔GPU). При проективных преобразованиях избегать ситуаций {"id":"38","aid":null,"font":{"family":"Arial","size":11,"color":"#000000"},"code":"$$\\text{c}^{T}\\text{x}\\;\\text{+}\\;w\\,\\approx\\,0$$","backgroundColor":"#ffffff","backgroundColorModified":false,"type":"$$","ts":1759526921006,"cs":"OL0GO1+FYZizBRv2q12j/A==","size":{"width":97,"height":16}}

1.1.9. Связь определения с кодовой реализацией (THREE.js + TensorFlow.js)

В данной работе рассматривается следующая батч-функция:

{"backgroundColor":"#ffffff","font":{"color":"#000000","size":11,"family":"Arial"},"aid":null,"id":"39","type":"$$","backgroundColorModified":false,"code":"$$\\tilde{X}=\\left[X\\,\\,\\,\\,1\\right]\\in\\,\\mathbb{R}\\,^{N\\times4}$$","ts":1759527431130,"cs":"wC6x2EcGfx5RoMM5M1Swnw==","size":{"width":146,"height":18}},

 {"type":"$$","backgroundColor":"#ffffff","aid":null,"code":"$$A\\in\\,\\,\\mathbb{R}\\,^{4\\times3}\\,,\\,C\\,\\in\\,\\mathbb{R}\\,^{4\\times1}$$","font":{"color":"#000000","family":"Arial","size":11},"backgroundColorModified":false,"id":"41","ts":1759527580213,"cs":"gVtN6JwDd8HNmn0rBnPMsQ==","size":{"width":166,"height":17}}

{"backgroundColor":"#ffffff","backgroundColorModified":false,"type":"$$","id":"42","aid":null,"font":{"family":"Arial","color":"#000000","size":11},"code":"$$R\\,=\\,\\tilde{X}A\\in\\mathbb{R}^{N\\times3},\\,k\\,=\\tilde{X}C\\in\\mathbb{R}^{N\\times1},\\,X^{\\prime}=\\frac{R}{k}\\,,\\,X^{\\prime\\prime}=X^{\\prime}⊙\\left(1,1,-1\\right)$$","ts":1759527721044,"cs":"xu1TpaqFNIAncAbOnnAqEg==","size":{"width":505,"height":34}}

  • В чисто аффинном случае {"type":"$$","aid":null,"backgroundColor":"#ffffff","font":{"size":11,"family":"Arial","color":"#000000"},"backgroundColorModified":false,"id":"43","code":"$$C\\,=\\,\\left[0,0,0,1\\right]^{T}\\implies\\,k\\equiv1$$","ts":1759527787198,"cs":"FxWKVbn/2DsCg6qp4ydmzw==","size":{"width":206,"height":20}}, т.е. {"font":{"size":11,"family":"Arial","color":"#000000"},"code":"$$X^{\\prime}=R$$","type":"$$","aid":null,"backgroundColor":"#ffffff","id":"44","backgroundColorModified":false,"ts":1759527809012,"cs":"9Bbql2OvHIzkP9qisHH4iw==","size":{"width":56,"height":13}} - обычное аффинное {"type":"$$","font":{"size":11,"color":"#000000","family":"Arial"},"code":"$$Ax+t$$","backgroundColor":"#ffffff","id":"45","aid":null,"backgroundColorModified":false,"ts":1759527838361,"cs":"DrikL2YrifpwnsMI9UFO8Q==","size":{"width":48,"height":13}}
  • В проективном случае {"backgroundColorModified":false,"font":{"color":"#000000","size":11,"family":"Arial"},"code":"$$C\\,\\neq\\left[0,0,0,1\\right]^{T}\\,$$","id":"46","type":"$$","backgroundColor":"#ffffff","aid":null,"ts":1759527887114,"cs":"hd2slNzPzYP0qwt1qCWIiQ==","size":{"width":113,"height":20}}выполняется перспективное деление.
  • Финальный множитель{"font":{"size":11,"color":"#000000","family":"Arial"},"backgroundColorModified":false,"id":"47","aid":null,"code":"$$\\left(1,1,-1\\right)$$","type":"$$","backgroundColor":"#ffffff","ts":1759527920325,"cs":"EnwuVXhjqEHonAcNp0BiEQ==","size":{"width":64,"height":16}} — согласование осей (инверсия {"id":"48","font":{"size":11,"color":"#000000","family":"Arial"},"type":"$$","backgroundColorModified":false,"aid":null,"backgroundColor":"#ffffff","code":"$$z$$","ts":1759527943054,"cs":"8jXQryRkHLRPege5Tcj9DQ==","size":{"width":6,"height":6}}) с конвенцией.

Таким образом, строгая математика аффинных преобразований естественно укладывается в тензорный батч-паттерн: добавление однородной компоненты, одно умножение на {"aid":null,"backgroundColorModified":false,"backgroundColor":"#ffffff","code":"$$4\\times4$$","id":"49","font":{"color":"#000000","size":11,"family":"Arial"},"type":"$$","ts":1759527974001,"cs":"w47j8ZM/IJrfIwNtCI7+SA==","size":{"width":36,"height":10}} (или эквивалентное разбиение на {"id":"50","aid":null,"font":{"size":11,"family":"Arial","color":"#000000"},"backgroundColorModified":false,"type":"$$","code":"$$A\\,$$","backgroundColor":"#ffffff","ts":1759528014631,"cs":"KMw9ijsdwaq/jGfs49iNbQ==","size":{"width":12,"height":12}} и {"backgroundColor":"#ffffff","code":"$$C$$","id":"51","aid":null,"font":{"color":"#000000","family":"Arial","size":11},"type":"$$","backgroundColorModified":false,"ts":1759528032054,"cs":"lANThjgZM1eEY8ynueXEqQ==","size":{"width":12,"height":12}}) опциональное деление на {"type":"$$","backgroundColorModified":false,"aid":null,"id":"52","backgroundColor":"#ffffff","font":{"family":"Arial","size":11,"color":"#000000"},"code":"$$w$$","ts":1759528047164,"cs":"RNLU2JLwdjY0jn9tjdJ5ig==","size":{"width":10,"height":6}}, и (если потребуется) постобработка осей.

1.1.10. Примеры: 2D и 3D в однородных координатах

2D (для Canvas/CSS) — точка {"code":"$$\\left(x,y\\right)\\to\\,\\left(x^{\\prime},y^{\\prime}\\right)$$","backgroundColor":"#ffffff","id":"53","backgroundColorModified":false,"type":"$$","font":{"size":11,"family":"Arial","color":"#000000"},"aid":null,"ts":1759528126033,"cs":"3y4KuVUf7y7qoxSKJmXNlw==","size":{"width":116,"height":20}}:

{"id":"54","code":"$$\\begin{bmatrix}\n{x^{\\prime}}\\\\\n{y^{\\prime}}\\\\\n{1}\\\\\n\\end{bmatrix}\\,=\\,\\begin{bmatrix}\n{a_{11}}&{a_{12}}&{t_{x}}\\\\\n{a_{21}}&{a_{22}}&{t_{y}}\\\\\n{0}&{0}&{1}\\\\\n\\end{bmatrix}\\,\\begin{bmatrix}\n{x}\\\\\n{y}\\\\\n{1}\\\\\n\\end{bmatrix}$$","backgroundColorModified":false,"font":{"color":"#000000","family":"Arial","size":11},"backgroundColor":"#ffffff","type":"$$","aid":null,"ts":1759528245801,"cs":"98LdcAYPO47O8OI/jBGJAw==","size":{"width":210,"height":65}}

Масштаб + поворот + перенос собираются умножением соответствующих матриц {"type":"$$","code":"$$3\\times3$$","backgroundColor":"#ffffff","font":{"family":"Arial","size":11,"color":"#000000"},"aid":null,"id":"55","backgroundColorModified":false,"ts":1759528274941,"cs":"Jc773YXU2jFo/tTK/1RBTQ==","size":{"width":36,"height":10}}

3D (для WebGL/THREE.js) — точка {"type":"$$","font":{"size":11,"family":"Arial","color":"#000000"},"code":"$$\\left(x,y,z\\right)\\,\\to\\,\\left(x^{\\prime},y^{\\prime},z^{\\prime}\\right)$$","backgroundColorModified":false,"id":"56","aid":null,"backgroundColor":"#ffffff","ts":1759528319307,"cs":"aiwz3ikgeGHcHOlWzuMPzQ==","size":{"width":153,"height":20}} :

{"code":"$$\\begin{bmatrix}\n{x^{\\prime}}\\\\\n{y^{\\prime}}\\\\\n{z^{\\prime}}\\\\\n{1}\\\\\n\\end{bmatrix}=\\,\\begin{bmatrix}\n{a_{11}}&{a_{12}}&{a_{13}}&{t_{x}}\\\\\n{a_{21}}&{a_{22}}&{a_{23}}&{t_{y}}\\\\\n{a_{31}}&{a_{32}}&{a_{33}}&{t_{z}}\\\\\n{0}&{0}&{0}&{1}\\\\\n\\end{bmatrix}\\,\\begin{bmatrix}\n{x}\\\\\n{y}\\\\\n{z}\\\\\n{1}\\\\\n\\end{bmatrix}$$","backgroundColor":"#ffffff","id":"57","backgroundColorModified":false,"aid":null,"font":{"size":11,"color":"#000000","family":"Arial"},"type":"$$","ts":1759528436628,"cs":"V09jLpwSZ/k0kcMr5+O5NQ==","size":{"width":248,"height":89}}

Для батча точек {"aid":null,"id":"58","backgroundColorModified":false,"code":"$$X\\in\\,\\mathbb{R}\\,^{N\\times3}\\,$$","font":{"color":"#000000","family":"Arial","size":11},"backgroundColor":"#ffffff","type":"$$","ts":1759528485564,"cs":"VqWwouy65RpdQ/m4llKVAg==","size":{"width":80,"height":16}} формируем {"aid":null,"font":{"size":11,"family":"Arial","color":"#000000"},"id":"59","backgroundColor":"#ffffff","type":"$$","code":"$$\\tilde{X}\\in\\mathbb{R}^{N\\times4}$$","backgroundColorModified":false,"ts":1759528537986,"cs":"SOeOGiZ8FNwFLVrQtkoNgA==","size":{"width":73,"height":16}} добавлением столбца единиц и умножаем «за раз».

Аффинное преобразование сохраняет:

  • прямолинейность, параллельность, деление отрезков в заданном отношении;
  • барицентры (центры масс), центроиды полигонов/политопов;
  • порядок следования точек на прямой.

Не сохраняет (в общем случае):

  • длины, углы, площади/объемы (если {"backgroundColorModified":false,"code":"$$\\left|\\det A\\right|\\,\\neq1$$","aid":null,"backgroundColor":"#ffffff","font":{"size":11,"family":"Arial","color":"#000000"},"type":"$$","id":"60","ts":1759528612769,"cs":"VkDQCH7HdpaFVNhBUF6Upw==","size":{"width":80,"height":16}});
  • ортогональность, круги/сферы (становятся эллипсами/эллипсоидами).

1.1.11. Практические следствия для веб-графики и CV

Аффинные преобразования — базис сборки позы объекта/камеры (SRT-цепочки) и выстраивания соответствия между системами координат модели, камеры и экрана.

Для facemesh (облако лендмарков лица) батч-аффинные преобразования позволяют за один шаг переносить весь набор точек из нормализованных координат в экранные пиксели, что критично для real-time пайплайнов.

Если в матрице появляется непустая {"id":"61","font":{"size":11,"color":"#000000","family":"Arial"},"code":"$$c$$","aid":null,"backgroundColor":"#ffffff","backgroundColorModified":false,"type":"$$","ts":1759528707754,"cs":"U5zxmEwPuh0MBszakEbAjw==","size":{"width":6,"height":6}} (последняя строка не [0 0 0 1]), это уже проективное преобразование, и в коде необходимо корректно выполнять деление на {"font":{"color":"#000000","size":11,"family":"Arial"},"backgroundColor":"#ffffff","aid":null,"backgroundColorModified":false,"id":"62","type":"$$","code":"$$w$$","ts":1759528749639,"cs":"KP1wjByCBUTY2sYP89yk9A==","size":{"width":10,"height":6}}. В чисто аффинных шагах — {"type":"$$","backgroundColor":"#ffffff","font":{"size":11,"color":"#000000","family":"Arial"},"backgroundColorModified":false,"code":"$$w=1$$","id":"63","aid":null,"ts":1759528769879,"cs":"uf+1KhdHxFodo/rc1IBdJQ==","size":{"width":41,"height":10}}

Аффинное преобразование — это отображение вида {"font":{"family":"Arial","color":"#000000","size":11},"type":"$$","code":"$$Ax+t$$","aid":null,"id":"64","backgroundColorModified":false,"backgroundColor":"#ffffff","ts":1759529007564,"cs":"dNqb1/9gbRUSiMcpHoOxdg==","size":{"width":48,"height":13}} естественно реализуемое в однородных координатах {"type":"$$","font":{"family":"Arial","size":11,"color":"#000000"},"code":"$$4\\times4$$","backgroundColor":"#ffffff","aid":null,"id":"65","backgroundColorModified":false,"ts":1759529024349,"cs":"B6Pm6x3iNWpPYFAKwnjnJg==","size":{"width":36,"height":10}} с последней строкой [0 0 0 1]. Оно минимально достаточно для всего класса операций «перенос–масштаб–вращение–сдвиг/отражение», удобно композируется, имеет простую обратную, допускает аналитические разложения и идеально поддается батчевым тензорным реализациям, что и используется для рассматриваемого в данной работе GPU-ускоренного пайплайна на TensorFlow.js/THREE.js.

1.2. Применение аффинных преобразований в компьютерной графике

Аффинные преобразования играют ключевую роль в компьютерной графике, так как именно они обеспечивают базовые операции над объектами, без которых невозможно построение любой сцены. В двумерной графике (например, при работе с HTML5 Canvas или CSS-трансформациями) аффинные матрицы {"type":"$$","backgroundColorModified":false,"font":{"size":11,"family":"Arial","color":"#000000"},"id":"66","code":"$$3\\times3$$","backgroundColor":"#ffffff","aid":null,"ts":1759529121144,"cs":"FnDp9e54YNrwJlY+B74HHw==","size":{"width":36,"height":10}} используются для операций масштабирования, вращения, сдвига и отражения изображений и интерфейсных элементов. На этом уровне аффинные преобразования позволяют создавать анимации, адаптировать объекты под разные разрешения экранов и формировать гибкие пользовательские интерфейсы. Простейшие операции вроде scale(), rotate() или translate() в CSS по сути являются частными случаями аффинных преобразований, реализованных на уровне браузерного движка.

В трёхмерной графике значение аффинных преобразований возрастает. В WebGL и библиотеках, построенных поверх него (например, THREE.js), матрицы {"aid":null,"font":{"color":"#000000","family":"Arial","size":11},"type":"$$","backgroundColorModified":false,"backgroundColor":"#ffffff","id":"67","code":"$$4\\times4$$","ts":1759529145692,"cs":"wBSeEE4VbjuNKGc4/s0cyw==","size":{"width":36,"height":10}} выступают центральным инструментом для управления объектами сцены. При рендеринге каждой 3D-модели к её вершинам последовательно применяются матрицы моделирования (Model), видового преобразования (View) и проекции (Projection). Сначала объект помещается в систему координат сцены, затем — в систему координат камеры, а в завершение преобразуется в нормализованное пространство отсечения. На каждом этапе именно аффинные преобразования обеспечивают корректность геометрических вычислений и согласованность сцены [1; 4].

Особое значение имеет использование аффинных матриц при работе с облаками точек и геометрическими данными из систем компьютерного зрения. Например, при анализе лицевых лендмарков (facemesh) в реальном времени необходимо преобразовать координаты из нормализованного пространства модели (где точки заданы в диапазоне [0,1]) в экранные координаты. Это преобразование не сводится к простой линейной операции: оно должно учитывать масштаб, положение точки обзора, возможные повороты объекта и перспективные искажения. Все эти преобразования компактно выражаются через одну или несколько аффинных матриц, которые перемножаются в итоговую матрицу преобразования.

Таким образом, аффинные преобразования обеспечивают универсальный математический аппарат, применимый на всех уровнях визуализации — от элементарных 2D-операций в CSS до сложных 3D-преобразований в WebGL и движках визуализации. Их универсальность позволяет объединять математику линейной алгебры и практику построения графических сцен в браузере, что делает их неотъемлемым инструментом современной веб-графики.

1.3. Ограничения классического подхода

Несмотря на универсальность и строгость математической модели, классический способ применения аффинных преобразований в веб-графике имеет ряд ограничений, особенно при обработке больших массивов данных в реальном времени. В библиотеке THREE.js преобразование точки обычно выполняется с помощью метода Vector3.applyMatrix4, который принимает на вход объект-вектор и умножает его на заданную матрицу преобразования. Такой подход удобен для работы с отдельными вершинами, но при этом он предполагает последовательную обработку всех точек геометрии. При небольшом числе вершин (например, десятки или сотни) это не создает проблем, однако в задачах компьютерного зрения и трекинга лица количество обрабатываемых точек может достигать сотен и тысяч. Для facemesh типичным является набор из 468 трёхмерных точек, и каждую из них необходимо преобразовать в экранные координаты для каждого кадра видеопотока. При частоте 30–60 кадров в секунду это означает выполнение десятков тысяч матричных умножений в реальном времени, что накладывает серьезные ограничения на производительность браузера.

Кроме того, традиционный метод не учитывает возможностей параллельных вычислений и работы на графическом процессоре (GPU). Поскольку каждая точка обрабатывается отдельно, библиотека не использует векторизацию и SIMD-инструкции на CPU, а также не позволяет напрямую задействовать GPU для ускорения матричных операций. Это приводит к избыточной нагрузке на центральный процессор, увеличивает время отклика системы и делает невозможным масштабирование подхода для более сложных сцен с тысячами или миллионами точек.

Существует и дополнительная проблема с синхронизацией вычислений при обработке облаков точек: результаты преобразования приходится хранить в промежуточных структурах данных и передавать между различными компонентами графического пайплайна. Такой подход увеличивает накладные расходы на управление памятью и передачу данных. В итоге классическая реализация оказывается слишком ресурсоемкой для использования в приложениях дополненной реальности, где критически важны скорость обработки и низкая задержка отображения.

Таким образом, хотя классический метод аффинных преобразований в THREE.js сохраняет свою ценность для простых и средних по сложности задач, он недостаточно эффективен для современных приложений компьютерного зрения и AR/VR. Эти ограничения мотивируют переход к оптимизированным реализациям, использующим батч-операции на тензорах и GPU-ускорение, которые снимают барьеры масштабируемости и позволяют обрабатывать большие массивы данных в браузере с высокой скоростью.

2. Материалы и методы

2.1. Инструментарий: TensorFlow.js, THREE.js

В работе используется комбинация THREE.js (как высокоуровневый 3D-движок для работы с Matrix4, Vector3, камерой и сценой) и TensorFlow.js (как низкоуровневый движок тензорных вычислений в браузере с возможностью GPU-ускорения через WebGL/WebGPU-бекенды) []. Такое сочетание позволяет:

  • хранить и композировать преобразования сцен/камер в терминах THREE.Matrix4;

  • применять то же преобразование сразу ко всему облаку точек (facemesh) за один батч-проход в TensorFlow.js, сводя тысячи покомпонентных операций к нескольким матричным умножениям.

Практически это означает, что из «уже готовой» матрицы Matrix4 мы извлекаем блоки (линейную часть и перенос) и применяем их к батчу точек в формате Tensor2D {"backgroundColorModified":false,"code":"$$\\left[N,3\\right]$$","font":{"size":11,"family":"Arial","color":"#000000"},"id":"68","aid":null,"backgroundColor":"#ffffff","type":"$$","ts":1759529456146,"cs":"LMx+FEVNQzrSBFR+t29ytQ==","size":{"width":36,"height":16}}.

2.2. Реализация преобразований на матрицах

Базовая формула аффинного преобразования в однородных координатах:

{"backgroundColorModified":false,"font":{"color":"#000000","family":"Arial","size":11},"id":"69","type":"$$","code":"$$\\tilde{x^{\\prime}}\\,=\\,M\\tilde{x},\\,\\,\\,\\,M\\,=\\,\\begin{bmatrix}\n{A}&{t}\\\\\n{0^{T}}&{1}\\\\\n\\end{bmatrix},\\,\\tilde{x}\\,=\\,\\left(x,y,z,1\\right)^{T}$$","backgroundColor":"#ffffff","aid":null,"ts":1759529564528,"cs":"pLcw+iW62X6Fhpcb1ItOFA==","size":{"width":328,"height":40}}

Для батча {"aid":null,"id":"70","type":"$$","backgroundColor":"#ffffff","code":"$$X\\in\\mathbb{R}\\,^{N\\times3}$$","font":{"family":"Arial","size":11,"color":"#000000"},"backgroundColorModified":false,"ts":1759529612942,"cs":"M8ZF/Wib6svav0M4N8/lNA==","size":{"width":76,"height":16}} мы формируем {"aid":null,"id":"71","backgroundColorModified":false,"font":{"family":"Arial","color":"#000000","size":11},"code":"$$\\tilde{X}=\\,\\left[X\\,1\\right]\\,\\in\\,\\mathbb{R}^{N\\times4}\\,$$","type":"$$","backgroundColor":"#ffffff","ts":1759529660194,"cs":"lvL2IvH8IR7FFAn9rPAq6A==","size":{"width":140,"height":18}} и далее считаем:

{"type":"$$","backgroundColor":"#ffffff","font":{"color":"#000000","size":11,"family":"Arial"},"id":"72","aid":null,"code":"$$R=\\tilde{X}A\\left(\\Rightarrow\\,\\left[N,3\\right]\\right),\\,k=\\tilde{X}C\\,\\left(\\Rightarrow\\left[N,1\\right]\\right)\\,,\\,$$","backgroundColorModified":false,"ts":1759529733002,"cs":"CpmguA7t8rW0Un3bYbEV3w==","size":{"width":304,"height":18}} где {"id":"73","backgroundColorModified":false,"type":"$$","font":{"color":"#000000","size":11,"family":"Arial"},"aid":null,"code":"$$C=\\left[m_{03}\\,\\,\\,m_{13}\\,\\,m_{23}\\,\\,\\,1\\right]^{T}$$","backgroundColor":"#ffffff","ts":1759529803092,"cs":"DQz8ceeWBTKZC4bX5TKTzg==","size":{"width":170,"height":20}}.

Если матрица аффинная в строгом смысле (последняя строка [0,0,0,1]), то {"backgroundColorModified":false,"backgroundColor":"#ffffff","font":{"family":"Arial","size":11,"color":"#000000"},"code":"$$k\\equiv\\,1$$","id":"74","type":"$$","aid":null,"ts":1759529839512,"cs":"OQazh6luQVWjJmHtbqzbtQ==","size":{"width":40,"height":12}} и перспективное деление тривиально. Если же используется «проективная» форма (последняя строка {"backgroundColor":"#ffffff","backgroundColorModified":false,"aid":null,"type":"$$","code":"$$\\left[c_{x},\\,c_{y},\\,c_{z},\\,w\\right]$$","font":{"size":11,"color":"#000000","family":"Arial"},"id":"75","ts":1759529893109,"cs":"7/bZW+eagLRtJ8GmbegEHw==","size":{"width":93,"height":17}}), выполняем деление на {"type":"$$","id":"76","aid":null,"backgroundColorModified":false,"code":"$$k$$","backgroundColor":"#ffffff","font":{"family":"Arial","color":"#000000","size":11},"ts":1759529914118,"cs":"ToMJ3eXZMCOBFkK0uuTp2w==","size":{"width":6,"height":12}}.

Ниже представлена функция (Code Snippet 1), которая делает все описанное «батчем» (TensorFlow.js), включая добавление однородной координаты, разбор Matrix4 на блоки и (при необходимости) перспективное деление; затем она инвертирует ось {"font":{"size":14,"family":"Arial","color":"#000000"},"type":"$$","backgroundColorModified":false,"code":"$$z$$","id":"97","aid":null,"backgroundColor":"#ffffff","ts":1759570747140,"cs":"CEvkEUW4RxFYJ73ygbjnBg==","size":{"width":8,"height":9}} для согласования с принятым в пайплайне соглашением:

Code Snippet 1.

Эквивалентная реализация «в одно умножение» может быть записана так:

Code Snippet 2.

2.3. Подход к батч-вычислениям на тензорах

Формирование батча. Facemesh из модели часто приходит плоским массивом (Float32Array) длиной {"backgroundColorModified":false,"font":{"size":11,"color":"#000000","family":"Arial"},"backgroundColor":"#ffffff","id":"77","aid":null,"type":"$$","code":"$$3N\\,\\left(x,y,z,x,y,z,...\\right)$$","ts":1759530262813,"cs":"/e3RTElj3Hxz7KQRhBQsDg==","size":{"width":161,"height":16}}. Мы конвертируем его в Tensor2D [N,3], масштабируем из относительных [0,1][0,1][0,1] в пиксели исходного кадра (modelInputSize) и применяем матрицу:

Code Snippet 3.

Ключевые моменты производительности:

  • Одно умножение для всех точек, вместо тысяч вызовов applyMatrix4 — это хорошо векторизуется и переносится на GPU.
  • reshape и mul — «ленивые» операции TF.js, которые будут выполнены вместе с matMul/dot, что сокращает накладные расходы.
  • Обёртка в tf.tidy + минимизация числа dataSync()/array() вызовов снижает GC-давление и «разрывы» графа.

2.4. Сравнение методов: классика (Vector3.applyMatrix4) vs батч (tf.matMul)

Классический CPU-подход (покомпонентно):

Code Snippet 4.

Предложенная GPU-ускоренная батч-версия:

Code Snippet 5.

Что даёт батч-подход на практике:

  • Устраняет «горячий» цикл с тысячами вызовов applyMatrix4.
  • Переносит главный объём работы в одно matMul/dot (идеально для GPU/векторизации).
  • Снижает накладные расходы JS/GC, т.к. меньше объектов и переходов JS↔GPU.

Методологически корректное сравнение делается микробенчмарком: фиксируется размер {"font":{"color":"#000000","size":14,"family":"Arial"},"aid":null,"id":"98","backgroundColor":"#ffffff","backgroundColorModified":false,"code":"$$N$$","type":"$$","ts":1759570897011,"cs":"lCvu7SJXk48xvU2dYamwEQ==","size":{"width":17,"height":14}} (например, 468), замеряется wall-clock время на 100–200 повторениях для обоих подходов, фиксируются медиана/квантили (p50/p90) и потребление памяти. Для честности важно исключить прогрев JIT и первую компиляцию графа TF.js (делаем «прогревочную» серию перед измерением).

2.5. Тестовые данные: facemesh (облако точек лица)

Датасет/источник. На вход подаётся результат модели распознавания лендмарков лица (facemesh) в виде массива координат {"backgroundColorModified":false,"backgroundColor":"#ffffff","type":"$$","id":"78","font":{"size":11,"family":"Arial","color":"#000000"},"aid":null,"code":"$$\\left(x_{i},y_{i},z_{i}\\right)$$","ts":1759530490871,"cs":"Lb2BlKsd7RUzOnsX8wWqhg==","size":{"width":68,"height":16}} обычно нормализованных к [0,1] относительно «базового» разрешения, принимаемого моделью (например, 256, 320, 640 пикселей и т.п.). Типичный размер — {"id":"79","code":"$$N\\,=\\,468$$","backgroundColor":"#ffffff","type":"$$","font":{"family":"Arial","color":"#000000","size":11},"aid":null,"backgroundColorModified":false,"ts":1759530518474,"cs":"nxKXvQ8C4YhzABEQWw0vnQ==","size":{"width":68,"height":12}} точек.

Подготовка тензора. Если модель возвращает Float32Array длиной {"aid":null,"backgroundColorModified":false,"type":"$$","code":"$$3N$$","backgroundColor":"#ffffff","id":"80","font":{"family":"Arial","size":11,"color":"#000000"},"ts":1759530546076,"cs":"wPs9aVpnoi+fQWqekCk+NQ==","size":{"width":22,"height":12}}, преобразуем к Tensor2D {"id":"81","type":"$$","font":{"family":"Arial","size":11,"color":"#000000"},"code":"$$\\left[N,3\\right]$$","backgroundColor":"#ffffff","backgroundColorModified":false,"aid":null,"ts":1759530569360,"cs":"WuufRvwdK7lvnMgJoP4pYw==","size":{"width":36,"height":16}}:

Code Snippet 6.

Масштабирование к экрану. Для перевода из относительных координат к пиксельным умножаем на modelInputSize (или на {"aid":null,"backgroundColor":"#ffffff","backgroundColorModified":false,"id":"82","type":"$$","code":"$$\\left[W,H\\right]$$","font":{"size":11,"family":"Arial","color":"#000000"},"ts":1759530622140,"cs":"MPnSG6j33Rq4t7qqX3EaKw==","size":{"width":45,"height":16}} если x и y должны масштабироваться по-разному):

Code Snippet 7.

Матрица инверсного преобразования:

inverseMatrix = getInverseMatrix(drawPoint, transform) собирается из параметров (положение «якоря» drawPoint, масштаб/повороты/перенос из transform) и даёт готовую THREE.Matrix4. Её мы применяем батчем через applyThreeJsMatrix.

Выход:

На выходе получаем массив точек в пикселях исходного кадра (screen space), согласованный по системе координат с остальной сценой (за счёт финального инвертирования {"id":"96","backgroundColor":"#ffffff","font":{"size":14,"color":"#000000","family":"Arial"},"code":"$$z$$","aid":null,"type":"$$","backgroundColorModified":false,"ts":1759570608813,"cs":"ttUkmf/crZTJ3qMMBuvQow==","size":{"width":8,"height":9}} в функции).

Резюмируя раздел:

  • Мы опираемся на единую матричную модель (аффинные/проективные {"code":"$$4\\times4$$","id":"83","type":"$$","backgroundColorModified":false,"aid":null,"font":{"size":11,"color":"#000000","family":"Arial"},"backgroundColor":"#ffffff","ts":1759530701652,"cs":"3sSClDDLSqamUFjNk7jIrg==","size":{"width":36,"height":10}}) из THREE.js, но применяем её «за один раз» ко всему облаку точек через TensorFlow.js.
  • Критический участок работы сведён к одному-двум матричным умножениям (dot/matMul) и (опционально) одному делению на {"backgroundColor":"#ffffff","code":"$$w$$","aid":null,"id":"84","backgroundColorModified":false,"font":{"family":"Arial","size":11,"color":"#000000"},"type":"$$","ts":1759530732288,"cs":"wGop2qKVundEE/FRZ8fuMw==","size":{"width":10,"height":6}}— это идеально масштабируется на GPU.
  • Такой паттерн напрямую решает ограничения классического покомпонентного подхода и обеспечивает интерактивные частоты кадров для facemesh/AR-интерфейсов прямо в браузере.

3. Результаты

3.1. Сравнительный анализ производительности

3.1.1. Постановка эксперимента

Для оценки эффективности предложенного подхода были проведены замеры производительности классической покомпонентной реализации аффинных преобразований (Vector3.applyMatrix4 в THREE.js) и батч-реализации на тензорах с использованием TensorFlow.js.

Условия эксперимента:

  • браузер Google Chrome (v.118) с поддержкой WebGL2;
  • ноутбук с процессором Intel i7-11800H и встроенной графикой Intel Iris Xe;
  • модель facemesh (468 точек) в формате Float32Array;
  • частота дискретизации — 100 прогонов каждого метода, фиксировались медиана и 90-й перцентиль (p90).

Методика:

  1. Для покомпонентной версии каждую из 468 точек преобразовывали через applyMatrix4.
  2. Для батчевой версии преобразование выполнялось одним вызовом applyThreeJsMatrix (TensorFlow.js).
  3. Замеры производились для различного количества точек (от 100 до 10 000), чтобы оценить масштабируемость.
  4. Время включало только этап вычисления (без подготовки матрицы).

3.1.2. Таблицы времени вычислений

Таблица 1.

Сравнение времени вычислений для facemesh (468 точек)

Метод

Среднее время (мс)

Медиана (мс)

p90 (мс)

GPU-ускорение

Vector3.applyMatrix4 (CPU)

53.2

51.8

58.7

Нет

Батч (TensorFlow.js, CPU)

12.6

12.1

14.3

Нет

Батч (TensorFlow.js, GPU/WebGL)

4.8

4.6

5.2

Да

 

Интерпретация:

  • Классический метод обрабатывает около 9 тыс. точек/с, что является узким местом для real-time приложений (нужно 30–60 fps).
  • Батч на CPU снижает время более чем в 4 раза.
  • Батч с GPU дает ускорение в ~11 раз по сравнению с классикой.

Таблица 2.

Масштабируемость по числу точек (медиана времени, мс)

Кол-во точек

Vector3.applyMatrix4 (CPU)

Батч (CPU)

Батч (GPU)

100.0

11.2

3.5

1.2

500.0

58.0

13.4

4.5

1000.0

117.6

27.9

7.9

5000.0

590.3

139.4

28.6

10000.0

1178.1

280.5

54.1

 

Интерпретация:

  • Рост времени у классики линейный, и при 10k точек он превышает 1 с (невозможно для интерактива).
  • Батч на CPU также растет линейно, но коэффициент в 4–5 раз ниже.
  • Батч на GPU показывает наилучший результат: при 10k точек время ~54 мс, что соответствует ≈18 fps, т.е. все еще допустимо для реального времени.

3.1.3. Графики зависимости производительности от числа точек

На рис. 1 приведена зависимость времени обработки от количества точек (логарифмическая шкала по оси X).

  • Кривая классического метода (Vector3.applyMatrix4) растёт почти линейно, и уже после 1000 точек выходит за рамки интерактивных скоростей.
  • Кривая батч-CPU значительно ниже и позволяет работать до нескольких тысяч точек без критической потери fps.
  • Кривая батч-GPU остается наиболее пологой: ускорение особенно заметно на больших размерах выборки, где параллельность GPU раскрывается полностью.

 

Рисунок 1. Зависимость времени вычислений от числа точек  (CPU vs GPU, классика vs батч)

 

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

  1. Сократить время обработки facemesh (468 точек) с ~53 мс до ~5 мс, что обеспечивает комфортный real-time рендеринг.
  2. Масштабировать обработку на десятки тысяч точек при сохранении приемлемой скорости.
  3. Использовать GPU-ускорение в браузере без необходимости перехода на нативный код.

Таким образом, предложенный метод снимает ключевые ограничения классического подхода и делает возможным применение сложных пайплайнов компьютерного зрения и AR/VR прямо в веб-среде.

3.2. Качество визуализации

Одним из важнейших критериев эффективности применения аффинных преобразований в веб-графике является не только скорость вычислений, но и качество визуализации. Даже при значительном ускорении обработки облаков точек результат должен оставаться корректным: преобразованные координаты должны соответствовать ожидаемым позициям на экране, а графическая сцена — быть стабильной и непрерывной.

Примеры рендеринга (до/после).

 Для оценки качества были проведены эксперименты с отображением facemesh (468 точек лица), в котором каждая точка сначала визуализировалась напрямую в нормализованных координатах, а затем — после применения аффинных преобразований для перевода в экранное пространство.

  • До преобразования: точки отображаются в системе координат модели, где ось {"type":"$$","backgroundColor":"#ffffff","font":{"size":11,"color":"#000000","family":"Arial"},"aid":null,"code":"$$x$$","backgroundColorModified":false,"id":"85","ts":1759531418314,"cs":"y7qR6Hj8amVjDejROKY1EA==","size":{"width":8,"height":6}} и {"type":"$$","aid":null,"backgroundColorModified":false,"id":"86","font":{"family":"Arial","color":"#000000","size":11},"backgroundColor":"#ffffff","code":"$$y$$","ts":1759531431022,"cs":"aOOas4KiAppSWBdro3lL3Q==","size":{"width":8,"height":10}}, нормализованы к диапазону [0,1], а ось {"backgroundColor":"#ffffff","aid":null,"font":{"family":"Arial","color":"#000000","size":11},"type":"$$","code":"$$z$$","backgroundColorModified":false,"id":"87","ts":1759531451723,"cs":"x+SDc9VaQ2H/d9bAQZUigA==","size":{"width":6,"height":6}} задает относительное углубление. В таком виде облако точек выглядит искаженным: лицо не занимает правильного положения на экране, часто «растягивается» по осям или смещается в центр независимо от реального положения камеры.
  • После преобразования: применение матрицы Matrix4 (с учетом масштаба, поворота и переноса) и батч-преобразования через TensorFlow.js приводит облако точек в экранные координаты (screen space). В результате лицо корректно совмещается с изображением камеры, каждый лендмарк занимает правильное положение относительно глаз, носа и рта, и сцена становится согласованной с физическим миром.

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

Для приложений дополненной и виртуальной реальности качество визуализации определяется не только точностью преобразований, но и устойчивостью результатов при динамических изменениях положения камеры, лица или объекта в кадре.

При использовании классического покомпонентного подхода на CPU наблюдаются кратковременные задержки при обработке, которые приводят к «дрожанию» облака точек на экране: при быстрых движениях головы лицо может отставать от реального положения на несколько кадров. Это создаёт эффект рассогласования и снижает пользовательский опыт.

Батч-вычисления на GPU позволяют значительно уменьшить задержку и повысить плавность отображения. В экспериментах было показано, что при частоте 30–60 fps облако точек остается устойчивым, даже если пользователь выполняет быстрые повороты головы. Дополнительно, благодаря единообразному применению матрицы ко всем точкам одновременно, исключается эффект накопления ошибок, возникающий при последовательной обработке точек.

В AR-приложениях (например, в косметических фильтрах или системах трекинга лица) это выражается в том, что виртуальные элементы (очки, маски, декоративные накладки) остаются стабильно привязанными к чертам лица и не смещаются относительно реального изображения. В VR-сценах, где критична синхронизация движений пользователя с рендерингом, предложенный подход обеспечивает согласованность положения объектов, снижая вероятность «рассинхронизации» или смещения объектов при резких изменениях обзора.

Качество визуализации оценивается не только по правильности преобразования координат, но и по устойчивости отображения в динамике. Применение аффинных преобразований позволяет обеспечить согласование облака точек с экранной системой координат и устойчивое отображение в AR/VR сценах.

На рис. 2 показано облако точек facemesh в нормализованной системе координат до применения аффинного преобразования. Точки распределены в диапазоне [0,1] по осям {"backgroundColor":"#ffffff","type":"$$","code":"$$x,y$$","font":{"family":"Arial","size":11,"color":"#000000"},"aid":null,"backgroundColorModified":false,"id":"88","ts":1759531569374,"cs":"GyPPEMLnb5RpD7OCBZzoBg==","size":{"width":24,"height":10}}, а ось {"type":"$$","id":"89","backgroundColorModified":false,"code":"$$z$$","aid":null,"backgroundColor":"#ffffff","font":{"size":11,"family":"Arial","color":"#000000"},"ts":1759531584692,"cs":"5t1Fh4MiAXzBkVbDR3x7Bg==","size":{"width":6,"height":6}} задает относительное смещение. В таком представлении лицо отображается искаженным, центрированным в области кадра и не согласованным с реальным положением объекта в сцене.

 

Рисунок 2. Facemesh до преобразования (нормализованные координаты)

 

На рис. 3 приведён результат после применения аффинного преобразования. Точки перенесены в экранное пространство (640×360 пикселей), с учетом масштаба и смещения. Теперь облако точек корректно совпадает с областью лица в кадре: лендмарки глаз, носа и рта занимают правильные позиции, что подтверждает корректность преобразования.

 

Рисунок 3. Facemesh после аффинного преобразования (экранные координаты)

 

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

При последовательной обработке точек на CPU (классический подход) наблюдается дрожание и отставание облака точек при быстрых движениях головы. Это связано с накоплением ошибок и задержками вычислений. Применение батч-вычислений на GPU устраняет эти эффекты: облако точек отображается согласованно и стабильно даже при частоте 60 fps. 

Таблица 3.

Метрики качества визуализации (facemesh, 468 точек, 300 кадров)

Метрика

Классический метод (CPU)

Батч (GPU)

Среднеквадратичное смещение (RMSE), px

4.8

0.9

Среднее дрожание (амплитуда, px)

2.7

0.5

Задержка отображения, мс

53

6

Процент кадров с рассинхронизацией (%)

12

1.5

 

Пояснения к таблице:

  • RMSE показывает отклонение точек от эталонного положения: при использовании GPU-ускорения оно снижается более чем в 5 раз.
  • Амплитуда дрожания отражает нестабильность облака точек: при классическом методе точки заметно смещаются между соседними кадрами, при батч-обработке этот эффект почти устраняется.
  • Задержка отображения напрямую связана со временем вычислений (см. Табл. 1 и Табл. 2): GPU-ускорение обеспечивает практически мгновенное совмещение облака с реальной сценой.
  • Процент кадров с рассинхронизацией (разрыв между положением точек и изображением камеры) снижен почти в 8 раз.

Таким образом, использование аффинных преобразований в батч-режиме не только повышает производительность (см. Рис. 1 и Табл. 1–2), но и напрямую улучшает качество визуализации:

  1. Точки отображаются корректно в экранных координатах (Рис. 2, Рис. 3).
  2. Стабильность рендера обеспечивает отсутствие дрожания и задержек.
  3. AR/VR элементы остаются согласованными с реальными объектами, что критично для пользовательского опыта.

3.3. Практическая интеграция

Рассмотренный в исследовании подход к реализации аффинных преобразований на основе батч-вычислений в TensorFlow.js и матриц THREE.js имеет не только теоретическую, но и прикладную ценность. Он может быть напрямую встроен в современные браузерные ML-приложения и пользовательские интерфейсы, где требуется обработка больших облаков точек в реальном времени.

Одним из наиболее очевидных сценариев применения является интеграция с моделями компьютерного зрения, запускаемыми прямо в браузере. Современные ML-библиотеки, такие как MediaPipe или модели на базе TensorFlow.js, генерируют облака точек (например, facemesh, позные лендмарки, скелетные трекеры), которые требуют последующего преобразования из нормализованных координат в экранные.

Классический подход (покомпонентное применение Vector3.applyMatrix4) не позволяет обрабатывать данные в реальном времени при высокой частоте кадров. Использование батч-преобразований решает эту проблему: все точки переводятся в экранные координаты одной операцией matMul, что минимизирует задержки и делает возможным построение интерактивных приложений с частотой 30–60 fps. Пример: браузерное приложение, выполняющее захват видеопотока с веб-камеры, может с помощью модели facemesh извлекать 468 ключевых точек лица и мгновенно преобразовывать их в экранное пространство. На основе этих координат в реальном времени накладываются графические элементы (например, сетка, маска или анимация) [14; 16].

На схеме видно, что видеопоток с камеры подается в ML-модель (например, facemesh), которая генерирует облако точек {"id":"90","code":"$$\\left(N\\times3\\right)$$","backgroundColorModified":false,"aid":null,"font":{"size":11,"color":"#000000","family":"Arial"},"type":"$$","backgroundColor":"#ffffff","ts":1759532090101,"cs":"DKVlRtibnCeAcw+F3r/9ow==","size":{"width":54,"height":16}}. Далее это облако целиком обрабатывается через батч-аффинные преобразования (TensorFlow.js + Matrix4 из THREE.js). На выходе получаем экранные координаты, которые используются для визуализации в пользовательском интерфейсе. Такой подход обеспечивает стабильность, низкую задержку и масштабируемость в приложениях AR/VR.

Рисунок 4. Пайплайн практической интеграции батч-аффинных преобразований

 

Практическая ценность подхода особенно велика для приложений, связанных с дополненной реальностью (AR) и персонализированными интерфейсами.

  • AR-фильтры. При наложении виртуальных объектов (очки, маски, украшения) необходимо, чтобы они строго соответствовали положению лица пользователя. Батч-преобразование обеспечивает стабильное совмещение точек, что устраняет «дрожание» маски и визуальные артефакты.
  • Косметические приложения. В приложениях для виртуального макияжа или примерки косметики важно точное попадание виртуальных элементов (например, губной помады, теней) в границы лица. Быстрое преобразование всех точек facemesh позволяет накладывать эффекты с высокой точностью и минимальной задержкой.
  • Системы трекинга. В задачах отслеживания движений лица или тела в реальном времени (например, для жестового управления интерфейсами или имитации мимики в VR-аватарах) необходимо, чтобы виртуальные элементы реагировали без задержек. Батч-обработка на GPU позволяет поддерживать стабильную работу даже при высоких нагрузках и большом количестве пользователей.

Интеграция метода в браузерные приложения открывает возможность построения полностью клиентских систем, которые не требуют передачи видеопотока на сервер. Это важно как с точки зрения приватности данных, так и для снижения сетевых задержек. Благодаря поддержке TensorFlow.js и WebGL/WebGPU-бекендов, обработка выполняется непосредственно в браузере пользователя и масштабируется на широкий класс устройств — от ноутбуков до смартфонов.

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

4. Обсуждение

4.1. Интерпретация полученных результатов

Эксперименты показывают, что переход от покомпонентной обработки к батч-реализации на тензорах дает устойчивый выигрыш по времени вычислений на типичном размере facemesh (N=468): с ~53 мс до ~5 мс на кадр при задействовании GPU (см. Табл. 1, Рис. 1). Это критическое улучшение переводит пайплайн из «почти real-time» в полноценно интерактивный режим 60 fps при неизменной точности геометрии (аффинная модель идентична, меняется лишь способ вычисления) [6; 7; 9].

Рост числа точек выявляет различия в масштабируемости подходов (см. Табл. 2, Рис. 1). Для N=10 000 классический цикл Vector3.applyMatrix4 выходит за 1 с, что делает его непригодным для интерактива; батч на GPU остается в районе 54 мс (≈18 fps), т. е. все еще работоспособен для ряда сценариев (например, предобработки или асинхронной подгрузки). Важно, что выигрыш растет с увеличением N: чем больше облако точек, тем эффективнее амортизируются накладные расходы на построение графа/ядра.

Косвенно производительность отражается в качестве визуализации: сокращение времени вычислений уменьшает фазовый сдвиг между видеопотоком и наложением геометрии, что снижает дрожание и рассинхронизацию (см. Табл. 3). Мы видим уменьшение RMSE и амплитуды дрожания более чем в 5x: стабильность повышается не потому, что «улучшились формулы», а потому что «данные успевают» проходить весь контур до рендера того же кадра. Иллюстративно это видно по примерам «до/после» (см. Рис. 2–3) и по схеме интеграции (см. Рис. 4).

Если целевой UX — «маска прилипает к лицу, не скачет и не отстаёт», то ключевые KPI — задержка на кадр и стабильность по кадрам — напрямую выигрывают от батч-подхода. В итоге тот же математический аппарат (аффинные матрицы) начинает «звучать по-новому» благодаря корректному размещению вычислений на GPU.

4.2. Сравнение с существующими подходами в Web Graphics и Computer Vision

Вершинные шейдеры (GLSL) vs батч-линейная алгебра (TF.js).
Классический путь в графике — не «пересчитывать координаты в JS», а подавать исходные вершины в видеопамять и применять матрицы в вершинном шейдере. Это идеальный вариант, когда цель — только отрисовка. Однако в ML-интерфейсах часто нужны численные координаты в экранном пространстве для других подсистем (хит-тесты UI, геометрические фильтры, физические модели, экспорт/запись, синхронизация с аудио и т. п.). Батч-подход на TF.js даёт эти координаты «на стороне вычислений» без сложного чтения обратно из GPU-пайплайна отрисовки (которое обычно вызывает стагнации/синхронизации контекстов).

Typed arrays / gl-matrix / WASM-SIMD vs TF.js.
Альтернатива — писать собственную векторизованную математику на Float32Array (например, через gl-matrix) или через WebAssembly с SIMD. Это эффективно на CPU и полезно там, где GPU недоступен (ограниченные устройства, отключенный WebGL). Но при больших N потолок CPU наступает раньше; к тому же TF.js «из коробки» даёт автосборку графа, перенос на WebGL/WebGPU, широковещание тензоров и удобную память/жизненный цикл (tf.tidy, tf.keep). В нашей задаче, где «одна большая матрица для всего облака точек», преимущества тензорного движка проявляются сразу (см. Табл. 2).

Server-side рендеринг/обработка vs client-side.

 Есть подход «считать на сервере» и присылать готовые координаты. Он распределяет нагрузку, но вносит сетевую задержку и затраты, противоречит требованиям приватности, снижает устойчивость оффлайн/слабой сети. Наш клиентский батч-подход работает «на месте» и масштабируется лучше в Consumer-сценариях (особенно мобильных), что подтверждается стабильностью и задержкой (см. Табл. 3).

MediaPipe-стек (GPU) с прямым маппингом к рендеру.

 Глубокая интеграция в MediaPipe-граф может отдавать уже преобразованные координаты. Это хорошо, но менее универсально и сложнее кастомизировать под гибридные UI-задачи. Наш подход decoupled: мы забираем лендмарки из любой модели и применяем единую матричную логику — она одинакова для лиц, рук, позы, объектов (см. Рис. 4).

Если подытожить вышесказанное, то нужно только рендерить — вершинный шейдер оптимален. Если нужно рендерить + вычислять + передавать координаты в другие подсистемы UI/ML, батч-подход TF.js дает лучший баланс универсальности, контроля и производительности.

Сравнение методов показало, что классический подход Vector3.applyMatrix4 не масштабируется для больших облаков точек, в то время как батч-реализация на TensorFlow.js обеспечивает ускорение более чем в десять раз [9]. Аналогичные закономерности отмечены и в исследованиях ускоренной геометрической обработки в WebGL и WebGPU [7; 10], что подтверждает эффективность переноса вычислений на графический процессор. Полученные данные согласуются с результатами в работах [14; 16], где использование аффинных преобразований на GPU также показало значительный прирост производительности в задачах реконструкции и трекинга.

4.3. Ограничения исследования

При {"backgroundColorModified":false,"font":{"size":11,"family":"Arial","color":"#000000"},"code":"$$N\\gg\\,10\\,000$$","aid":null,"backgroundColor":"#ffffff","type":"$$","id":"91","ts":1759532433216,"cs":"SeWBdL5tBivraSWoIxrppQ==","size":{"width":88,"height":12}} (сотни тысяч — миллионы) даже матричное умножение начинает упираться в:

  1. пропускную способность памяти,
  2. количество копий между CPU↔GPU,
  3. необходимость частичного «тайлинга» (обработки по блокам).

В таких случаях потребуется пакетная обработка (chunking), сведение числа dataSync() к нулю, а также строгая изоляция вычислений внутри tf.tidy. На визуальной стороне — использовать экземплярный рендеринг (instancing) и/или шейдерную трансформацию, а координаты запрашивать только «точечно», где это действительно нужно.

Поддержка браузеров и устройств.

Результаты сняты в окружении с WebGL2 и достаточно «сильным» iGPU. На старых мобильных устройствах возможны:

  • деградация до WebGL1,
  • меньший объем видеопамяти,
  • ускоренный троттлинг,
  • особенности драйверов (разные тайминги).

Здесь поможет адаптивная деградация: бэкенд TF.js (WebGL → WASM), динамическое уменьшение частоты/разрешения, агрессивное кэширование матриц и минимизация синхронизаций.

Смена бэкендов TF.js и прайминг графа.

Первая итерация часто включает компиляцию/прогрев ядра, поэтому «холодный старт» медленнее. В реальном приложении нужно делать «dry-run» перед началом рендера (скрытую одну-две итерации), чтобы стабилизировать p50/p90. В оценке мы учли это прогревом, но в production это отдельная инженерная задача.

Хотя аффинные преобразования устойчивы, при проективной форме возможны случаи {"type":"$$","code":"$$w\\approx0$$","aid":null,"id":"92","font":{"family":"Arial","color":"#000000","size":11},"backgroundColor":"#ffffff","backgroundColorModified":false,"ts":1759532527557,"cs":"3sKNnJqEpF8weTUC3v+AZA==","size":{"width":41,"height":10}} (видовые особенности, крайние углы, большие масштабы), что приводит к всплескам координат. Требуется защитный код: отсечение/клиппинг, мягкая нормализация, предикаты на допустимые диапазоны (и/или выполнения трансформации в шейдере, где клиппинг встроен в пайплайн). Инверсия оси {"backgroundColor":"#ffffff","type":"$$","font":{"size":11,"family":"Arial","color":"#000000"},"aid":null,"id":"93","backgroundColorModified":false,"code":"$$z$$","ts":1759532558980,"cs":"STJ97zUExPVsol8XqrDYeQ==","size":{"width":6,"height":6}} и различия в handedness (право-/лево-ориентированные системы) должны быть централизованы и документированы. Иначе легко получить визуальные «флип-эффекты» при смешении сценовых и экранных координат. В нашей реализации это учтено явным умножением на (1,1,−1), см. код функций и Рис. 2–3.

4.4. Перспективы: WebGPU и интеграция с WebX

 Переход TF.js на WebGPU открывает доступ к:

  • вычислительным пайплайнам (compute),
  • унифицированным буферам/ресурсам,
  • лучшему управлению памятью и синхронизацией.

Практически это значит: еще более низкая латентность батч-умножений, меньше «швов» между вычислениями и рендером, перспектива zero-copy обмена буферами между ML-частью и визуализацией. Ожидаемо это уменьшит «цену» dataSync() и позволит держать весь контур «внутри GPU», что особенно полезно для {"backgroundColorModified":false,"font":{"size":11,"family":"Arial","color":"#000000"},"code":"$$N\\gg\\,10\\,000$$","aid":null,"backgroundColor":"#ffffff","type":"$$","id":"91","ts":1759532433216,"cs":"SeWBdL5tBivraSWoIxrppQ==","size":{"width":88,"height":12}} (см. тренды на Табл. 2).

WebXR предъявляет строгие требования к стабильности и времени кадра (обычно 90 Hz на HMD). Рассматриваемый батч-подход уже уменьшает лаг, но в XR-контексте стоит:

  • переносить трансформации максимально близко к рендеру (шейдер/compute),
  • использовать предсказание позы (late latching),
  • согласовывать координаты с референс-пространствами WebXR,
  • хранить матрицы в UBO/SSBO для мгновенного доступа шейдерами.

Такой «гибрид» (TF.js для ML-инференса + WebGPU/WebXR для трансформаций/рендера) дает наилучший шанс на 90 Hz без дрожания.

Те же принципы переносятся на:

  • трекинг скелета/жестов (руки, тело),
  • SLAM-карты/point clouds из камер глубины,
  • постпроцессинг (стабилизация, фильтры, геометрические сшивки).

Главное — стандартизировать интерфейс «N×3 → матрицы → экран» и изолировать плагины преобразований (аффинные, проективные, специальные).

Для промышленных приложений рекомендуется:

  • оборачивать горячие участки в tf.tidy,
  • минимизировать число dataSync() (агрегировать чтения),
  • кешировать матрицы и предварительно собирать композиции SRT,
  • использовать адаптивный контроль качества (менять N/частоту при перегреве/троттлинге),
  • внедрить мониторинг p50/p90/GC-паузы «на устройстве» пользователя.

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

1. Семантика та же — исполнение другое. Мы применяем тот же аффинный аппарат, но переносим вычисления на батч-ядра GPU, что даёт 10× улучшение времени и качественный рост стабильности (см. Табл. 1–3, Рис. 1–4).

2. Не «или-или», а «и-и». Для чистого рендера — вершинный шейдер; для интеграции с ML/UI — батч-вычисления TF.js. Гибрид даёт максимум.
Ограничения понятны и инженерно решаемы. Большие N, разные браузеры, прогрев, численная стабильность — управляемы при грамотной архитектуре пайплайна.

3. Будущее — WebGPU + WebXR. Схождение вычислений и рендера в одном GPU-контуре позволяет уйти к нулевым копиям и стабильным 60–90 Hz даже для «тяжёлых» облаков точек.

Для внедрения предложенного подхода в промышленные браузерные приложения необходимо учитывать не только математическую корректность и производительность аффинных преобразований, но и инженерные аспекты их эксплуатации. В таблице приведен набор практических рекомендаций, которые обеспечивают устойчивость пайплайна при длительной работе, кросс-платформенную совместимость и предсказуемое качество визуализации. Чек-лист охватывает вопросы управления памятью (tf.tidy), минимизации синхронных вызовов (dataSync), кэширования матриц преобразований, поддержки fallback-бэкендов (WebGL → WASM), мониторинга производительности и адаптивного регулирования качества (downsampling, снижение fps при перегрузке). Отдельное внимание уделено необходимости тестирования на разных устройствах и браузерах, что критично для AR/VR и ML-приложений, ориентированных на массового пользователя. Ниже представлен чек-лист продакш-готовности в таблице 4.

Таблица 4.

Чек-лист продакш-готовности

Пункт

Описание / Детализация

Управление памятью (tf.tidy)

Каждый вызов батч-преобразований должен быть обернут в tf.tidy(), чтобы гарантировать освобождение промежуточных тензоров. Это предотвращает утечки памяти при длительной работе приложения (несколько часов/дней).

Минимизация dataSync()

Избегать частых вызовов dataSync() и arraySync(), так как они синхронно блокируют поток JS и разрывают граф вычислений. Лучше агрегировать результаты и запрашивать их одним блоком или использовать асинхронный API (data()).

Кэширование матриц (SRT-композиции)

Матрицы преобразований (Scale, Rotate, Translate) и их композиции редко меняются на каждом кадре. Их можно вычислять один раз и переиспользовать, вместо пересборки на каждом шаге.

Fallback-бэкенды

Необходимо предусмотреть плавную деградацию: если WebGL недоступен, переключать TF.js на WASM-бэкенд. Это гарантирует работу на старых браузерах и мобильных устройствах.

Мониторинг производительности

Собирать метрики p50/p90 времени обработки, количество кадров в секунду, GC-паузы и использовать их для адаптивного управления (например, снижать частоту обновления при перегрузке).

Адаптивное качество

В случае перегрева устройства или троттлинга автоматически уменьшать количество точек (downsampling) или частоту кадров, сохраняя плавность работы интерфейса.

Кросс-платформенное тестирование

Тестировать работу пайплайна на разных устройствах: десктопах, ноутбуках, смартфонах и VR-шлемах. Это позволяет выявить особенности работы драйверов, различия в системах координат и ограничения GPU.

 

5. Заключение

5.1. Научная значимость

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

Во-первых, в работе показано, что классическая матричная запись аффинных преобразований в однородных координатах может быть непосредственно реализована средствами TensorFlow.js и THREE.js, при этом сохраняется эквивалентность с традиционной операцией Vector3.applyMatrix4. Это обеспечивает взаимосвязь между теоретическим аппаратом линейной алгебры и практической реализацией в веб-среде, что повышает воспроизводимость и верифицируемость результатов.

Во-вторых, введен и обоснован концепт батч-аффинных преобразований, позволяющий применять матричные операции не к отдельным точкам, а сразу ко всему облаку размерности {"backgroundColorModified":false,"aid":null,"font":{"family":"Arial","color":"#000000","size":11},"id":"94","code":"$$N\\times3$$","backgroundColor":"#ffffff","type":"$$","ts":1759569462778,"cs":"m3Nzjc+emF6WHovLFLK3hg==","size":{"width":42,"height":12}}. Такая постановка расширяет методологическую базу компьютерной графики, делая возможным анализ больших наборов данных (например, облаков точек facemesh, треков позы или сеток 3D-моделей) в терминах единой матричной модели. Формализация батч-подхода укрепляет связь между традиционной геометрической алгеброй и современными ML-инструментами, ориентированными на массовую параллельную обработку данных.

В-третьих, работа описывает границы применимости метода, включая вопросы численной устойчивости (например, поведение при {"aid":null,"backgroundColor":"#ffffff","backgroundColorModified":false,"font":{"color":"#000000","size":11,"family":"Arial"},"code":"$$w\\approx0$$","type":"$$","id":"95","ts":1759569499238,"cs":"PmtiR2eGWus8EreDPq60QA==","size":{"width":41,"height":10}} в проективных преобразованиях) и различия систем координат (право- и левосторонние). Эти аспекты, редко подробно освещаемые в инженерных публикациях, имеют принципиальное значение для построения корректных графических пайплайнов.

Научная значимость исследования проявляется также в том, что предложенный подход выходит за рамки конкретного сценария обработки лица и может быть обобщен на более широкий спектр задач: от трекинга рук и тела до визуализации данных глубины и облаков точек в задачах пространственного моделирования. Универсальность предлагаемой модели делает ее методологическим мостом между вычислительными задачами машинного обучения и визуальной аналитикой [1-5].

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

5.2. Практическая значимость

Практическая значимость исследования определяется возможностью непосредственного внедрения предложенного подхода в веб-приложения, использующие машинное обучение и трехмерную графику. Батчевое применение аффинных преобразований на GPU позволяет радикально повысить скорость и масштабируемость обработки данных, обеспечивая устойчивую работу интерфейсов в реальном времени [11-16].

Результаты экспериментов (см. Табл. 1–3, Рис. 1–4) показали, что время обработки облака из 468 точек сокращается более чем в десять раз — с ~53 мс до ~5 мс на кадр. Такое ускорение делает возможным использование сложных моделей распознавания и трекинга без потери интерактивности и плавности отображения. Это особенно важно для приложений, работающих в браузере, где каждый миллисекундный лаг напрямую влияет на пользовательское восприятие и точность совмещения виртуальных и реальных объектов.

Предложенный метод легко интегрируется в существующий технологический стек. Он опирается на стандартные структуры данных (Matrix4, Vector3 в THREE.js) и может быть вызван из любой ML-модели, работающей в TensorFlow.js, без необходимости модифицировать ядро рендеринга. Это снижает барьеры внедрения и обеспечивает совместимость с существующими архитектурами веб-визуализации.

Важным практическим преимуществом является автономность решения. Все вычисления выполняются полностью на стороне клиента, что позволяет избежать отправки видеопотока или облаков точек на сервер. Это не только повышает приватность данных, но и снижает сетевые задержки, обеспечивая работу системы в оффлайн-режиме.

Метод демонстрирует высокую переносимость: при наличии GPU используется ускорение через WebGL или WebGPU, при его отсутствии — деградация до WASM-бэкенда без потери функциональности. Такая архитектура делает систему кросс-платформенной и пригодной для работы на ноутбуках, мобильных устройствах и в VR-шлемах.

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

Кроме того, предложенное решение обладает низкой стоимостью эксплуатации. Оно не требует дополнительных серверных мощностей и минимизирует накладные расходы на память и сборку мусора благодаря использованию tf.tidy, кешированию матриц и редкому обращению к синхронным операциям. В результате обеспечивается длительная стабильная работа интерфейсов без деградации производительности.

Наконец, подход полностью совместим с будущими стандартами WebGPU и WebXR, что делает его перспективным для дальнейшего развития браузерных технологий. WebGPU предоставит возможность выполнять аффинные преобразования в вычислительных пайплайнах с минимальными задержками и обменом данными напрямую между ML-моделями и рендером. Интеграция с WebXR позволит достичь частоты обновления 60–90 Гц и обеспечить устойчивое совмещение виртуальных объектов в пространствах расширенной и виртуальной реальности.

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

Таким образом, научная значимость работы состоит в том, что она вносит вклад в формализацию и методологическую основу веб-графики, обосновывая использование аффинных преобразований как универсального математического инструмента для обработки пространственных данных в браузере. Практическая значимость заключается в разработке масштабируемого, быстродействующего и кросс-платформенного решения, которое обеспечивает точное, устойчивое и приватное преобразование облаков точек для приложений машинного зрения и AR/VR-интерфейсов нового поколения.

5.3. Выводы

Проведенное исследование подтвердило гипотезу о том, что аффинные преобразования могут быть эффективно реализованы средствами браузерных технологий при сохранении математической строгости и высокой производительности. На основе теоретического анализа и практической реализации был разработан универсальный подход к преобразованию облаков точек, который объединяет принципы линейной алгебры и методы тензорных вычислений на GPU.

Ключевые результаты исследования.

Во-первых, в работе показано, что классическая модель аффинных преобразований может быть представлена в виде батч-операций над тензорами, что позволяет обрабатывать тысячи точек за один проход. Это обеспечивает значительное ускорение вычислений — более чем в десять раз по сравнению с традиционной покомпонентной обработкой в библиотеке THREE.js (см. Табл. 1, Рис. 1).

Во-вторых, экспериментальные результаты подтвердили, что использование TensorFlow.js в связке с THREE.js обеспечивает не только рост скорости, но и повышение устойчивости визуализации. Снижение задержки при обработке точек напрямую приводит к устранению дрожания и рассинхронизации при наложении графических элементов, что особенно важно для интерфейсов реального времени (см. Табл. 3, Рис. 2–3).

В-третьих, продемонстрировано, что предложенный метод сохраняет универсальность: он может применяться для любых наборов данных, описывающих трехмерные точки, включая лендмарки лица, тела, рук, а также облака точек, полученные из датчиков глубины. Это позволяет рассматривать разработанный подход как общую вычислительную схему преобразования координат в браузере, применимую для множества задач в областях Web Graphics и Computer Vision.

Подтверждение целей исследования.

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

  • создан и реализован алгоритм, использующий единую матричную модель для всех уровней веб-графики;
  • показана его работоспособность на примере преобразования facemesh с использованием TensorFlow.js и THREE.js;
  • экспериментально доказано улучшение производительности, масштабируемости и стабильности визуализации.

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

Направления дальнейших исследований.

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

Во-вторых, перспективным направлением является адаптация подхода для пространственных сред WebXR, где требуется стабильная работа при частоте обновления 60–90 Гц и высокая синхронизация между виртуальными и физическими объектами.

В-третьих, дальнейшие исследования могут быть направлены на автоматизацию выбора оптимального бэкенда (GPU/CPU/WASM) и на разработку универсальной библиотеки аффинных преобразований для браузера, объединяющей задачи визуализации и анализа данных в едином модуле.

Завершая исследование, следует подчеркнуть, что предложенный подход формирует методологическую основу для нового поколения браузерных приложений, объединяющих компьютерное зрение, машинное обучение и интерактивную графику. Его практическая значимость определяется возможностью создавать лёгкие, масштабируемые и приватные ML-интерфейсы без перехода на нативные технологии, а научная ценность — в том, что работа закладывает основу для дальнейшего сближения областей Web Graphics и Data Science.

 

Список литературы:

  1. Ланде Д. П. Линейная алгебра и аналитическая геометрия. — М.: МГТУ им. Н. Э. Баумана, 2017. — 412 с.
  2. Струанг Г. Введение в линейную алгебру. — М.: МЦНМО, 2019. — 510 с.
  3. Хорн Р., Джонсон Ч. Матричный анализ. — М.: БИНОМ. Лаборатория знаний, 2013. — 710 с.
  4. Федосов Н. Ф. Аффинная и проективная геометрия. — СПб.: Лань, 2010. — 368 с.
  5. Лэй Д. К., Лэй С. Р., Макдональд Дж. Дж. Линейная алгебра и её приложения (Linear Algebra and Its Applications). — Пирсон, 2016. — 576 с.
  6. Khronos Group. Спецификация WebGL 2.0 (WebGL Specification 2.0). — [Электронный ресурс]. URL: https://www.khronos.org/registry/webgl/specs/latest/2.0/ (дата обращения: 04.10.2025).
  7. Паризи Т. WebGL: быстрый старт (WebGL: Up and Running). — Себастопол: O’Reilly Media, 2012. — 256 с.
  8. Дирксен Д. Изучаем Three.js — библиотеку JavaScript 3D для WebGL (Learning Three.js — The JavaScript 3D Library for WebGL). — Лондон: Packt Publishing, 2023. — 412 с.
  9. Смилков Д., Никол А., Торат Н. и др. TensorFlow.js: машинное обучение для веба (TensorFlow.js: Machine Learning for the Web) // Труды конференции SysML. — Пало-Альто, 2019. — URL: https://www.tensorflow.org/js.
  10. W3C Community Group. API устройства WebXR (WebXR Device API). — [Электронный ресурс]. URL: https://immersive-web.github.io/webxr/ (дата обращения: 04.10.2025).
  11. Хартли Р., Зиссерман А. Многоракурсная геометрия в компьютерном зрении (Multiple View Geometry in Computer Vision). — Кембридж: Cambridge University Press, 2004. — 672 с.
  12. Фишлер М. А., Боллес Р. К. Метод случайного консенсуса (RANSAC): подход к подгонке моделей с применением к анализу изображений и картографии (Random Sample Consensus: A Paradigm for Model Fitting with Applications to Image Analysis and Automated Cartography) // Communications of the ACM. — 1981. — Т. 24, № 6. — С. 381–395.
  13. Лоу Д. Г. Уникальные признаки изображений на основе масштабно-инвариантных ключевых точек (Distinctive Image Features from Scale-Invariant Keypoints) // International Journal of Computer Vision. — 2004. — Т. 60, № 2. — С. 91–110.
  14. Чжэн Ю., Чжоу К., Хуанг Ч. Аффинные преобразования и трёхмерная реконструкция в веб-средах (Affine Transformation and 3D Reconstruction in Web-Based Environments) // Computer Graphics Forum. — 2021. — Т. 40, № 7. — С. 123–135.
  15. Сандерсон К., Ловелл Б. С. Многорегиональные вероятностные гистограммы для верификации лиц при аффинных преобразованиях (Multi-Region Probabilistic Histograms for Face Verification under Affine Transformations) // Pattern Recognition Letters. — 2009. — Т. 30, № 12. — С. 1057–1065.
  16. Чжао Р., Сяо Дж., Чжан В. Реализация аффинных преобразований в реальном времени для треккинга Facemesh в веб-приложениях (Real-Time Affine Transformations for Facemesh Tracking in Web Applications) // IEEE Access. — 2023. — Т. 11. — С. 74231–74245.
Информация об авторах

архитектор программного обеспечения, EPAM Systems, США, Калифорния, г. Сан-Франциско

Software ArchitectSolution Architect EPAM Systems, USA, California, San Francisco

Журнал зарегистрирован Федеральной службой по надзору в сфере связи, информационных технологий и массовых коммуникаций (Роскомнадзор), регистрационный номер ЭЛ №ФС77-54434 от 17.06.2013
Учредитель журнала - ООО «МЦНО»
Главный редактор - Звездина Марина Юрьевна.
Top