Введение в 3D анимацию в HTML

Введение в 3D анимацию в HTML

Картинка к публикации: Введение в 3D анимацию в HTML

Введение в 3D анимацию в HTML

Значение анимированных 3D фигур

Анимированные 3D фигуры вносят значительный вклад в веб-дизайн, предоставляя уникальные возможности для создания вовлекающего и динамичного пользовательского опыта. В отличие от традиционных 2D изображений, трёхмерные объекты добавляют глубину и реализм, что особенно ценно в различных областях, таких как онлайн-торговля, образовательные платформы и интерактивные медиа. Используя 3D анимации, разработчики могут более естественно демонстрировать продукты, создавать иммерсивные обучающие модули и повышать общее взаимодействие с пользователем.

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

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

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

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

Обзор ключевых технологий

Для создания анимированных 3D фигур в веб-среде, две основные технологии занимают центральное место: WebGL и библиотека Three.js. Понимание этих инструментов является ключевым для эффективного внедрения 3D контента на ваших веб-страницах.

WebGL (Web Graphics Library) представляет собой JavaScript API, который позволяет выполнять рендеринг интерактивной 2D и 3D графики в браузере без использования дополнительных плагинов. WebGL основан на OpenGL ES, стандарте, широко используемом в мобильных устройствах и встроенных системах для рендеринга комплексных графических элементов.

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

Three.js — это высокоуровневая JavaScript-библиотека, которая упрощает создание и анимацию 3D сцен в вебе. Она действует как оболочка над более низкоуровневым WebGL, предоставляя более простой и понятный API. Библиотека предлагает множество предварительно созданных объектов, таких как камеры, материалы, освещение и геометрические фигуры, что значительно ускоряет процесс разработки.

Three.js особенно полезна для новичков в 3D программировании, так как она позволяет сосредоточиться на креативных аспектах проекта, минимизируя необходимость глубокого погружения в математические детали рендеринга и оптимизации производительности. Кроме того, благодаря большому сообществу и множеству доступных ресурсов и примеров, Three.js является отличным выбором для быстрого старта в мире 3D веб-разработки.

Используя WebGL для максимальной производительности и Three.js для упрощения разработки, можно достичь впечатляющих результатов в создании 3D анимации. Эти технологии взаимодополняют друг друга, позволяя разработчикам реализовывать сложные и красивые визуальные сцены с высокой степенью интерактивности и реалистичности.

Цели статьи

Вы научитесь настраивать базовую 3D сцену, используя Three.js. Это включает в себя подготовку HTML-разметки и интеграцию с библиотекой Three.js, чтобы начать работу с 3D графикой. Мы обсудим, как добавить камеры, свет и базовые геометрические объекты, создавая основу для более сложных проектов.

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

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

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

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

Эта статья поможет вам не только понять технические аспекты создания 3D сцен, но и вдохновит на эксперименты с новыми идеями и творческими подходами в области 3D веб-дизайна и программирования.

Настройка разработки 3D сцены

Подготовка среды разработки

Для разработки 3D сцен в вебе эффективная и подходящая среда разработки играет значительную роль. Она не только упрощает написание кода, но и помогает в тестировании и отладке.

Выбор текстового редактора или IDE

  1. Visual Studio Code (VS Code): Один из самых популярных редакторов среди веб-разработчиков. VS Code предлагает широкий спектр плагинов, встроенную поддержку Git, удобные возможности для отладки и большую систему подсказок по коду. Он идеально подходит для работы с JavaScript и библиотекой Three.js.
  2. Atom: Еще один популярный редактор, разработанный GitHub. Atom легко настраивается и имеет большое количество доступных плагинов. Он поддерживает множество языков программирования и предоставляет удобные инструменты для работы в команде.
  3. Sublime Text: Этот редактор известен своей скоростью и гибкостью. Sublime Text поддерживает множество плагинов и тем, что делает его удобным инструментом для разработки веб-приложений.

Полезные плагины и инструменты

  • Three.js Developer Tools: Расширение для Google Chrome, которое позволяет инспектировать и отлаживать 3D сцены, созданные с использованием Three.js.
  • WebGL Inspector: Еще одно расширение для Chrome, которое предоставляет детальные сведения о WebGL вызовах и помогает отслеживать производительность и отлаживать ошибки.
  • Live Server: Плагин для VS Code, который запускает локальный сервер разработки с возможностью "горячей" перезагрузки, автоматически обновляя страницу при изменении файлов проекта.

После выбора текстового редактора или IDE, следует его настроить:

  1. Установите необходимые плагины через менеджер расширений вашего редактора.
  2. Настройте встроенный терминал (если доступен), чтобы иметь возможность запускать команды для сборки или тестирования прямо из редактора.
  3. Подготовьте шаблоны кода (snippets) для часто используемых функций и конструкций Three.js, чтобы ускорить процесс написания нового кода.

Установка инструментов

Для начала создания 3D сцен на веб-страницах нам потребуется установить и настроить ряд инструментов, основным из которых является библиотека Three.js.

Шаг 1: Подготовка рабочего окружения

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

Шаг 2: Подключение библиотеки Three.js

Для начала работы с 3D графикой в вебе, основой является интеграция библиотеки Three.js. Это инструмент, который позволяет создавать и управлять 3D контентом прямо в браузере без дополнительных плагинов. Подключение через CDN (Content Delivery Network) является одним из самых простых и эффективных способов интеграции, обеспечивая быструю загрузку и актуальность версий библиотеки. Также добавим определение importmap в наш HTML-документ, что позволяет удобно использовать модули ES в вашем проекте на базе Three.js включая OrbitControls, которые позволяют пользователю вращать, масштабировать и перемещать камеру с помощью мыши. Использование importmap особенно полезно при работе с множеством зависимостей, поскольку это позволяет централизованно управлять путями импорта в нашем приложении.

Добавление скрипта в HTML: Для подключения Three.js вам необходимо добавить следующий тег <script> в ваш HTML-документ, предпочтительно в раздел <head>:

<script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.164.1/build/three.module.js",
      "OrbitControls": "https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/controls/OrbitControls.js",
      "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.164.1/examples/jsm/"
    }
  }
</script>

Создание базовой HTML-структуры

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

DOCTYPE и HTML теги: Начните с определения типа документа и основного HTML тега. Это устанавливает стандарт HTML5 для страницы, что гарантирует совместимость с современными браузерами.

<!DOCTYPE html>
<html lang="ru">

Head секция: В этой части определяется заголовок документа и подключаются необходимые скрипты и стили. Здесь же подключается Three.js.

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Scene</title>
    <meta name="description" content="Пример 3D сцены с использованием Three.js">
    <script type="importmap">
      ... // Тут размещено подключение Three.js
    </script>
    <style>
        body { margin: 0; }
        canvas { display: block; width: 100vw; height: 100vh; }
    </style>
</head>

Для того чтобы canvas элемент правильно отображался на весь экран, добавим немного CSS. Эти стили уберут отступы у тела документа и настроят холст так, чтобы он занимал весь доступный видимый экран.

Body секция: Здесь будет размещен элемент canvas, на котором Three.js будет рендерить 3D сцену.

<body>  
 <canvas id="myThreeJsCanvas"></canvas>  
 <script>    
 // Здесь будет JavaScript код для создания и управления 3D сценой  
 </script> 
</body>

Интеграция JavaScript для 3D рендеринга

В секции <script> в теге <body> вы будете создавать и управлять вашей 3D сценой. Это место для инициализации сцены, камеры, рендерера и добавления объектов и света, а также для запуска анимационных функций. Этот блок состоит из нескольких инструкций import, используемых для загрузки модулей JavaScript, которые предоставляют функциональность для создания и управления 3D графикой в веб-приложении с использованием библиотеки Three.js и некоторых дополнительных инструментов для постобработки. Вот разбивка каждого импорта:

  1. Основной модуль Three.js:

    <script type="module">
      import * as THREE from "three";

    Эта строка импортирует все экспорты библиотеки Three.js как пространство имен THREE. Это означает, что все классы и функции Three.js теперь доступны через префикс THREE, например THREE.Scene, THREE.Mesh и т.д.

  2. OrbitControls:

      import { OrbitControls } from 'OrbitControls';

    Здесь импортируется класс OrbitControls из модуля OrbitControls. Этот контроллер позволяет пользователям вращать, масштабировать и перемещать камеру в сцене с помощью мыши или сенсорных жестов, что делает взаимодействие с 3D сценой более интуитивным.

  3. EffectComposer и связанные компоненты:

      import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
      import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
      import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
      import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
      // Здесь будет JavaScript код для создания и управления 3D сценой 
    </script>                 

    Эти строки импортируют различные компоненты, связанные с постобработкой:

    • EffectComposer используется для управления последовательностью постобработки. Он позволяет комбинировать различные эффекты в одну цепочку обработки.
    • RenderPass — это проход, который отвечает за рендеринг сцены в буфер или на экран.
    • UnrealBloomPass добавляет эффект "свечения" (bloom), который имитирует эффект камеры, видимый при сильном освещении.
    • ShaderPass позволяет применять пользовательский шейдер к результату всей сцены или к предыдущему проходу постобработки.

Эти инструменты в совокупности позволяют создать богатые визуальные эффекты и глубоко настраивать визуализацию сцены в Three.js, улучшая визуальное качество и создавая различные атмосферные эффекты.

Подготовив эту базовую структуру, вы легко сможете расширять и углублять вашу 3D сцену, добавляя более сложные элементы и интерактивность. 

После установки всех необходимых компонентов, создайте простую 3D сцену для проверки того, что все настроено правильно:

<!DOCTYPE html>
<html lang="ru">

