簡體   English   中英

我如何找出從理光Theta S Dual FIsh Eye到Three.js r71 SphereGeometry的UV映射

[英]How do I figure out the UV Mapping from Ricoh Theta S Dual FIsh Eye to a Three.js r71 SphereGeometry

我正在嘗試使用Three.js r71重現Three.js全景圖doublefisheye示例

我需要堅持使用r71,因為最終我將在基於Three.js r71的Autodesk Forge Viewer上使用此代碼。

我取得了一些進展,但是在找出UV貼圖時需要幫助。

如果將來自此鏈接three.js panaorama dualfisheye示例的結果與代碼片段進行比較, 則會發現問題很嚴重

  var camera, scene, renderer; var isUserInteracting = false, onMouseDownMouseX = 0, onMouseDownMouseY = 0, lon = 0, onMouseDownLon = 0, lat = 0, onMouseDownLat = 0, phi = 0, theta = 0, distance = 500; init(); animate(); function init() { var container, mesh; container = document.getElementById('container'); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000); scene = new THREE.Scene(); // var geometry = new THREE.SphereBufferGeometry( 500, 60, 40 ).toNonIndexed(); var geometry = new THREE.SphereGeometry(500, 60, 40); // invert the geometry on the x-axis so that all of the faces point inward // geometry.scale( - 1, 1, 1 ); geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1)); /* // Remap UVs // var normals = geometry.attributes.normal.array; var normals = []; geometry.faces.forEach(element => { normals.push(element.normal) }); var uvs = geometry.faceVertexUvs // var uvs = geometry.attributes.uv.array; for (var i = 0, l = normals.length / 3; i < l; i++) { var x = normals[i * 3 + 0]; var y = normals[i * 3 + 1]; var z = normals[i * 3 + 2]; if (i < l / 2) { var correction = (x == 0 && z == 0) ? 1 : (Math.acos(y) / Math.sqrt(x * x + z * z)) * (2 / Math.PI); uvs[i * 2 + 0] = x * (404 / 1920) * correction + (447 / 1920); uvs[i * 2 + 1] = z * (404 / 1080) * correction + (582 / 1080); } else { var correction = (x == 0 && z == 0) ? 1 : (Math.acos(- y) / Math.sqrt(x * x + z * z)) * (2 / Math.PI); uvs[i * 2 + 0] = - x * (404 / 1920) * correction + (1460 / 1920); uvs[i * 2 + 1] = z * (404 / 1080) * correction + (582 / 1080); } } */ // geometry.rotateZ( - Math.PI / 2 ); geometry.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI / 2)) THREE.ImageUtils.crossOrigin = ''; var texture = THREE.ImageUtils.loadTexture('https://threejs.org/examples/textures/ricoh_theta_s.jpg'); this.texture = texture; texture.format = THREE.RGBFormat; var material = new THREE.MeshBasicMaterial({ map: texture }); material.map.repeat.set(1, 1); material.map.offset.set(0, 0); 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); 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; distance = THREE.Math.clamp(distance, 400, 1000); } 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 - 180); 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(scene.position); renderer.render(scene, camera); } 
  body { background-color: #000000; margin: 0px; overflow: hidden; } 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/71/three.js"></script> <div id="container"></div> 

感謝您的時間。

使用Geometry而不是BufferGeometry時,法線是每個面( face.vertexNormals ),是Vector3的數組。 uv是Vector2s數組的數組。

someVector2 = geometry.faceVertexUvs[setNdx][faceNdx][vertexNdx]

 var camera, scene, renderer; var isUserInteracting = false, onMouseDownMouseX = 0, onMouseDownMouseY = 0, lon = 0, onMouseDownLon = 0, lat = 0, onMouseDownLat = 0, phi = 0, theta = 0, distance = 500; init(); animate(); function init() { var container, mesh; container = document.getElementById('container'); camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000); scene = new THREE.Scene(); var geometry = new THREE.SphereGeometry(500, 60, 40); // invert the geometry on the x-axis so that all of the faces point inward geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1)); // Remap UVs var uvs = geometry.faceVertexUvs[0]; geometry.faces.forEach((face, ndx) => { const faceUVs = uvs[ndx]; for (var i = 0; i < 3; ++i) { const faceNormal = face.vertexNormals[i]; var x = faceNormal.x; var y = faceNormal.y; var z = faceNormal.z; if (ndx < geometry.faces.length / 2) { var correction = (x == 0 && z == 0) ? 1 : (Math.acos(y) / Math.sqrt(x * x + z * z)) * (2 / Math.PI); faceUVs[i].x = x * (404 / 1920) * correction + (447 / 1920); faceUVs[i].y = z * (404 / 1080) * correction + (582 / 1080); } else { var correction = (x == 0 && z == 0) ? 1 : (Math.acos(- y) / Math.sqrt(x * x + z * z)) * (2 / Math.PI); faceUVs[i].x = - x * (404 / 1920) * correction + (1460 / 1920); faceUVs[i].y = z * (404 / 1080) * correction + (582 / 1080); } } }); geometry.applyMatrix(new THREE.Matrix4().makeRotationZ(Math.PI / 2)) THREE.ImageUtils.crossOrigin = ''; var texture = THREE.ImageUtils.loadTexture('https://threejs.org/examples/textures/ricoh_theta_s.jpg'); this.texture = texture; texture.format = THREE.RGBFormat; var material = new THREE.MeshBasicMaterial({ map: texture }); material.map.repeat.set(1, 1); material.map.offset.set(0, 0); 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); 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; distance = THREE.Math.clamp(distance, 400, 1000); } 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 - 180); 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(scene.position); renderer.render(scene, camera); } 
 body { background-color: #000000; margin: 0px; overflow: hidden; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/71/three.js"></script> <div id="container"></div> 

讓我指出,我是通過運行示例,然后在Chrome中打開devtools,放置斷點並檢查變量來解決這一問題的。

這是uvs

在此處輸入圖片說明

這是頂點法線

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM