アップデート5
別のフィドルを作成して、予想される内容を示します。非表示のスカイドームとキューブカメラが追加され、環境マップが使用されます。私の場合、すでに述べた理由のため、これらの手法はどれも使用すべきではありません。
アップデート4
重要:ターゲットメッシュの後ろに反射面があることに注意してください。これは、テクスチャがメッシュサーフェスに正しくバインドされているかどうかを観察するためのものであり、解決しようとしていることとは関係ありません。
アップデート3
新しいフィドルを作成して、予期された動作ではないものを示します
- コード
多分私は私の質問を言い換えるべきですが、私が解決しようとしていることについて正確に説明する知識が不足しています、助けてください..(Panoramic-Transform-With-Texture-Looking-At-Direction-Locked-Onto-The-Camera多分 .. ?)
アップデート2
(コードスニペットが適用されたため、非推奨になりました。)
更新
OK .. 3つのメソッドを追加しました:
TransformUv
ジオメトリと、uv変換を処理する変換メソッドを受け入れます。コールバックは、各面と対応するFace3
のuvs配列を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問題を求めていることを誤解しないでください:)