<head>
  ...
</head>

<body>
 <script type="module">
   // ... импорты аддонов как описано выше
   
   // Создаем сцену    
   const scene = new THREE.Scene(); 
   // Добавляем камеру    
   const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);    
   camera.position.z = 5;    
   // Создаем рендерер
   const renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myThreeJsCanvas')});
   renderer.setSize(window.innerWidth, window.innerHeight);    
            
   // Создаем геометрический объект    
   const geometry = new THREE.BoxGeometry();
   // Создаем материал куба
   const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
   // Собираем куб из геометрии и материала   
   const cube = new THREE.Mesh(geometry, material);
   // Добавляем куб в сцену
   scene.add(cube);    
            
   // Функция анимации    
   function animate() {
     requestAnimationFrame(animate);     
     cube.rotation.x += 0.01;      
     cube.rotation.y += 0.01;      
     renderer.render(scene, camera);    
   }    
   animate();
 </script>
</body>

Этот код создает простую сцену с вращающимся кубом, что позволит вам убедиться, что все компоненты работают корректно.

Следуя этим шагам, вы подготовите все необходимое для разработки более сложных 3D.

Моделирование 3D объектов

Основы создания объектов

Для начала практической работы с 3D сценами важно понять, как создавать базовые геометрические формы. Рассмотрим процесс создания трех базовых моделей — куба, сферы и пирамиды — используя Three.js. Эти примеры помогут вам освоить основные принципы работы с библиотекой и понять, как манипулировать объектами в трехмерном пространстве. Удалим предыдущий геометрический объект, оставив сцену и рендер.

Создание куба

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

	// Создаем геометрию куба
	const cubeGeometry = new THREE.BoxGeometry(2, 2, 2); // параметры: ширина, высота, глубина

	// Создаем геометрию для рёбер куба
	const edgesGeometry = new THREE.EdgesGeometry(cubeGeometry);

	// Создаем материал для линий
	const lineMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 }); // красный цвет

	// Создаем линии по рёбрам куба
	const cubeEdges = new THREE.LineSegments(edgesGeometry, lineMaterial);

	// Добавляем каркас куба в сцену
	scene.add(cubeEdges);

Создание сферы

Сфера создается похожим образом, но с использованием SphereGeometry. Это позволяет создавать более сложные и гладкие формы:

	// Создаем геометрию сферы 
	const sphereGeometry = newTHREE.SphereGeometry(1, 32, 32); // параметры: радиус, широтные и меридиональные сегменты

	// Создаем материал сферы 
	const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // зеленый цвет

	// Собираем сферу из геометрии и материала 
	const sphere = newTHREE.Mesh(sphereGeometry, sphereMaterial);

	// Добавляем сферу в сцену 
	scene.add(sphere);

Создание пирамиды

Для создания пирамиды используем ConeGeometry, который также можно настроить для создания конических и пирамидальных форм:

	// Создаем геометрию пирамиды 
	const pyramidGeometry = newTHREE.ConeGeometry(1.5, 3, 4); // параметры: радиус основания, высота, количество сегментов основания 

	// Создаем материал пирамиды 
	const pyramidMaterial = newTHREE.MeshBasicMaterial({ color: 0x0000ff }); // синий цвет 

	// Собираем пирамиду из геометрии и материала 
	const pyramid = newTHREE.Mesh(pyramidGeometry, pyramidMaterial); 

	// Добавляем пирамиду в сцену 
	scene.add(pyramid);
	// Функция анимации    
	function animate() {
  	  requestAnimationFrame(animate);     
  	  cubeEdges.rotation.x += 0.01;      
  	  cubeEdges.rotation.y += 0.01;  
  	  sphere.rotation.x += 0.01;  
  	  sphere.rotation.y += 0.01;  
  	  pyramid.rotation.x += 0.01;  
  	  pyramid.rotation.y += 0.01;      
  	  renderer.render(scene, camera);    
	}    
	animate();

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

Комплексные 3D модели

