three.js全景視訊
阿新 • • 發佈:2019-01-25
小生最近學習three.js,將three.js官網提供的網站例項翻譯翻譯,共同學習。接下來翻譯一下 webgl_video_panorama_equirectangular.html
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - equirectangular video 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> <script src="../build/three.js"></script> <script> //原理:通過three.js建立一個球模型,將視訊貼到球模型上,通過矩陣變換將視訊貼到模型內部,觀察點不動,通過滑鼠拖動,改變相機的位置來實現全景視訊的觀看。 //當然需要將模型新增到場景中,通過渲染器不斷的渲染 var camera, scene, renderer; var texture_placeholder,//多餘程式碼 isUserInteracting = false,//滑鼠按下的標誌,開始滑鼠沒有按下為false onMouseDownMouseX = 0, onMouseDownMouseY = 0, lon = 0,//記錄水平方向的偏角,即水平角 onMouseDownLon = 0,//多餘程式碼 lat = 0,//記錄豎直方向的偏角,即仰俯角 onMouseDownLat = 0,//多餘程式碼 phi = 0,//在three.js中 phi代表與xoy平面的夾角,即仰俯角 theta = 0, //theta代表與xoy平面的夾角, 即水平角 distance = 500,//觀察點到相機的距離,即球半徑 onPointerDownPointerX = 0,//記錄滑鼠按下瞬間的螢幕x值 onPointerDownPointerY = 0,//記錄滑鼠按下瞬間的螢幕x值 onPointerDownLon = 0,//記錄上一次滑鼠水平移動的角度. onPointerDownLat = 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 );//建立半徑為500,水平垂直分割面分別為60,40的緩衝球面 geometry.scale( -1, 1, 1 );//進行縮放,進行矩陣變換,將視訊貼在球內表面 var video = document.createElement( 'video' ); video.width = 640; video.height = 360; video.loop = true;//視訊是否迴圈 video.muted = true;//是否關閉音訊 video.src = "textures/pano.webm"; video.setAttribute( 'webkit-playsinline', 'webkit-playsinline' ); video.play(); var texture = new THREE.VideoTexture( video );//視訊紋理 texture.minFilter = THREE.LinearFilter;//紋理在縮小時的過濾方式,預設THREE.LinearMipMapNearestFilter選擇最臨近的mip層,並執行線性過濾 texture.format = THREE.RGBFormat;//畫素資料的顏色格式, 預設為THREE.RGBAFormat,還有以下可選引數 //THREE.AlphaFormat = 1019; //GL_ALPHA Alpha 值 //THREE.RGBFormat = 1020; //Red, Green, Blue 三原色值 //THREE.RGBAFormat = 1021; //Red, Green, Blue 和 Alpha 值 //THREE.LuminanceFormat = 1022; //灰度值 //THREE.LuminanceAlphaFormat = 1023; //灰度值和 Alpha 值 var material = new THREE.MeshBasicMaterial({ map: texture });//基礎網孔材料 mesh = new THREE.Mesh( geometry, material ); scene.add( mesh ); renderer = new THREE.WebGLRenderer();//webGL渲染器 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 ); // 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; onPointerDownPointerX = event.clientX; onPointerDownPointerY = event.clientY; onPointerDownLon = lon; onPointerDownLat = lat; } function onDocumentMouseMove( event ) { if ( isUserInteracting === true ) { //按下並移動,計算移動的角度 lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon; lat = ( onPointerDownPointerY -event.clientY ) * 0.1 + onPointerDownLat; } } //滑鼠擡起 function onDocumentMouseUp( event ) { isUserInteracting = false; } //滑鼠滾輪操作,改變相機位置 function onDocumentMouseWheel( event ) { distance += event.deltaY * 0.05; } function animate() { requestAnimationFrame( animate ); update(); } function update() { //將角度轉化為弧度 lat = Math.max( - 85, Math.min( 85, lat ) ); phi = THREE.Math.degToRad( 90 - lat ); theta = THREE.Math.degToRad( lon ); //球面座標計算公式,相當於相機在球面移動,觀察點不動 camera.position.x = distance * Math.sin( phi ) * Math.cos( theta ); camera.position.y = distance * Math.cos( phi ); camera.position.z = distance * Math.sin( phi ) * Math.sin( theta ); camera.lookAt( camera.target ); /* // distortion camera.position.copy( camera.target ).negate(); */ //渲染 renderer.render( scene, camera ); }