предисловие
Вот в чем дело, у меня есть外包工头
Бренду необходимо создать онлайн-выставочный зал виртуальной реальности. Пользователи могут посетить выставочный зал с панорамой на 360 градусов с помощью гироскопа или перетащить на мобильный телефон. В этом выставочном зале виртуальной реальности будет несколько информационных точек. После нажатия появится дополнительная информация. могут быть представлены (видео, графика и т.д.)...
Моей первой реакцией было использовать 3D-движок, потому что я только недавно начал его использовать.three.js
сделал одинBMW
Онлайн-шоурум, по сути,three.js
Я знаком с этим.
здесьДругая статья научит вас, как сделать этот BMW Online DIY с помощью threejs.~
Вариант 1: движок WebGL3D
Используйте 3D-движок для создания базовой 3D-сцены, следующая демонстрация используетthree.js, я также исследовал подобные 3D-движкиbabylon.js,playcanvas, использование почти такое же, и вы можете изучить базовый.
var scene, camera, renderer;
function initThree(){
//场景
scene = new THREE.Scene();
//镜头
camera = new THREE.PerspectiveCamera(90, document.body.clientWidth / document.body.clientHeight, 0.1, 100);
camera.position.set(0, 0, 0.01);
//渲染器
renderer = new THREE.WebGLRenderer();
renderer.setSize(document.body.clientWidth, document.body.clientHeight);
document.getElementById("container").appendChild(renderer.domElement);
//镜头控制器
var controls = new THREE.OrbitControls(camera, renderer.domElement);
//一会儿在这里添加3D物体
loop();
}
//帧同步重绘
function loop() {
requestAnimationFrame(loop);
renderer.render(scene, camera);
}
window.onload = initThree;
Теперь мы можем видеть темный мир, потому что теперьscene
В нем ничего нет, и тогда нам приходится вставлять трехмерные объекты. Методы реализации использования 3D-движка не что иное, как следующее
Реализовано с помощью куба (коробки)
Это самый простой для понимания способ: мы находимся в комнате, смотрим на потолок, землю, переднюю часть, левую и правую стороны и заднюю часть, всего шесть сторон. Мы фотографируем все шесть ракурсов, чтобы получить следующие шесть изображений.
Теперь непосредственно используем куб (коробку) для построения такой комнаты
var materials = [];
//根据左右上下前后的顺序构建六个面的材质集
var texture_left = new THREE.TextureLoader().load( './images/scene_left.jpeg' );
materials.push( new THREE.MeshBasicMaterial( { map: texture_left} ) );
var texture_right = new THREE.TextureLoader().load( './images/scene_right.jpeg' );
materials.push( new THREE.MeshBasicMaterial( { map: texture_right} ) );
var texture_top = new THREE.TextureLoader().load( './images/scene_top.jpeg' );
materials.push( new THREE.MeshBasicMaterial( { map: texture_top} ) );
var texture_bottom = new THREE.TextureLoader().load( './images/scene_bottom.jpeg' );
materials.push( new THREE.MeshBasicMaterial( { map: texture_bottom} ) );
var texture_front = new THREE.TextureLoader().load( './images/scene_front.jpeg' );
materials.push( new THREE.MeshBasicMaterial( { map: texture_front} ) );
var texture_back = new THREE.TextureLoader().load( './images/scene_back.jpeg' );
materials.push( new THREE.MeshBasicMaterial( { map: texture_back} ) );
var box = new THREE.Mesh( new THREE.BoxGeometry( 1, 1, 1 ), materials );
scene.add(box);
Хорошо, теперь ставим объектив камеры (то есть человеческую перспективу) в коробку, и переворачиваем все текстуры внутрь, реализуется VR-панорама.
box.geometry.scale( 1, 1, -1 );
Теперь мы в коробке! !
пример официальной кубической панорамы threejs
Реализовано с помощью сферы
Мы фиксируем весь свет в 360-градусном сферическом диапазоне комнаты на картинку, а затем расширяем эту картинку в прямоугольник, чтобы получить вот такую панорамную картинку
var sphereGeometry = new THREE.SphereGeometry(/*半径*/1, /*垂直节点数量*/50, /*水平节点数量*/50);//节点数量越大,需要计算的三角形就越多,影响性能
var sphere = new THREE.Mesh(sphereGeometry);
sphere.material.wireframe = true;//用线框模式大家可以看得清楚是个球体而不是圆形
scene.add(sphere);
Теперь мы вставляем это панорамное изображение на эту сферу.
var texture = new THREE.TextureLoader().load('./images/scene.jpeg');
var sphereMaterial = new THREE.MeshBasicMaterial({map: texture});
var sphere = new THREE.Mesh(sphereGeometry,sphereMaterial);
// sphere.material.wireframe = true;
Как и раньше помещаем объектив камеры (т.е. перспективу человека) внутрь сферы и переворачиваем все текстуры внутрь, получается VR панорама
Теперь мы внутри сферы! !
var sphereGeometry = new THREE.SphereGeometry(/*半径*/1, 50, 50);
sphereGeometry.scale(1, 1, -1);
Пример официальной сферической панорамы Threejs
добавить информационный пункт
На VR-панораме нам нужно разместить какие-то информационные точки, а после клика пользователь будет совершать какие-то действия.
Теперь строим такой массив точек
var hotPoints=[
{
position:{
x:0,
y:0,
z:-0.2
},
detail:{
"title":"信息点1"
}
},
{
position:{
x:-0.2,
y:-0.05,
z:0.2
},
detail:{
"title":"信息点2"
}
}
];
Переберите этот массив и добавьте карту индикации информационных точек в 3D-сцену.
var pointTexture = new THREE.TextureLoader().load('images/hot.png');
var material = new THREE.SpriteMaterial( { map: pointTexture} );
for(var i=0;i<hotPoints.length;i++){
var sprite = new THREE.Sprite( material );
sprite.scale.set( 0.1, 0.1, 0.1 );
sprite.position.set( hotPoints[i].position.x, hotPoints[i].position.y, hotPoints[i].position.z );
scene.add( sprite );
}
Видите ГОРЯЧИЙ индикатор?
Чтобы добавить событие щелчка, сначала поместите все спрайты в массив.
sprite.detail = hotPoints[i].detail;
poiObjects.push(sprite);
Затем мы используем raycast, который похож на выстрел пулей из центра объектива в направлении щелчка мыши, чтобы проверить, в какие объекты в конечном итоге попадет пуля.
document.querySelector("#container").addEventListener("click",function(event){
event.preventDefault();
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
mouse.x = ( event.clientX / document.body.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / document.body.clientHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( poiObjects );
if(intersects.length>0){
alert("点击了热点"+intersects[0].object.detail.title);
}
});
Вариант 2: CSS3D
threejs
Когда 3D-движок слишком мощный, размер кода этих движков составляет сотни Кбайт, что не имеет значения при сегодняшней скорости сети, но все же было важным соображением, когда я получил запрос несколько лет назад. Поскольку мы используем только небольшую часть 3D-движка, можем ли мы найти более легкий 3D-движок?
имеют!css3d-engine, этот 3D-движок имеет только14kb
и применяется во многих известных коммерческих проектах
- Фестиваль создателей таобаоshrek.imdevsh.com/show/zwj/
- Adidas никогда не исчезлаshrek.imdevsh.com/show/drose/
- адидас в полном разгареshrek.imdevsh.com/show/bbcny/
- Адидас никогда не будет следоватьВи из Sleeping Hot Kang.IM Life.com/show/crazy La…
Реализация с использованием скайбокса
window.onload=initCSS3D;
function initCSS3D(){
var s = new C3D.Stage();
s.size(window.innerWidth, window.innerHeight).update();
document.getElementById('container').appendChild(s.el);
var box = new C3D.Skybox();
box.size(954).position(0, 0, 0).material({
front: {image: "images/scene_front.jpeg"},
back: {image: "images/scene_back.jpeg"},
left: {image: "images/scene_right.jpeg"},
right: {image: "images/scene_left.jpeg"},
up: {image: "images/scene_top.jpeg"},
down: {image: "images/scene_bottom.jpeg"},
}).update();
s.addChild(box);
function loop() {
angleX += (curMouseX - lastMouseX + lastAngleX - angleX) * 0.3;
angleY += (curMouseY - lastMouseY + lastAngleY - angleY) * 0.3;
s.camera.rotation(angleY, -angleX, 0).updateT();
requestAnimationFrame(loop);
}
loop();
var lastMouseX = 0;
var lastMouseY = 0;
var curMouseX = 0;
var curMouseY = 0;
var lastAngleX = 0;
var lastAngleY = 0;
var angleX = 0;
var angleY = 0;
document.addEventListener("mousedown", mouseDownHandler);
document.addEventListener("mouseup", mouseUpHandler);
function mouseDownHandler(evt) {
lastMouseX = curMouseX = evt.pageX;
lastMouseY = curMouseY = evt.pageY;
lastAngleX = angleX;
lastAngleY = angleY;
document.addEventListener("mousemove", mouseMoveHandler);
}
function mouseMoveHandler(evt) {
curMouseX = evt.pageX;
curMouseY = evt.pageY;
}
function mouseUpHandler(evt) {
curMouseX = evt.pageX;
curMouseY = evt.pageY;
document.removeEventListener("mousemove", mouseMoveHandler);
}
}
Помимо небольшой библиотеки, преимущество схемы 2 в том, что для построения 3D-сцены используется div+css. Однако автор этой библиотеки почти не поддерживает ее.Если у вас возникнут проблемы, вы должны найти способ их решения.Например, при использовании на компьютере вы увидите очевидные края патча.
Но это все еще довольно хорошо, если смотреть на мобильном телефоне.
добавить информационный пункт
Мы продолжаем добавлять в него интерактивные информационные точки
var hotPoints=[
{
position:{
x:0,
y:0,
z:-476
},
detail:{
"title":"信息点1"
}
},
{
position:{
x:0,
y:0,
z:476
},
detail:{
"title":"信息点2"
}
}
];
function initPoints(){
var poiObjects = [];
for(var i=0;i<hotPoints.length;i++){
var _p = new C3D.Plane();
_p.size(207, 162).position(hotPoints[i].position.x,hotPoints[i].position.y,hotPoints[i].position.z).material({
image: "images/hot.png",
repeat: 'no-repeat',
bothsides: true,//注意这个两面贴图的属性
}).update();
s.addChild(_p);
_p.el.detail = hotPoints[i].detail;
_p.on("click",function(e){
console.log(e.target.detail.title);
})
}
}
Таким образом могут отображаться информационные точки, а поскольку это элемент div, нам очень легко добавлять такие эффекты, как взаимодействие с щелчком мыши.
но,bothsides
Когда свойство истинно, изображение информационной точки на обратной стороне переворачивается.
Поэтому нам нужно сделать здесь небольшую обработку, сбросить угол поворота информационной точки в соответствии с ее углом с камерой. (如果是那种怎么旋转都无所谓的图片,比如圆点则无需处理
)
var r = Math.atan2(hotPoints[i].position.z-0,0-0) * 180 / Math.PI+90;
_p.size(207, 162).position(hotPoints[i].position.x,hotPoints[i].position.y,hotPoints[i].position.z).material({
image: "images/hot.png",
repeat: 'no-repeat',
bothsides: false,
}).update();
Спрос повышен!
Вышеуказанные две схемы, я думал, что мог бы дать клиенту передачу. Но клиент придумал несколько идей
-
Качество панорамы должно быть выше, но скорость загрузки не может быть ниже
-
В каждой сцене много информационных точек, а редактирование координат слишком хлопотно
В то время я думал про себя, я беру с тебя всего десять тысяч долларов, неужели мне придется настраивать под тебя движок, а потом делать визуальный редактор?
Пока заказчик не прислал реферальную ссылку, я ее прочитал惊呆了
, панорама очень четкая, но первая скорость загрузки очень быстрая.Как и Baidu Maps, загружается от размытого до четкого.
Проверив код веб-страницы со справочной ссылкой, я нашел решение три
Вариант 3: pano2vr
pano2vr — это WYSIWYG программное обеспечение для создания панорамных VR (подлинная цена 149 евро).Оно имеет мощные функции и может быть напрямую выведено на статические веб-страницы HTML5.Опыт очень хороший.
И его основная библиотекаpano2vr_player.js
Количество кода только238kb
.
Мы можем напрямую использовать это программное обеспечение для визуального добавления информационных точек.После вывода в HTML5 вся информация о конфигурации, кроме статических изображений, находится здесь.pano.xml
в файле
Изменить изображение информационной точки
Общий интерактивный опыт очень хорош, но мне не нравится стиль информационной точки по умолчанию Мы можем изменить изображение информационной точки с помощью следующего кода
pano.readConfigUrlAsync("pano.xml",()=>{
var pois=pano.getPointHotspotIds();
var hotScale = 0.2;
for(var i=0;i<pois.length;i++){
var ids=pois[i];
var hotsopt=pano.getHotspot(ids);
hotsopt.div.firstChild.src="images/hot.png";
hotsopt.div.firstChild.style.width = 207*hotScale+"px";
hotsopt.div.firstChild.style.height = 162*hotScale+"px";
hotsopt.div.onmouseover = null;
hotsopt.div.setAttribute("ids",ids);
hotsopt.div.onclick=function() {
//在这里可以响应信息点的点击事件啦
console.log(this.getAttribute("ids"));
};
}
});
Ха-ха, не ожидал, что итоговое решение не только добилось очень простой VR-панорамы с хорошим опытом, но и включало в себя очень удобное редактирование информационных точек. В дополнение к трудоемкой разработке в первый раз, потребуется 10 минут, чтобы сделать новую сцену VR в будущем.
но подумай о外包工头
частоСократить мое предложение, сократить сроки строительства, необоснованно изменить спрос
Когда он получил оплату за проект, он попросил меня пойти на K-song, и я не сказал ему об использовании pano2vr, когда сидел в приватной комнате КТВ, а сказал ему
Редактирование информационных точек каждой сцены VR занимает 1 день.
Каждый раз, когда вы создаете новую сцену VR, вы получаете 8k от бренда.
Я беру с тебя 3к за сцену, ты зарабатываешь 5к лежа
В конце концов, мы старые друзья, я имею в виду достаточно.
Он смело выпил пиво из рук и сказал: «Добрый брат, я спою тебе песенку!»
Эта история чисто вымышленная.Если фотографии в конце статьи нарушают авторские права, пожалуйста, свяжитесь со мной, чтобы выпить с боссом.
Посмотрите видеоинструкцию, сопровождающую эту статью
Если вам нравятся уроки Дашуая, добавьте в закладки, лайкните и подпишитесь
- Билибили:
大帅老猿
- Публичный аккаунт WeChat:
大帅老猿