После того как мы освоили создание базовых геометрических форм, давайте перейдем к более сложным 3D моделям. 

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

	// Создаем сцену    
    const scene = new THREE.Scene(); 
    // Добавляем камеру    
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);    
    camera.position.z = 5;  
    
    // Добавляем свет
    const light = new THREE.PointLight(0xffffff, 1, 100);
    light.position.set(10, 10, 10);
    scene.add(light);

    const ambientLight = new THREE.AmbientLight(0x404040); // мягкий белый свет
    scene.add(ambientLight);
      
    // Создаем рендерер
    const renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myThreeJsCanvas')});
    renderer.setSize(window.innerWidth, window.innerHeight);

    // Туловище робота
    const bodyGeometry = new THREE.BoxGeometry(2, 3, 1.5);
    const bodyMaterial = new THREE.MeshPhongMaterial({ color: 0x7777ff });
    const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
    scene.add(body);

    // Голова робота
    const headGeometry = new THREE.BoxGeometry(1, 1, 1);
    const headMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });
    const head = new THREE.Mesh(headGeometry, headMaterial);
    head.position.set(0, 2.5, 0);
    scene.add(head);

    // Руки робота
    const handGeometry = new THREE.CylinderGeometry(0.25, 0.25, 2);
    const handMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
    const leftHand = new THREE.Mesh(handGeometry, handMaterial);
    leftHand.position.set(-1.5, 1, 0);
    const rightHand = new THREE.Mesh(handGeometry, handMaterial);
    rightHand.position.set(1.5, 1, 0);
    scene.add(leftHand);
    scene.add(rightHand);

    function animate() {
        requestAnimationFrame(animate);

        // Анимация головы: поворот влево и вправо
        head.rotation.y += 0.01;
        if (head.rotation.y > Math.PI / 4 || head.rotation.y < -Math.PI / 4) {
            head.rotation.y *= -1; // Переключение направления вращения
        }

        // Анимация рук: подъем и опускание
        leftHand.rotation.z += 0.01;
        rightHand.rotation.z -= 0.01;
        if (leftHand.rotation.z > Math.PI / 4 || leftHand.rotation.z < -Math.PI / 4) {
            leftHand.rotation.z *= -1; // Переключение направления вращения
        }
        if (rightHand.rotation.z < -Math.PI / 4 || rightHand.rotation.z > Math.PI / 4) {
            rightHand.rotation.z *= -1; // Переключение направления вращения
        }

        renderer.render(scene, camera);
    }
    animate(); // Запускаем анимацию

Для создания еще более сложных форм можно использовать ExtrudeGeometry или LatheGeometry, которые позволяют создавать объекты с нестандартными контурами.

    const scene = new THREE.Scene(); 
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);    
    camera.position.z = 20;  
    
    const renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myThreeJsCanvas')});
    renderer.setSize(window.innerWidth, window.innerHeight);

    // Создаем сердцевидный объект
    const heartShape = new THREE.Shape();
    heartShape.moveTo(2.5, 2.5);
    heartShape.bezierCurveTo(2.5, 2.5, 2, 0, 0, 0);
    heartShape.bezierCurveTo(-3, 0, -3, 3.5, -3, 3.5);
    heartShape.bezierCurveTo(-3, 5.5, -1, 7.7, 2.5, 9.5);
    heartShape.bezierCurveTo(6, 7.7, 8, 5.5, 8, 3.5);
    heartShape.bezierCurveTo(8, 3.5, 8, 0, 5, 0);
    heartShape.bezierCurveTo(3.5, 0, 2.5, 2.5, 2.5, 2.5);
    const extrudeSettings = {
        steps: 2,
        depth: 2,
        bevelEnabled: true,
        bevelThickness: 0.5,
        bevelSize: 0.5,
        bevelOffset: 0,
        bevelSegments: 1
    };
    const geometry = new THREE.ExtrudeGeometry(heartShape, extrudeSettings);
    const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
    const heart = new THREE.Mesh(geometry, material);
    heart.position.set(0, 0, 0);
    heart.rotation.x = Math.PI; // Переворачиваем сердце на 180 градусов
    scene.add(heart);

    // Добавляем свет
    const light = new THREE.PointLight(0xffffff, 1, 100);
    light.position.set(10, 10, 10);
    scene.add(light);
    const ambientLight = new THREE.AmbientLight(0x404040); // мягкий белый свет
    scene.add(ambientLight);

    let scaleDirection = 1;
    let scaleSpeed = 0.01;

    function animate() {
        requestAnimationFrame(animate);

        // Анимация сердца: пульсация
        heart.scale.x += scaleSpeed * scaleDirection;
        heart.scale.y += scaleSpeed * scaleDirection;
        heart.scale.z += scaleSpeed * scaleDirection;

        // Инверсия направления масштабирования при достижении границ
        if (heart.scale.x > 1.2 || heart.scale.x < 0.8) {
            scaleDirection *= -1;
        }

        renderer.render(scene, camera);
    }
    animate();

Настройка материалов и текстур

Для достижения реалистичности и визуальной привлекательности моделей, настройка материалов и текстур играет ключевую роль. Использование MeshStandardMaterial или MeshPhysicalMaterial может добавить реализм за счет точного моделирования освещения, отражения и тени.

Шаг 1: Создание сцены и камеры

Для начала создадим базовую сцену, камеру и освещение:

	const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);
    camera.position.z = 5;

    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);
    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    directionalLight.position.set(0, 1, 1);
    scene.add(directionalLight);

Шаг 2: Загрузка текстур

Загрузим текстуру, которую мы будем использовать для материала. Предположим, что это текстура камня:

	const textureLoader = new THREE.TextureLoader();
    const stoneTexture = textureLoader.load('path_to_your_texture.jpg');

Шаг 3: Создание материала и геометрии

Теперь создадим материал, используя MeshStandardMaterial, и применим к нему загруженную текстуру. Также создадим простую геометрию — например, куб:

	const boxGeometry = new THREE.BoxGeometry(2, 2, 2);
	const stoneMaterial = new THREE.MeshStandardMaterial({
      map: stoneTexture,
      roughness: 0.7,  // Уровень шероховатости материала
      metalness: 0.1   // Уровень металличности материала
	});
	const stoneBox = new THREE.Mesh(boxGeometry, stoneMaterial);
	scene.add(stoneBox);

Шаг 4: Рендеринг сцены

Добавим рендерер и запустим анимационный цикл:

	const renderer = new THREE.WebGLRenderer();
	renderer.setSize(window.innerWidth, window.innerHeight);
	document.body.appendChild(renderer.domElement);

	function animate() {
      requestAnimationFrame(animate);
      stoneBox.rotation.x += 0.01;
      stoneBox.rotation.y += 0.01;
      renderer.render(scene, camera);
	}
	animate();

Этот пример показывает, как применять текстуры и настраивать материалы для создания визуально привлекательных и реалистичных 3D моделей. MeshStandardMaterial делает модель более реалистичной за счёт точного моделирования света и тени, что особенно заметно при использовании динамического освещения, как в данном примере.

Манипуляции с объектами

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

Изменение размера объектов

Размер объекта можно изменить, используя свойство scale. Это позволяет увеличивать или уменьшать объекты без необходимости изменения их геометрии.

	// Масштабирование куба 
	cube.scale.set(2, 2, 2); 
	// Удваиваем размер куба по всем осям

Изменение цвета объектов

Цвет объекта можно изменить, модифицируя свойство color его материала. Это дает возможность динамически адаптировать внешний вид объектов в зависимости от требований сцены.

	// Изменение цвета куба на синий 
	cube.material.color.set(0x0000ff);

Применение текстур

Текстуры добавляют детализацию и реализм объектам. В Three.js текстуру можно назначить, загрузив изображение и применив его как материал объекта.

	// Загрузка текстуры
	const textureLoader = new THREE.TextureLoader();
	  textureLoader.load('path/to/texture.jpg', function(texture) {
   	  cube.material.map = texture;
   	  cube.material.needsUpdate = true; // Обновляем материал после загрузки текстуры
	});

Работа с прозрачностью и отражением

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

	// Создание полупрозрачного материала
	const transparentMaterial = new THREE.MeshPhongMaterial({
   	  color: 0x00ff00,
   	  transparent: true,
   	  opacity: 0.5
	});
	// Создание отражающего материала
	const reflectiveMaterial = new THREE.MeshPhongMaterial({
   	  color: 0x00ff00,
   	  envMap: scene.background, // Используем фон сцены как карту окружения
   	  reflectivity: 1
	});

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

Анимация и динамика 3D моделей

Анимация 3D моделей придает динамичность и живость вашим сценам. Three.js предоставляет множество инструментов для анимации объектов, включая вращение, масштабирование и перемещение. В этом разделе мы рассмотрим базовые принципы анимации в Three.js, начиная с простой анимации и постепенно переходя к более сложным техникам.

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

	// Функция анимации для вращения объекта
	function animate() {
   	  requestAnimationFrame(animate);
   	  // Вращение куба вокруг его осей
   	  cube.rotation.x += 0.01;
   	  cube.rotation.y += 0.01;
   	  renderer.render(scene, camera);
	}
	animate();

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

	// Изменение размера объекта во время анимации
	function animate() {
   	requestAnimationFrame(animate);
   	  // Масштабирование куба
   	  cube.scale.x = 1.5 + Math.abs(Math.sin(Date.now() * 0.001));
   	  cube.scale.y = 1.5 + Math.abs(Math.sin(Date.now() * 0.001));
   	  cube.scale.z = 1.5 + Math.abs(Math.sin(Date.now() * 0.001));
   	  renderer.render(scene, camera);
	}
	animate();

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

	// Перемещение объекта по сцене
	  function animate() {
   	  requestAnimationFrame(animate);
   	  // Плавное перемещение куба вверх и вниз
   	  cube.position.y = 2 * Math.sin(Date.now() * 0.001);
   	  renderer.render(scene, camera);
	}
	animate();

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

