Из материала статьи вы узнаете, как загрузить 3D-модель в пространство сцены с помощью PyWeb3D.
3D-модели доступны в сотнях файловых форматов, каждый из которых обладает своим назначением, особенностями и уровнем сложности. Несмотря на то, что three.js предоставляет множество загрузчиков, выбор правильного формата и рабочего процесса сэкономит время и избавит от разочарований в дальнейшем. Ведь некоторые форматы вызывают трудности в процессе работы, демонстрируют низкую производительность в режиме реального времени или просто не поддерживаются на данный момент.
Мы будем задействовать формат glTF
, рекомендуемый для three.js.
Примечание. Обе версии формата, .GLB
и .GLTF
, отлично поддерживаются.
Для загрузки модели в пространство сцены используется three.js GLTFLoader
.
С модифицированной версией для PyWeb3D можно ознакомиться по ссылке.
Шаблонный код HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PyWeb3D webgl - GLTFloader</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/brython.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/brython_stdlib.js"></script>
<script src="https://unpkg.com/[email protected]/build/three.js"></script>
<script src="https://www.pyweb3d.org/pyweb3d/v1.0.0/pyweb3d.brython.js"></script>
<style>
body { margin: 0; }
</style>
</head>
<body onload="brython(1)">
<script src="../jsm/loaders/GLTFLoader.js"></script>
<script src="../jsm/controls/OrbitControls.js"></script>
<script src="../jsm/loaders/RGBELoader.js"></script>
<script type="text/python">
# Код Python размещается здесь
</script>
<body>
</html>
Весь нижеследующий код размещается в строчном теге <script type=”text/python”>
в теле HTML-файла.
Импорт требуемых модулей и функций
from browser import document, window
from pyweb3d.pyweb3d import *
from javascript import UNDEFINED as undefined
Инициализация дополнительIх модулей
GLTFLoader = window.THREE.GLTFLoader.new
OrbitControls = window.THREE.OrbitControls.new
RGBELoader = window.THREE.RGBELoader.new
В данном фрагменте кода мы инициализируем дополнительные модули GLTFLoader
, OrbitControls
и RGBELoader
напрямую из файла JavaScript в код Python.
Создание сцены и загрузка модели
#Переменные для настройки
camera = None
renderer = None
scene = None
car = None
def init():
global camera
global renderer
global scene
global car
#Создание сцены
scene = Scene()
scene.background = Color( 0x333333 )
scene.environment = RGBELoader().load( 'textures/venice_sunset_1k.hdr' )
scene.environment.mapping = EquirectangularReflectionMapping
scene.fog = Fog( 0x333333, 10, 15 )
grid = GridHelper( 20, 40, 0xffffff, 0xffffff )
grid.material.opacity = 0.2
grid.material.depthWrite = False
grid.material.transparent = True
scene.add( grid )
fov = 45
aspect = window.innerWidth / window.innerHeight
near = 1
far = 1500
#Настройка камеры
camera = PerspectiveCamera(fov, aspect, near, far)
camera.position.x = 8
camera.position.y = 1
camera.position.z = 10
#Настройка источников света
ambientLight = AmbientLight( 'white', 2 )
scene.add( ambientLight )
DirectLight = DirectionalLight( 'white', 3.5 )
DirectLight.position.set( 100, 100, 100 )
scene.add( DirectLight )
hemiLight = HemisphereLight('white', 'darkslategrey', 5)
scene.add(hemiLight)
#Визуализатор
renderer = WebGLRenderer( { 'antialias': True } )
renderer.setPixelRatio( window.devicePixelRatio )
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
controls = OrbitControls(camera, renderer.domElement)
#Загрузка модели
loader = GLTFLoader()
def loadGLTF(gltf):
car = gltf.scene
car.scale.setScalar( 1.5 )
# центр
box = Box3().setFromObject( car )
center = box.getCenter( Vector3() )
car.position.x += ( car.position.x - center.x )
car.position.y += ( car.position.y - center.y + 1.4)
car.position.z += ( car.position.z - center.z )
scene.add( car )
animate(0)
def onError(error):
print(error)
loader.load( 'models/Nissan_Z_Proto/scene.gltf', loadGLTF, undefined, onError)
Построчно разберем содержимое данного кода.
- Строки
2 — 5
. Объявляем пустые переменные для хранения камеры, визуализатора, сцены и автомобиля. - Строки
7 — 75
. Определяем функциюinit()
. Внутри нее создаем сцену, камеру, сетку, источник света и загружаем модель.
Переходим к более детальному разбору.
- Строки
8 — 11
. Делаем переменные из строк2–5
изменяемыми. Для тех, кто только начинает работать с Python, отметим, что ключевое словоglobal
необходимо для изменения глобальной копии переменных, объявленных в строках2 — 5
. - Строки
14 — 18
. Создаем сцену, добавляем к ней фоновый цвет, текстуру и эффект тумана. - Строки
20 — 24
. Создаем сетку и добавляем ее к сцене. - Строки
26 — 35
. Создаем камеру с перспективной проекцией и задаем ей область просмотра, соотношение сторон, ближнюю и дальнюю плоскости отсечения. - Строки
38 — 39
. Создаем источник рассеянного света и добавляем его к сцене. - Строки
41 — 43
. Создаем источник направленного света и добавляем его к сцене. - Строки
45 — 46
. Создаем полусферический источник света и добавляем его к сцене. - Строки
49 -52
. Создаем визуализаторWebGL
и добавляем его в тело HTML-файла. - Строка
54
. Создаем элемент управления вращением камерыOrbitControl
, который принимает цель в качестве аргумента (в данном случае камеру иrenderer.domElement
или элемент<canvas>
). - Строка
57
. ИнстанцируемGLTFLoader
. - Строки
59 — 70
. Определяем функцию обратного вызоваloadGLTF()
для обработки настроек моделиgLTF
. - Строки
72 — 73
. Определяем функцию обратного вызоваonError()
. Она обрабатывает сообщения об ошибках и помогает устранять неполадки в случае сбоев загрузки модели. - Строка
75
. Загружаем модель и передаем функции обратного вызова методуload
в качестве аргумента.
Обработка события изменения размера окна и анимации
def onWindowResize(resize):
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize( window.innerWidth, window.innerHeight )
window.addEventListener( 'resize', onWindowResize )
def animate(time):
window.requestAnimationFrame( animate )
renderer.render( scene, camera )
init()
Строки 1 — 8
. Обрабатываем событие изменения размера окна.
Строки 10 — 12
. Обрабатываем цикл анимации.
Строка 14
. Вызываем функцию init()
, определенную в строках 7 — 75
предыдущего фрагмента кода.
Запуск кода
Открываем HTML-файл в браузере и видим прекрасную модель спорткара Nissan Z Proto.
Версия в интерактивном режиме по ссылке.
Исходный код по ссылке.
Читайте также:
- Создание базовых 3D-сцен с помощью Three.js
- Реализация VR-пространства в браузере
- 10 инструментов, которые упростят жизнь веб-разработчика
Читайте нас в Telegram, VK и Дзен
Перевод статьи Bruno Odinukweze: Loading 3D Models Using PyWeb3D