อัปเดต 5
สร้างซออื่นเพื่อแสดงสิ่งที่คาดหวังว่าจะมีลักษณะ มีการเพิ่ม skydome ที่มองไม่เห็นและ cubecamera และแผนที่สิ่งแวดล้อมใช้ ในกรณีของฉันไม่ควรใช้เทคนิคเหล่านี้ด้วยเหตุผลที่กล่าวถึงแล้ว
อัปเดต 4
สำคัญ: โปรดทราบว่ามีระนาบสะท้อนแสงที่ด้านหลังของตาข่ายเป้าหมายซึ่งใช้สำหรับสังเกตว่าพื้นผิวนั้นผูกกับพื้นผิวตาข่ายอย่างถูกต้องหรือไม่ไม่มีอะไรเกี่ยวข้องกับสิ่งที่ฉันกำลังพยายามแก้ไข
อัปเดต 3
สร้างซอใหม่เพื่อแสดงสิ่งที่ไม่ใช่พฤติกรรมที่คาดหวัง
- รหัส
บางทีฉันควรจะเรียบเรียงคำถามของฉันใหม่ แต่ฉันขาดความรู้ในการอธิบายอย่างถูกต้องเกี่ยวกับสิ่งที่ฉันกำลังพยายามแก้ไขโปรดช่วย .. อาจจะ .. ?)
อัปเดต 2
(เลิกใช้แล้วเนื่องจากมีการใช้ข้อมูลโค้ด)
ปรับปรุง
ตกลง .. ฉันได้เพิ่ม 3 วิธี:
TransformUv
ยอมรับรูปทรงเรขาคณิตและวิธีการแปลงซึ่งจัดการการเปลี่ยนรูปแบบยูวี การเรียกกลับยอมรับอาร์เรย์ Uvs สำหรับแต่ละใบหน้าและที่สอดคล้องกันFace3
ของการgeometry.faces[]
เป็นพารามิเตอร์MatcapTransformer
เป็นการเรียกกลับตัวจัดการ uv-transform เพื่อทำการแปลง matcapและ
fixTextureWhenRotateAroundZAxis
ทำงานเหมือนสิ่งที่มีชื่อ
จนถึงขณะนี้ยังไม่มีfixTexture..
วิธีการใดที่สามารถใช้งานร่วมกันfixTextureWhenRotateAroundXAxis
ได้ทั้งหมด ปัญหายังคงไม่ได้รับการแก้ไขฉันหวังว่าสิ่งที่เพิ่งเพิ่มเข้ามาจะช่วยให้คุณช่วยเหลือฉันได้
ฉันกำลังพยายามทำให้พื้นผิวของตาข่ายต้องเผชิญกับกล้องเปอร์สเปคทีฟอยู่เสมอไม่ว่าตำแหน่งญาติจะเป็นอะไร
สำหรับการสร้างกรณีจริงของฉากของฉันและการโต้ตอบจะค่อนข้างซับซ้อนฉันได้สร้างตัวอย่างเล็กน้อยเพื่อแสดงให้เห็นถึงความตั้งใจของฉัน
- รหัส
var MatcapTransformer=function(uvs, face) { for(var i=uvs.length; i-->0;) { uvs[i].x=face.vertexNormals[i].x*0.5+0.5; uvs[i].y=face.vertexNormals[i].y*0.5+0.5; } }; var TransformUv=function(geometry, xformer) { // The first argument is also used as an array in the recursive calls // as there's no method overloading in javascript; and so is the callback. var a=arguments[0], callback=arguments[1]; var faceIterator=function(uvFaces, index) { xformer(uvFaces[index], geometry.faces[index]); }; var layerIterator=function(uvLayers, index) { TransformUv(uvLayers[index], faceIterator); }; for(var i=a.length; i-->0;) { callback(a, i); } if(!(i<0)) { TransformUv(geometry.faceVertexUvs, layerIterator); } }; var SetResizeHandler=function(renderer, camera) { var callback=function() { renderer.setSize(window.innerWidth, window.innerHeight); camera.aspect=window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); }; // bind the resize event window.addEventListener('resize', callback, false); // return .stop() the function to stop watching window resize return { stop: function() { window.removeEventListener('resize', callback); } }; }; (function() { var fov=45; var aspect=window.innerWidth/window.innerHeight; var loader=new THREE.TextureLoader(); var texture=loader.load('https://i.postimg.cc/mTsN30vx/canyon-s.jpg'); texture.wrapS=THREE.RepeatWrapping; texture.wrapT=THREE.RepeatWrapping; texture.center.set(1/2, 1/2); var geometry=new THREE.SphereGeometry(1, 16, 16); var material=new THREE.MeshBasicMaterial({ 'map': texture }); var mesh=new THREE.Mesh(geometry, material); var geoWireframe=new THREE.WireframeGeometry(geometry); var matWireframe=new THREE.LineBasicMaterial({ 'color': 'red', 'linewidth': 2 }); mesh.add(new THREE.LineSegments(geoWireframe, matWireframe)); var camera=new THREE.PerspectiveCamera(fov, aspect); camera.position.setZ(20); var scene=new THREE.Scene(); scene.add(mesh); { var mirror=new THREE.CubeCamera(.1, 2000, 4096); var geoPlane=new THREE.PlaneGeometry(16, 16); var matPlane=new THREE.MeshBasicMaterial({ 'envMap': mirror.renderTarget.texture }); var plane=new THREE.Mesh(geoPlane, matPlane); plane.add(mirror); plane.position.setZ(-4); plane.lookAt(mesh.position); scene.add(plane); } var renderer=new THREE.WebGLRenderer(); var container=document.getElementById('container1'); container.appendChild(renderer.domElement); SetResizeHandler(renderer, camera); renderer.setSize(window.innerWidth, window.innerHeight); var fixTextureWhenRotateAroundYAxis=function() { mesh.rotation.y+=0.01; texture.offset.set(mesh.rotation.y/(2*Math.PI), 0); }; var fixTextureWhenRotateAroundZAxis=function() { mesh.rotation.z+=0.01; texture.rotation=-mesh.rotation.z TransformUv(geometry, MatcapTransformer); }; // This is wrong var fixTextureWhenRotateAroundAllAxis=function() { mesh.rotation.y+=0.01; mesh.rotation.x+=0.01; mesh.rotation.z+=0.01; // Dun know how to do it correctly .. texture.offset.set(mesh.rotation.y/(2*Math.PI), 0); }; var controls=new THREE.TrackballControls(camera, container); renderer.setAnimationLoop(function() { fixTextureWhenRotateAroundYAxis(); // Uncomment the following line and comment out `fixTextureWhenRotateAroundYAxis` to see the demo // fixTextureWhenRotateAroundZAxis(); // fixTextureWhenRotateAroundAllAxis(); // controls.update(); plane.visible=false; mirror.update(renderer, scene); plane.visible=true; renderer.render(scene, camera); }); })();
body { background-color: #000; margin: 0px; overflow: hidden; }
<script src="https://threejs.org/build/three.min.js"></script> <script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script> <div id='container1'></div>
โปรดทราบว่าแม้ว่าตาข่ายจะหมุนเองในการสาธิตนี้ความตั้งใจจริงของฉันคือการทำให้กล้องเคลื่อนที่เหมือนกับการโคจรรอบตาข่าย
ฉันได้เพิ่มโครงลวดเพื่อทำให้การเคลื่อนไหวชัดเจนยิ่งขึ้น อย่างที่คุณเห็นฉันใช้fixTextureWhenRotateAroundYAxis
ในการทำอย่างถูกต้อง แต่เป็นเพียงแกน y mesh.rotation.y
ในรหัสจริงของฉันจะถูกคำนวณสิ่งที่ต้องการ
var ve=camera.position.clone();
ve.sub(mesh.position);
var rotY=Math.atan2(ve.x, ve.z);
var offsetX=rotY/(2*Math.PI);
อย่างไรก็ตามฉันขาดความรู้เกี่ยวกับวิธีการทำfixTextureWhenRotateAroundAllAxis
อย่างถูกต้อง มีข้อ จำกัด บางประการในการแก้ไขปัญหานี้:
ไม่สามารถใช้ CubeCamera / CubeMap เนื่องจากเครื่องไคลเอ็นต์อาจมีปัญหาประสิทธิภาพการทำงาน
อย่าทำให้
lookAt
กล้องเป็นตาข่ายในขณะที่มีรูปทรงเรขาคณิตในที่สุดไม่เพียง แต่เป็นรูปทรงกลมเท่านั้น เทคนิคเหมือนlookAt
และคืนค่า.quaternion
ในเฟรมจะโอเค
โปรดอย่าเข้าใจฉันผิดที่ฉันกำลังถามปัญหา XY เนื่องจากฉันไม่มีสิทธิ์ที่จะเปิดเผยรหัสกรรมสิทธิ์หรือฉันจะไม่ต้องใช้ความพยายามในการสร้างตัวอย่างเล็ก ๆ น้อย ๆ :)