Продвинутая анимация

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

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

 // Инициализация AnimationMixer
    const mixer = new THREE.AnimationMixer(cube);

    // Создание анимации вращения
    const rotateKeyframes = new THREE.AnimationClip('rotate', -1, [
        new THREE.KeyframeTrack('cube.rotation[y]', [0, 1], [0, Math.PI * 2])
    ]);

    // Создание анимации масштабирования
    const scaleKeyframes = new THREE.AnimationClip('scale', -1, [
        new THREE.KeyframeTrack('cube.scale[x]', [0, 1, 2], [1, 2, 1]),
        new THREE.KeyframeTrack('cube.scale[y]', [0, 1, 2], [1, 2, 1])
    ]);

    // Воспроизведение анимаций
    const rotateAction = mixer.clipAction(rotateKeyframes);
    rotateAction.play();
    const scaleAction = mixer.clipAction(scaleKeyframes);
    scaleAction.play();

    // Функция анимации
    function animate(time) {
        requestAnimationFrame(animate);
        mixer.update(time * 0.001);  // время в секундах
        renderer.render(scene, camera);
    }

    // Запуск анимации
    animate(0);

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

// Создание системы частиц
    const particlesGeometry = new THREE.BufferGeometry();
    const particlesCount = 500;
    const posArray = new Float32Array(particlesCount * 3); // Массив позиций частиц
    for (let i = 0; i < particlesCount * 3; i++) {
        posArray[i] = (Math.random() - 0.5) * 5; // Распределение частиц в пространстве
    }
    particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3));
    const particlesMaterial = new THREE.PointsMaterial({
        size: 0.025,
        color: 'white'
    });
    const particleMesh = new THREE.Points(particlesGeometry, particlesMaterial);
    scene.add(particleMesh);

    // Функция анимации для обновления сцены
    function animate() {
        requestAnimationFrame(animate);
        particleMesh.rotation.y += 0.01; // Вращение системы частиц
        renderer.render(scene, camera); // Рендер сцены
    }

    animate(); // Запуск анимации

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

Работа с анимационными кривыми

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

Кривые Безье в анимации используются для создания плавных и контролируемых переходов между ключевыми кадрами. В Three.js это реализуется через KeyframeTrack, где каждый ключевой кадр может иметь свою кривую, определяющую изменение параметра объекта во времени.

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

 // Создание объекта - сферы
    const sphere = new THREE.Mesh(
        new THREE.SphereGeometry(0.5, 32, 32),
        new THREE.MeshBasicMaterial({ color: 0xFF6347 })
    );
    sphere.position.y = 0;
    scene.add(sphere);

    // Камера позиционируется
    camera.position.z = 5;

    // Создаем анимационный миксер для сферы
    const mixer = new THREE.AnimationMixer(sphere);

    // Определение ключевых кадров для анимации подпрыгивания
    const positionKF = new THREE.VectorKeyframeTrack(
        'sphere.position',
        [0, 1, 2],
        [0, 0, 0, 0, 1.5, 0, 0, 0, 0],
        THREE.InterpolateSmooth
    );

    // Создание анимационного клипа
    const clip = new THREE.AnimationClip('bounce', 3, [positionKF]);

    // Активация и воспроизведение анимации
    const action = mixer.clipAction(clip);
    action.play();

    // Функция анимации
    function animate(time) {
        requestAnimationFrame(animate);
        mixer.update(time * 0.001); // время в секундах
        renderer.render(scene, camera);
    }

    animate(0); // Запуск анимационной функции

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

// Создание кривой Безье
    const curve = new THREE.CubicBezierCurve3(
        new THREE.Vector3(-10, 0, 0),
        new THREE.Vector3(-5, 15, 0),
        new THREE.Vector3(20, 15, 0),
        new THREE.Vector3(10, 0, 0)
    );

    // Генерация точек кривой и создание геометрии
    const points = curve.getPoints(50);
    const geometry = new THREE.BufferGeometry().setFromPoints(points);

    // Создание материала и линии для отображения кривой
    const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
    const curveObject = new THREE.Line(geometry, material);
    scene.add(curveObject);

    // Позиционирование камеры
    camera.position.set(0, 5, 30);
    camera.lookAt(0, 0, 0);

    // Функция анимации для обновления и рендеринга сцены
    function animate() {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
    }

    // Запуск анимации
    animate();

Анимационные кривые являются необходимым инструментом в арсенале разработчика Three.js, позволяя создавать сложные, реалистичные и визуально привлекательные анимации. Освоение этой техники открывает новые возможности для динамического взаимодействия и повышения эмоциональной выразительности ваших 3В проекто.

Освещение и интерактивность

Настройка освещения

Освещение в 3D сценах играет критическую роль в восприятии формы, глубины и материала объектов. Three.js предоставляет несколько типов источников света, каждый из которых имеет свои особенности и применения. Далее рассмотрим, как добавлять различные источники света в сцену, чтобы создавать реалистичные тени и глубину.

  • Направленный свет (Directional Light): Имитирует свет, исходящий из бесконечно удаленного источника, например, солнца. Идеален для создания теней, так как лучи света распространяются параллельно.
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight.position.set(5, 10, 7.5);
scene.add(directionalLight);
  • Точечный свет (Point Light): Исходит из одной точки и распространяется во все стороны. Подходит для имитации источников света, таких как лампочки.
