업데이트 5
기대되는 모습을 보여주는 또 다른 바이올린을 만들었습니다. 보이지 않는 skydome과 cubecamera가 추가되고 환경 맵이 사용됩니다. 필자의 경우 이미 언급 한 이유로 이러한 기술을 사용해서는 안됩니다.
업데이트 4
중요 : 텍스처가 메쉬 표면에 올바르게 바인딩되는지 관찰하기 위해 대상 메쉬 뒤에 반사 평면이 있으며, 해결하려는 것과는 아무런 관련이 없습니다.
업데이트 3
예상되는 행동이 아닌 것을 보여주기 위해 새로운 바이올린을 만들었습니다.
- 암호
어쩌면 나는 내 질문을 바꿔야하지만, 해결하려고하는 것에 대해 정확하게 설명 할 지식이 부족합니다 .. 아마도 .. ?)
업데이트 2
(코드 스 니펫이 적용되면 더 이상 사용되지 않습니다.)
최신 정보
확인 .. 3 가지 방법을 추가했습니다.
TransformUv
기하학과 UV 변환을 처리하는 변환기 방법을 허용합니다. 콜백은 UV를 각 얼굴 어레이 및 대응 수용Face3
의geometry.faces[]
해당 파라미터로한다.MatcapTransformer
matcap 변환을 수행하는 uv 변환 핸들러 콜백입니다.과
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 문제를 묻는 것이 잘못되지 않습니다. :)