相机朝向网格旋转有时会非常严重 - Using Three.js and Tween.js for 360° pictures player
Camera rotation toward mesh sometimes bugs very hard - Using Three.js and Tween.js for 360° pictures player
我正在使用 Three.js 开发 360° 图片播放器。
我的场景包含一个具有 360° 图片作为纹理的球体 (BasicMeshMaterial)。相机位于该球体的中间,因此用户可以看到应用于球体 "walls".
的图片
我最近添加了点击球体某些点的可能性,将相机旋转到那个点。镜头平稳的移动到这个点,直到这个点在屏幕中央。
我的问题是,有时本应聚焦于单击点的相机缓动(补间动画)使用了非常奇怪的路径,而且非常难看。
这似乎发生在相机的初始位置和目标位置穿过球体的某个点时。我几乎不知道会发生什么。你 ?它可以有一个 link 球体,还是相机只玩四元数,所以它不受其他物体的影响?那么是什么让它选择了错误的路径,为什么它只在球体的某个角度发生?任何事情都会有所帮助!
播放器可在 http://isiko.io/ 滚动一点后进行测试。
我可以给你看代码,但真的不知道该选什么。告诉我你是否需要相机的旋转,或者球体的启动..
感谢您的反馈。
还有另一种绕轴补间角度的方法:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 32, 24), new THREE.MeshBasicMaterial({
color: "yellow",
wireframe: true
}));
scene.add(sphere);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var center = new THREE.Vector3();
var vectorStart = new THREE.Vector3(0, 0, -10); // in front of the camera
var vectorEnd = new THREE.Vector3();
var angle = {
value: 0
};
var angleEnd = {
value: 0
};
var normal = new THREE.Vector3();
var lookAt = new THREE.Vector3();
var isMoving = false;
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(event) {
if (isMoving) return;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let newPosition = raycaster.ray.at(10);
setPoint(newPosition);
// prepare the values we need for tweening
vectorEnd.copy(newPosition);
angle.value = 0; // we will tween this value
angleEnd.value = vectorStart.angleTo(vectorEnd); // to this one
normal.copy(vectorStart).cross(vectorEnd).normalize(); // around this axis
// tween the angle
var tween = new TWEEN.Tween(angle).to(angleEnd, 1000).delay(250).easing(TWEEN.Easing.Cubic.InOut).onStart(function(){
isMoving = true;
}).onUpdate(
function() {
camera.lookAt(lookAt.copy(vectorStart).applyAxisAngle(normal, angle.value));
}
).onComplete(function() {
isMoving = false;
vectorStart.copy(vectorEnd);
}).start();
}
function setPoint(position) {
let point = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
point.position.copy(position);
scene.add(point);
}
render()
function render() {
requestAnimationFrame(render);
TWEEN.update(); // don't forget to put this line into the animation loop, when you use Tween.js
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>
我正在使用 Three.js 开发 360° 图片播放器。 我的场景包含一个具有 360° 图片作为纹理的球体 (BasicMeshMaterial)。相机位于该球体的中间,因此用户可以看到应用于球体 "walls".
的图片我最近添加了点击球体某些点的可能性,将相机旋转到那个点。镜头平稳的移动到这个点,直到这个点在屏幕中央。
我的问题是,有时本应聚焦于单击点的相机缓动(补间动画)使用了非常奇怪的路径,而且非常难看。 这似乎发生在相机的初始位置和目标位置穿过球体的某个点时。我几乎不知道会发生什么。你 ?它可以有一个 link 球体,还是相机只玩四元数,所以它不受其他物体的影响?那么是什么让它选择了错误的路径,为什么它只在球体的某个角度发生?任何事情都会有所帮助!
播放器可在 http://isiko.io/ 滚动一点后进行测试。 我可以给你看代码,但真的不知道该选什么。告诉我你是否需要相机的旋转,或者球体的启动..
感谢您的反馈。
还有另一种绕轴补间角度的方法:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 32, 24), new THREE.MeshBasicMaterial({
color: "yellow",
wireframe: true
}));
scene.add(sphere);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var center = new THREE.Vector3();
var vectorStart = new THREE.Vector3(0, 0, -10); // in front of the camera
var vectorEnd = new THREE.Vector3();
var angle = {
value: 0
};
var angleEnd = {
value: 0
};
var normal = new THREE.Vector3();
var lookAt = new THREE.Vector3();
var isMoving = false;
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(event) {
if (isMoving) return;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let newPosition = raycaster.ray.at(10);
setPoint(newPosition);
// prepare the values we need for tweening
vectorEnd.copy(newPosition);
angle.value = 0; // we will tween this value
angleEnd.value = vectorStart.angleTo(vectorEnd); // to this one
normal.copy(vectorStart).cross(vectorEnd).normalize(); // around this axis
// tween the angle
var tween = new TWEEN.Tween(angle).to(angleEnd, 1000).delay(250).easing(TWEEN.Easing.Cubic.InOut).onStart(function(){
isMoving = true;
}).onUpdate(
function() {
camera.lookAt(lookAt.copy(vectorStart).applyAxisAngle(normal, angle.value));
}
).onComplete(function() {
isMoving = false;
vectorStart.copy(vectorEnd);
}).start();
}
function setPoint(position) {
let point = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
point.position.copy(position);
scene.add(point);
}
render()
function render() {
requestAnimationFrame(render);
TWEEN.update(); // don't forget to put this line into the animation loop, when you use Tween.js
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>