const pointLight = new THREE.PointLight(0xff0000, 1.0, 100);
pointLight.position.set(10, 10, 10);
scene.add(pointLight);
  • Прожектор (Spotlight): Исходит из конуса, позволяя создавать фокусированный свет с мягкими краями, что идеально подходит для акцентирования определенных частей сцены.
const spotLight = new THREE.SpotLight(0x00ff00, 1.0);
spotLight.position.set(0, 10, 0);
spotLight.angle = Math.PI / 4;
scene.add(spotLight);
  • Окружающий свет (Ambient Light): Добавляет единообразное освещение всей сцене, без создания теней. Это хороший способ моделировать рассеянный свет.
const ambientLight = new THREE.AmbientLight(0x404040); // мягкий белый свет
scene.add(ambientLight);
  • Работа с тенями: Для реализации теней в Three.js, светильник должен быть настроен на их производство, и также нужно указать, что объекты в сцене могут их принимать или отбрасывать.
// Настройка направленного света для создания теней
directionalLight.castShadow = true;
scene.add(directionalLight);
// Настройка объектов для взаимодействия с тенями
cube.castShadow = true;  // Куб отбрасывает тень
plane.receiveShadow = true;  // Плоскость принимает тени
// Настройка рендерера
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Тип карты теней для мягких теней

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

Добавление теней

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

Чтобы источник света мог создавать тени, необходимо активировать его свойство castShadow. Это свойство доступно у DirectionalLight, SpotLightи PointLight.

const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight.position.set(5, 10, 7.5);
directionalLight.castShadow = true;
scene.add(directionalLight);

Объекты в сцене должны быть настроены так, чтобы они могли отбрасывать или принимать тени. Это делается с помощью свойств castShadow и receiveShadow.

const cube = new THREE.Mesh(
   new THREE.BoxGeometry(2, 2, 2),
   new THREE.MeshPhongMaterial({ color: 0x00ff00 })
);
cube.position.set(0, 1, 0);
cube.castShadow = true;  // Куб будет отбрасывать тень
scene.add(cube);
const plane = new THREE.Mesh(
   new THREE.PlaneGeometry(5, 5),
   new THREE.MeshPhongMaterial({ color: 0xffffff })
);
plane.rotation.x = -Math.PI / 2;
plane.position.y = -0.5;
plane.receiveShadow = true;  // Плоскость будет принимать тени
scene.add(plane);

Three.js предоставляет несколько параметров для управления качеством и видом теней, таких как разрешение карты теней (shadowMapSize) и параметры, влияющие на мягкость теней.

directionalLight.shadow.mapSize.width = 1024;  // Разрешение теневой карты
directionalLight.shadow.mapSize.height = 1024;
directionalLight.shadow.camera.near = 0.5;  // Ближайшая граница камеры теней
directionalLight.shadow.camera.far = 50;    // Наиболее удалённая граница камеры теней
const shadowCameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(shadowCameraHelper);  // Визуализация границ камеры теней для отладки

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

  • Используйте меньшее разрешение теневой карты для меньшего потребления ресурсов.
  • Ограничьте количество светильников, отбрасывающих тени.
  • Настройте параметры camera.near и camera.far для каждого источника света, чтобы минимизировать размер области, где рассчитываются тени.

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

Обработка событий

Для создания полноценного интерактивного 3D приложения важно уметь реагировать на действия пользователя, такие как клики мыши или нажатия клавиш. Three.js предоставляет возможности для обработки таких событий, что позволяет разработчикам создавать более динамичные и вовлекающие сцены. 

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

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseClick(event) {
   // Перевод координат мыши в нормализованные значения от -1 до 1
   mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
   mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
   // Обновление позиции луча на основе координат мыши
   raycaster.setFromCamera(mouse, camera);
   // Поиск объектов, пересекаемых лучом
   const intersects = raycaster.intersectObjects(scene.children);
   if (intersects.length > 0) {
       console.log('Объект выбран:', intersects[0].object);
       // Можно добавить любые действия, например, изменение цвета объекта
       intersects[0].object.material.color.set(0xff0000);
   }
}
window.addEventListener('click', onMouseClick);

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

function onKeyDown(event) {
   switch (event.keyCode) {
       case 87: // W
           camera.position.z -= 0.1;
           break;
       case 83: // S
           camera.position.z += 0.1;
           break;
       case 65: // A
           camera.position.x -= 0.1;
           break;
       case 68: // D
           camera.position.x += 0.1;
           break;
   }
}
window.addEventListener('keydown', onKeyDown);

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

function onKeyPress(event) {
   if (event.key === ' ' && !action.isRunning()) {
       action.reset().play();
   }
}
window.addEventListener('keypress', onKeyPress);

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

Оптимизация и выводы

Улучшение производительности

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

Минимизация ресурсоемких операций:

  • Использование LOD (Level of Detail): LOD помогает уменьшить количество полигонов, используемых для объектов на расстоянии от камеры, что снижает нагрузку на GPU.
