Добавить в корзинуПозвонить
Найти в Дзене
Один Rust не п...Rust

WebAR ML

t.me/oneRustnoqRust Для чего нужна данная статья? : Создать простое WebAR-приложение, которое интегрирует 3D-объекты с использованием камеры и сенсоров через браузер. Зачем Вам это уметь? : - использовать для компиляции в WebAssembly, что позволит интегрировать код Rust, с JavaScript для WebAR. Rust будет отвечать за вычисления и обработку, а взаимодействие с камерой и отображение AR-объектов будет происходить через JavaScript и HTML. Пример использования: Обработка данных с камеры (например, распознавание маркеров) на стороне Rust с последующей передачей данных в WebAR приложение для отображения. - использовать WebGL через WebAssembly для рендеринга 3D-объектов, которые используются в AR. Для этого можно использовать библиотеку wgpu. Пример использования: Визуализация интерактивных 3D-объектов в реальном времени с рендерингом на стороне клиента. - использовать Rust совместно с JavaScript-библиотеками для WebAR, такими как three.js, A-Frame или AR.js. Rust через WebAssembly будет выпо
Оглавление
ML на RUST без заморочек

t.me/oneRustnoqRust

GitHub - nicktretyakov/WebAR

Для чего нужна данная статья? :

Создать простое WebAR-приложение, которое интегрирует 3D-объекты с использованием камеры и сенсоров через браузер.

Зачем Вам это уметь? :

- использовать для компиляции в WebAssembly, что позволит интегрировать код Rust, с JavaScript для WebAR. Rust будет отвечать за вычисления и обработку, а взаимодействие с камерой и отображение AR-объектов будет происходить через JavaScript и HTML.

Пример использования: Обработка данных с камеры (например, распознавание маркеров) на стороне Rust с последующей передачей данных в WebAR приложение для отображения.

- использовать WebGL через WebAssembly для рендеринга 3D-объектов, которые используются в AR. Для этого можно использовать библиотеку wgpu.

Пример использования: Визуализация интерактивных 3D-объектов в реальном времени с рендерингом на стороне клиента.

- использовать Rust совместно с JavaScript-библиотеками для WebAR, такими как three.js, A-Frame или AR.js. Rust через WebAssembly будет выполнять сложные вычисления, такие как обработка компьютерного зрения, а JavaScript и существующие библиотеки будут отвечать за интеграцию с камерой и рендеринг.

Пример использования: Использование Rust для улучшения производительности алгоритмов распознавания объектов в реальном времени, а JavaScript для взаимодействия с WebAR-фреймворками.

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

Пример использования: Распознавание маркеров AR или объектов реального мира с использованием алгоритмов компьютерного зрения, написанных на Rust.

- для разработки серверной части WebAR приложений, где сервер будет отвечать за обработку данных AR, таких как генерация 3D-контента, хранение данных о сессиях или кэширование сложных 3D-моделей. В этом случае WebAR приложение может взаимодействовать с сервером на Rust через REST API или WebSockets.

Пример использования: Сервер на Rust, отвечающий за хранение и предоставление 3D-моделей в реальном времени или за обработку AR-сессий.

- для привязки AR-объектов к конкретным местам в реальном мире. Rust может обрабатывать данные с GPS-сенсоров, магнитометров или акселерометров и передавать их в WebAssembly приложение для отображения AR.

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

Пример: WebAR приложение с Rust и WebAssembly:

Шаги:

  1. Установка и настройка Rust для WebAssembly: Убедитесь, что у вас установлен инструмент wasm-pack:
    cargo install wasm-pack
  2. Создание проекта: Создадим проект с использованием WebAssembly и Yew:
    cargo new --lib webar_example
    cd webar_example
  3. Редактирование Cargo.toml: Добавьте зависимости для yew, wasm-bindgen, и wgpu:
    [dependencies] wasm-bindgen = "0.2" yew = { version = "0.20", features = ["wasm-bindgen"] }
    wgpu = "0.12" futures = "0.3" web-sys = { version = "0.3", features = ["Window", "HtmlCanvasElement"] }
    js-sys = "0.3" console_error_panic_hook = "0.1"
  4. Реализация логики WebAR в Rust:Основная логика состоит из 3 частей:Используем yew для интерфейса.
    Используем wasm-bindgen для взаимодействия с JavaScript и WebAssembly.
    Используем wgpu для рендеринга 3D-графики.

1. src/lib.rs — Главный файл и точка входа

#[wasm_bindgen(start)]
pub fn wasm_start() -> Result<(), JsValue>

  • Это аналог main() для WebAssembly.
  • Выполняется автоматически при загрузке .wasm модуля.
  • Здесь подключается console_error_panic_hook (чтобы паники выводились в консоль браузера) и логирование.

static GLOBAL_STATE: Lazy<Arc<RwLock<AppState>>> = ...

  • Используется паттерн Singleton + thread-safe глобальное состояние.
  • Lazy — инициализируется один раз при первом обращении.
  • Arc<RwLock<...>> — позволяет безопасно читать/писать из разных потоков (включая Web Workers).

#[wasm_bindgen]
pub struct WebARApp;

  • Это тонкий прокси, который экспортируется в JavaScript.
  • Все вызовы из JS (initialize, process_frame, render) идут через него.

2. src/binding/api.rs — Реализация бизнес-логики

Здесь находится основная логика инициализации:

  • Создаётся детектор маркеров (ArUcoSimdDetector)
  • Создаётся пул рабочих потоков (CVWorkerPool)
  • Создаётся WebGPU-рендерер

Важный момент:

let detector = Arc::new(ArUcoSimdDetector::new())
as Arc<dyn crate::core::MarkerDetector + Send + Sync>;

Мы приводим конкретный тип к type-erased trait object. Это позволяет в будущем легко подменять реализацию (ArUco → Neural Detector и т.д.) — Dependency Inversion Principle (D).

3. src/core/ — Сердце SOLID-архитектуры

core/mod.rs определяет главный трейт:

pub trait MarkerDetector: Send + Sync {
fn detect(&self, frame: &FrameData) -> Vec<DetectedMarker>;
fn update_intrinsics(&self, intrinsics: CameraIntrinsics);
fn reset(&self);
}

  • &self вместо &mut self — потому что мы используем Arc. Mutability достигается через внутренние RwLock.
  • Send + Sync — обязательно для использования в многопоточной среде и передачи между worker'ами.

core/types.rs содержит основные структуры данных (DetectedMarker, FrameData, CameraIntrinsics).

4. src/cv/detector/aruco_simd.rs — Компьютерное зрение

Самый "тяжёлый" и производительный модуль.

Что он делает:

  1. rgb_to_gray() — очень быстрая конверсия RGBA → Grayscale (используется в каждом кадре).
  2. detect() — основной метод, который:Принимает кадр
    Конвертирует в grayscale
    Ищет кандидатов (маркеры)
    Возвращает список DetectedMarker с позой в 3D пространстве.

Пока реализация упрощённая (заглушки), но структура уже готова к внедрению настоящего SIMD + contour detection + sub-pixel refinement.

5. src/threading/worker_pool.rs — Многопоточность

pub struct CVWorkerPool {
pool: rayon::ThreadPool,
}

  • Использует Rayon — высокоуровневую библиотеку для data parallelism.
  • web_spin_lock фича позволяет Rayon работать в WebAssembly (где нет настоящих OS threads, но есть Web Workers + SharedArrayBuffer).
  • Метод submit() отправляет задачу (CVTask) в пул потоков, не блокируя главный поток.

Это критично для WebAR: компьютерное зрение не должно блокировать UI и рендеринг.

6. Глобальное состояние и потокобезопасность

Всё приложение использует комбинацию:

  • Arc<T> — shared ownership
  • RwLock<T> — множественные читатели + один писатель
  • parking_lot — более быстрая и wasm-friendly реализация RwLock

Это позволяет:

  • Главному потоку читать состояние без блокировок
  • Фоновым worker'ам безопасно выполнять тяжёлые вычисления

Как работает весь цикл (frame loop)

  1. JavaScript захватывает кадр с камеры (getUserMedia)
  2. Преобразует в RGBA Uint8Array → передаёт в Rust через process_frame(rgba, w, h)
  3. Rust кладёт задачу в CVWorkerPool
  4. В фоне (в worker thread) выполняется:Конверсия в grayscale
    Детекция маркеров (ArUco)
    Оценка позы (PnP)
  5. Результаты (позиции маркеров) возвращаются в JS (пока через канал или SharedArrayBuffer — в текущей версии упрощённо)
  6. JS вызывает render(delta_time) → WebGPU рисует 3D-объекты поверх реального мира