1.全景图的实现原理
- 构建
thee.js基本要素 - 在场景中创建一个球体
- 将全景图片贴图与球体内部
- 将摄像机放置于球体内部
2.构建thee.js基本要素
2.1 创建场景 官方文档说明
import { Scene } from "three"
function initScene() {
return new Scene();
}
2.2 创建透视相机 官方文档说明
//@container 挂载容器
import { PerspectiveCamera } from "three"
function initCamera(container) {
const fov = 90;
const aspect = container.clientWidth / container.clientHeight;
const near = 0.1;
const far = 100;
const camera = new PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, 0.01);
return camera;
}
2.3 创建WebGL渲染器
//@container 挂载容器
import { WebGLRenderer } from "three"
function initRenderer(container) {
const renderer = new WebGLRenderer();
renderer.setSize(container.clientWidth / container.clientHeight);
renderer.setClearColor(0x000000, 1.0);
container.appendChild(renderer.domElement);
return renderer;
}
2.4 创建控制器
//@camera 透视相机实例
//@renderer 渲染器实例
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
function initOrbitControls(camera, renderer) {
return new OrbitControls(camera, renderer.domElement);
}
2.5 添加灯光
//@scene 场景实例
import { HemisphereLight } from "three";
function initLight(scene) {
const light = new THREE.HemisphereLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);
}
3.创建球体并贴图
import { TextureLoader } from "three";
function initTexture(src) {
return new TextureLoader().load(src);
}
import { SphereGeometry, MeshBasicMaterial, Mesh } from "three";
fucntion initSphere(scene) {
const texture = initTexture("https://fengtianxi001.github.io/THREE-PanoramaImage-DevTools/assets/texture.acafc6ef.jpeg");
const sphereGeometry = new SphereGeometry(1, 50, 50);
sphereGeometry.scale(1, 1, -1);
const sphereMaterial = new MeshBasicMaterial({ map: texture });
const sphere = new Mesh(sphereGeometry, sphereMaterial);
scene.add(sphere);
return sphere;
}
4.完整代码如下
代码不限框架, 可根据不同框架做适当修改
class Panorama {
constructor(container) {
this.container = container;
this.scene = this.initScene();
this.camera = this.initCamera();
this.renderer = this.initRenderer();
this.orbitControls = this.initOrbitControls();
this.sphere = this.initSphere();
}
initScene() {
return new THREE.Scene();
}
initCamera() {
const { clientWidth, clientHeight } = this.container
const fov = 90;
const aspect = clientWidth / clientHeight;
const near = 0.1;
const far = 100;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, 0.01);
camera.lookAt(0, 0, 0);
return camera;
}
initRenderer() {
const { clientWidth, clientHeight } = this.container
const renderer = new THREE.WebGLRenderer();
renderer.setSize(clientWidth, clientHeight);
renderer.setClearColor(0x000000, 1.0);
this.container.appendChild(renderer.domElement);
return renderer;
}
initOrbitControls() {
return new OrbitControls(this.camera, this.renderer.domElement)
}
initSphere() {
const texture = this.initTexture("https://fengtianxi001.github.io/THREE-PanoramaImage-DevTools/assets/texture.acafc6ef.jpeg");
const sphereGeometry = new THREE.SphereGeometry(1, 50, 50);
sphereGeometry.scale(1, 1, -1);
const sphereMaterial = new THREE.MeshBasicMaterial({ map: texture });
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
this.scene.add(sphere);
return sphere;
}
initTexture(src) {
return new THREE.TextureLoader().load(src);
}
animate() {
this.orbitControls.update()
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(() => this.animate());
}
}
export default Panorama;
5.补充
- 完整的陀螺仪全景图代码及案例可访问 MF-PanoramaImage
- 全景图的点位标记原理(2d坐标转3d坐标)可访问THREE-PanoramaImage-DevTools
- 欢迎访问的我的github仓库!