像倒置旋转木马或 VR/Spherical 一样查看图像

View Image like in inverted carrousel or VR/Spherical

我正在尝试构建这样的东西:

但不同之处在于我有一张 4096x1024 的背景图片,我希望它看起来像是某种 VR 外观,中心离屏幕有点远,边缘有点拉长并且更近

我设法使用 aframes 并将我的图像设置为 <a-sky> 标签的背景,因此它将我的图像扭曲成一个球体,并将视图或相机扭曲在球体的中心.我得到了我想要的正确视图类型,问题是我认为对此有更简单的解决方案。 我也想放文字,我希望它的行为方式与图像的行为方式相同。

这就是我用 aframes 存档的内容:Gif on Imgur

我不想在 scene/screen 周围移动(使用 AWDS),只是为了水平移动屏幕,因为我将拥有用户需要移动屏幕才能看到的元素,就像在gif 和常见的carrossel。

定义 "lighter"A-Frame 建立在 WebVRthree.js 之上,所以如果你不想 A-Frame 依赖,也许你可以使用 three.js 自己构建全景图。它实际上已经有一个关于如何这样做的例子:

https://threejs.org/examples/webgl_panorama_equirectangular.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.js"></script>
<!DOCTYPE html>
<html lang="en">
 <head>
  <title>three.js webgl - equirectangular panorama</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  <style>
   body {
    background-color: #000000;
    margin: 0px;
    overflow: hidden;
   }
   #info {
    position: absolute;
    top: 0px; width: 100%;
    color: #ffffff;
    padding: 5px;
    font-family:Monospace;
    font-size:13px;
    font-weight: bold;
    text-align:center;
   }
   a {
    color: #ffffff;
   }
  </style>
 </head>
 <body>

  <div id="container"></div>
  <div id="info">
   <a href="http://threejs.org" target="_blank" rel="noopener">three.js webgl</a> - equirectangular panorama demo. photo by <a href="http://www.flickr.com/photos/jonragnarsson/2294472375/" target="_blank" rel="noopener">Jón Ragnarsson</a>.<br />
   drag equirectangular texture into the page.
  </div>

  <script>
   var camera, scene, renderer;
   var isUserInteracting = false,
   onMouseDownMouseX = 0, onMouseDownMouseY = 0,
   lon = 0, onMouseDownLon = 0,
   lat = 0, onMouseDownLat = 0,
   phi = 0, theta = 0;
   init();
   animate();
   function init() {
    var container, mesh;
    container = document.getElementById( 'container' );
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1100 );
    camera.target = new THREE.Vector3( 0, 0, 0 );
    scene = new THREE.Scene();
    var geometry = new THREE.SphereBufferGeometry( 500, 60, 40 );
    // invert the geometry on the x-axis so that all of the faces point inward
    geometry.scale( - 1, 1, 1 );
    var material = new THREE.MeshBasicMaterial( {
     map: new THREE.TextureLoader().load( 'https://farm4.staticflickr.com/3289/2294472375_24a3b8ef46_o.jpg' )
    } );
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild( renderer.domElement );
    document.addEventListener( 'mousedown', onDocumentMouseDown, false );
    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
    document.addEventListener( 'mouseup', onDocumentMouseUp, false );
    document.addEventListener( 'wheel', onDocumentMouseWheel, false );
    //
    document.addEventListener( 'dragover', function ( event ) {
     event.preventDefault();
     event.dataTransfer.dropEffect = 'copy';
    }, false );
    document.addEventListener( 'dragenter', function ( event ) {
     document.body.style.opacity = 0.5;
    }, false );
    document.addEventListener( 'dragleave', function ( event ) {
     document.body.style.opacity = 1;
    }, false );
    document.addEventListener( 'drop', function ( event ) {
     event.preventDefault();
     var reader = new FileReader();
     reader.addEventListener( 'load', function ( event ) {
      material.map.image.src = event.target.result;
      material.map.needsUpdate = true;
     }, false );
     reader.readAsDataURL( event.dataTransfer.files[ 0 ] );
     document.body.style.opacity = 1;
    }, false );
    //
    window.addEventListener( 'resize', onWindowResize, false );
   }
   function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
   }
   function onDocumentMouseDown( event ) {
    event.preventDefault();
    isUserInteracting = true;
    onMouseDownMouseX = event.clientX;
    onMouseDownMouseY = event.clientY;
    onMouseDownLon = lon;
    onMouseDownLat = lat;
   }
   function onDocumentMouseMove( event ) {
    if ( isUserInteracting === true ) {
     lon = ( onMouseDownMouseX - event.clientX ) * 0.1 + onMouseDownLon;
     lat = ( event.clientY - onMouseDownMouseY ) * 0.1 + onMouseDownLat;
    }
   }
   function onDocumentMouseUp( event ) {
    isUserInteracting = false;
   }
   function onDocumentMouseWheel( event ) {
    var fov = camera.fov + event.deltaY * 0.05;
    camera.fov = THREE.Math.clamp( fov, 10, 75 );
    camera.updateProjectionMatrix();
   }
   function animate() {
    requestAnimationFrame( animate );
    update();
   }
   function update() {
    if ( isUserInteracting === false ) {
     lon += 0.1;
    }
    lat = Math.max( - 85, Math.min( 85, lat ) );
    phi = THREE.Math.degToRad( 90 - lat );
    theta = THREE.Math.degToRad( lon );
    camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
    //camera.target.y = 500 * Math.cos( phi ); // comment this to disable Y axis
    camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );
    camera.lookAt( camera.target );
    /*
    // distortion
    camera.position.copy( camera.target ).negate();
    */
    renderer.render( scene, camera );
   }
  </script>
 </body>
</html>