const lod = new THREE.LOD();
const highDetail = new THREE.Mesh(new THREE.SphereGeometry(1, 48, 48), new THREE.MeshBasicMaterial({color: 0xffffff}));
const mediumDetail = new THREE.Mesh(new THREE.SphereGeometry(1, 24, 24), new THREE.MeshBasicMaterial({color: 0xffffff}));
const lowDetail = new THREE.Mesh(new THREE.SphereGeometry(1, 8, 8), new THREE.MeshBasicMaterial({color: 0xffffff}));
lod.addLevel(highDetail, 0);
lod.addLevel(mediumDetail, 20);
lod.addLevel(lowDetail, 40);
scene.add(lod);
  • Уменьшение количества светильников и использование бейкнутых текстур: Текстуры с предварительно рассчитанным освещением могут значительно улучшить производительность, уменьшая необходимость в динамическом освещении.
  • Оптимизация теней: Тени могут существенно влиять на производительность. Используйте более низкое разрешение теневой карты и ограничивайте количество объектов, отбрасывающих тени.
directionalLight.shadow.mapSize.width = 512;  // Меньше значит быстрее
directionalLight.shadow.mapSize.height = 512;

Оптимизация загрузки ресурсов

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

const loader = new THREE.TextureLoader();
loader.load('texture.jpg', function(texture) {
   material.map = texture;
   material.needsUpdate = true;
});

Компрессия текстур и моделей: Используйте форматы файлов, которые поддерживают сжатие без значительной потери качества, например, JPEG для текстур и glTF для моделей.

Использование профайлеров:

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

console.log('Количество геометрий в памяти:', renderer.info.memory.geometries); 

Оптимизация 3D анимации не только улучшает пользовательский опыт, но и расширяет возможности использования вашего приложения на устройствах с ограниченными ресурсами. Применяя эти методы, вы сможете достичь баланса между качеством визуализации и требованиями к производительности.

Тестирование и отладка

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

Использование инструментов разработчика браузера: Современные браузеры предоставляют различные инструменты для отладки веб-приложений, включая 3D контент. Эти инструменты могут помочь в анализе производительности и поиске утечек памяти.

  • Консоль разработчика: Позволяет выводить логи, предупреждения и ошибки, что упрощает отслеживание поведения кода в реальном времени.
  • Профилировщик производительности: Анализирует время выполнения операций и помогает определить узкие места, замедляющие производительность.
  • Инспектор WebGL: Позволяет визуально проверять и отлаживать WebGL шейдеры и текстуры.

Автоматическое тестирование: Для обеспечения качества 3D анимации можно использовать автоматические тесты. Это включает в себя:

  • Юнит-тестирование: Тестирование отдельных функций и классов на корректность выполнения их функционала.
  • Интеграционное тестирование: Проверка взаимодействий между различными компонентами системы, чтобы убедиться, что они работают вместе правильно.
describe('3D Object Tests', () => {
   it('should create a sphere with correct parameters', () => {
       const radius = 5;
       const geometry = new THREE.SphereGeometry(radius);
       expect(geometry.parameters.radius).toBe(radius);
   });
});

Отладка шейдеров: Отладка шейдеров может быть сложной из-за их параллельной природы исполнения и ограниченных возможностей вывода данных. Использование специальных инструментов, таких как Shader Editor в Firefox или Spector.js, может помочь визуализировать и модифицировать шейдеры в реальном времени.

Визуализация границ и коллизий: Для отладки визуальных и пространственных аспектов 3D моделей полезно использовать визуализацию ограничивающих рамок и коллизий:

const box = new THREE.BoxHelper(cube, 0xff0000); scene.add(box);

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

Заключение и дальнейшее изучение

На протяжении этой статьи мы исследовали множество аспектов создания, анимации и оптимизации 3D моделей в вебе с использованием Three.js. Мы обсудили начальные шаги установки и настройки, базовые и продвинутые техники моделирования и анимации, а также методы освещения и взаимодействия с пользователем. Особое внимание было уделено оптимизации производительности и тестированию, что критически важно для создания качественных веб-приложений.

Резюме основных идей

  • Моделирование и анимация: Использование Three.js позволяет нам создавать сложные 3D сцены с детализированными объектами и плавной анимацией, делая интерфейс пользователя захватывающим и интерактивным.
  • Освещение и тени: Правильно настроенное освещение и реалистичные тени значительно повышают реализм сцены, добавляя глубину и визуальную аттрактивность.
  • Интерактивность: Обработка событий и реакция на действия пользователя увеличивают вовлеченность и удержание пользователя, что особенно важно для игр и интерактивных приложений.
  • Оптимизация и тестирование: Эффективное использование ресурсов и проверка на отсутствие ошибок обеспечивают стабильность приложения и плавное взаимодействие, независимо от платформы пользователя.

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


Читайте также:

ChatGPT
Eva
💫 Eva assistant