Привет, хочу рассказать основу о том как быстро начать пилить продвинутые приложения с 3d моделями.
Для того чтобы лучше понимать контекст последующего материала ожидается что у тебя уже есть знания js, а также react. Также заранее оговорюсь что буду использовать упрощенное объяснения для наилучшего восприятия.
Содержание
-
Основные сущности threejs
-
Основные части модели
-
Загрузка модели
-
Загрузка анимации
-
Threejs и React
Основные сущности Three.js
Three.js построен вокруг нескольких ключевых сущностей. Разберём их с примерами кода.
Сцена — это контейнер (объект), в который ты помещаешь все объекты: геометрию, свет, модели, эффекты и т.п.
const scene = new THREE.Scene(); scene.background = new THREE.Color(0x222222); // тёмно-серый фон
Камера — это глаз пользователя, который видит сцену. Объекты не отображаются, если они вне поля зрения камеры.
const camera = new THREE.PerspectiveCamera( 75, // угол обзора (FOV) window.innerWidth / window.innerHeight, // соотношение сторон 0.1, // ближняя плоскость отсечения 1000 // дальняя плоскость отсечения ); camera.position.set(0, 1, 5); // камера смотрит с точки (0, 1, 5)
Рендерер — это компонент, который переводит сцену и камеру в пиксели, т.е. отрисовывает результат на HTML-экране. Более подробно разберем во 2 части статьи.
const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); // размеры вьюпорта document.body.appendChild(renderer.domElement); // <canvas> элемент, вставляемый в DOM
Как они работают вместе ?
Ты → создаёшь объекты → добавляешь их в сцену
Камера → “смотрит” на сцену
Рендерер → рисует это в на экране
Так а что же на счет 3d моделей ради которых мы и собрались? Давай разберем их чуть подробнее.
Основные части модели
Что же такое модель ?
3D-модель — это структура, описывающая форму, материалы, текстуры и поведение объекта.
Как ты уже понял по описанию сущность состоит из нескольких компонентов. Давай разберемся в них подробнее.
Геометрия (Geometry) — это форма модели: вершины, грани, координаты и нормали.
-
Вершины (vertices) — точки в 3D-пространстве
-
Грани (faces) — треугольники между вершинами
-
Нормали — направление, в которое “смотрит” поверхность
-
UV — координаты наложения текстур
Более подробно разберем во 2 части статьи
Материалы (Materials) — описывают, как должна выглядеть поверхность: цвет, отражения, прозрачность.
В Threejs есть множество материалов, которые служат абстракцией для наилучшего описания нужного материла. Основной MeshStandardMaterial:
const standardMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff, metalness: 0.8, roughness: 0.2 });
MeshStandardMaterial, поддерживает следующие параметры:
-
color
-
roughness
-
metalness
-
emissive
-
alpha (прозрачность)
Для более продвинутых кейсов также существует MeshPhysicalMaterial, данный материал отличается более реалистичным отображением и фактически существует только в рамках threejs, к нему может быть автоматически преобразован материал модели с настройками отражения.
Текстуры (Textures) — это изображения, которые накладываются на материал для создания реалистичности.
Типы текстур:
-
diffuse/baseColor— основной цвет -
normalMap— фейковая детализация рельефа -
metalnessMap,roughnessMap - блеск -
aoMap— ambient occlusion (тени) -
emissiveMap— подсветка
const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load('/textures/wood.jpg'); const material = new THREE.MeshStandardMaterial({ map: texture });
Загрузка модели
Загрузка моделей может отличаться в зависимости от формата самой модели. Однако для наиболее популярных форматов подойдет GLTFLoader. В случае более экзотических форматов можно использовать Loader с кастомным поведением
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; const loader = new GLTFLoader(); loader.load('/models/robot.glb', (gltf) => { scene.add(gltf.scene); });
Загрузка анимации
Каждая модель может содержать анимацию, если она была заложена на этапе создания этой модели 3d-дизайнером.
В рамках threejs это можно проверить если модель содержит анимации (gltf.animations.length > 0), используй THREE.AnimationMixer:
let mixer; const clock = new THREE.Clock(); loader.load('/models/fox.glb', (gltf) => { const model = gltf.scene; scene.add(model); mixer = new THREE.AnimationMixer(model); // Проигрываем первую анимацию const action = mixer.clipAction(gltf.animations[0]); action.play(); }); function animate() { requestAnimationFrame(animate); const delta = clock.getDelta(); mixer?.update(delta); renderer.render(scene, camera); }
Threejs и React
Для работы с Three.js в React чаще всего используется следующие пакеты:
@react-three/fiber — обертка над Three.js через JSX (аналог react-dom, но для WebGL)
@react-three/drei — Набор готовых компонентов: OrbitControls, Stage, Text, Gizmo, Loader и т.д.
@react-three/postprocessing — Эффекты постобработки (bloom, depth of field, glitch и пр.)
import { Canvas } from '@react-three/fiber'; import { OrbitControls, Stage } from '@react-three/drei'; export default function App() { return ( <Canvas> <Stage environment="city" intensity={0.6}> <mesh> <boxGeometry args={[1, 1, 1]} /> <meshStandardMaterial color="skyblue" /> </mesh> </Stage> <OrbitControls /> </Canvas> ); }
Как видно из примера буквально в одну строчку кода можно описать нужное поведение. Например OrbitControls позволяет вращать камеру относительно сцены. А Stage добавляет пресет заднего фона с освещением. Работа с моделями также упрощена все настройки оборачиваются в mesh и внутри него описываются геометрия и материал, то есть составные части модели.
Также добавлен хук для упрощенной загрузки моделей — useGLTF
// ModelViewer.jsx import { useGLTF } from '@react-three/drei'; export default function ModelViewer(props) { const { scene } = useGLTF('/models/robot.glb'); return <primitive object={scene} scale={1.5} {...props} />; }
Далее можно вставить данную компоненту прямо в сцену как и любую другую компоненту в обычном react приложении.
Кроме того добавлен хук для загрузки текстур — useTextures
// CrateModel.jsx import { useGLTF, useTexture } from '@react-three/drei'; import * as THREE from 'three'; export default function CrateModel(props) { // Загружаем модель const { nodes } = useGLTF('/models/crate.glb'); // Загружаем текстуры const textureProps = useTexture({ map: '/textures/crate_diffuse.jpg', roughnessMap: '/textures/crate_roughness.jpg', normalMap: '/textures/crate_normal.jpg', }); // Настройка обёртки текстур (по желанию) Object.values(textureProps).forEach((tex) => { tex.wrapS = tex.wrapT = THREE.RepeatWrapping; tex.repeat.set(1, 1); }); return ( <mesh geometry={nodes.Crate.geometry} {...props} castShadow receiveShadow > <meshStandardMaterial {...textureProps} metalness={0.1} roughness={1} /> </mesh> ); }
Мы разобрали базу, без которой дальше никуда. Я надеюсь как минимум избавил тебя от переживаний, что работа с моделями это что-то из жанра фантастики и все намного проще чем кажется, если разобраться в ключевых аспектах.
В следующей части копнём глубже: как работает сам WebGL под капотом, что на самом деле делает Three.js и как всё это грамотно оптимизировать, чтобы сцена не лагала даже на мобилках. Будет интересно.
ссылка на оригинал статьи https://habr.com/ru/articles/928072/
Добавить комментарий