আপডেট 5
যা প্রত্যাশিত তা দেখতে কেমন হবে তা দেখাতে অন্য একটি ফ্রিডল তৈরি করেছে। একটি অদৃশ্য স্কাইডোম এবং একটি কিউবিকামেরা যুক্ত করা হয় এবং পরিবেশের মানচিত্র ব্যবহৃত হয়; আমার ক্ষেত্রে, এই প্রযুক্তিগুলির কোনওটি ইতিমধ্যে উল্লিখিত কারণে ব্যবহার করা উচিত নয়।
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 cubeCam = new THREE.CubeCamera(.1, 200, 4096);
cubeCam.renderTarget.texture.wrapS = THREE.RepeatWrapping;
cubeCam.renderTarget.texture.wrapT = THREE.RepeatWrapping;
cubeCam.renderTarget.texture.center.set(1 / 2, 1 / 2);
var geoSky = new THREE.SphereGeometry(2, 16, 16);
var matSky = new THREE.MeshBasicMaterial({
'map': texture,
'side': THREE.BackSide
});
var meshSky = new THREE.Mesh(geoSky, matSky);
meshSky.visible = false;
var geometry = new THREE.IcosahedronGeometry(1, 1);
var material = new THREE.MeshBasicMaterial({
'envMap': cubeCam.renderTarget.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);
scene.add(meshSky);
{
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 controls = new THREE.TrackballControls(camera, container);
var fixTextureWhenRotateAroundAllAxis = function() {
mesh.rotation.y += 0.01;
mesh.rotation.x += 0.01;
mesh.rotation.z += 0.01;
cubeCam.update(renderer, scene);
};
renderer.setAnimationLoop(function() {
// controls.update();
plane.visible = false;
{
meshSky.visible = true;
mesh.visible = false;
fixTextureWhenRotateAroundAllAxis();
mesh.visible = true;
meshSky.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>
আপডেট 4
গুরুত্বপূর্ণ: দয়া করে নোট করুন জাল পৃষ্ঠার পিছনে একটি প্রতিফলিত বিমান রয়েছে যা পর্যবেক্ষণ করার জন্য যদি টেক্সচারটি জাল পৃষ্ঠকে সঠিকভাবে বেঁধে রাখে, আমি সমাধান করার চেষ্টা করছি এর সাথে এর কোনও সম্পর্ক নেই।
আপডেট 3
প্রত্যাশিত আচরণটি কী নয় তা দেখাতে একটি নতুন ফিজল তৈরি করেছে
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);
}
};
};
var getVertexShader=function() {
return `
void main() {
gl_Position=projectionMatrix*modelViewMatrix*vec4(position, 1.0);
}
`;
};
var getFragmentShader=function(size) {
return `
uniform sampler2D texture1;
const vec2 size=vec2(`+size.x+`, `+size.y+`);
void main() {
gl_FragColor=texture2D(texture1, gl_FragCoord.xy/size.xy);
}
`;
};
(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 geometry=new THREE.BoxGeometry(2, 2, 2);
// var material=new THREE.MeshBasicMaterial({ 'map': texture });
var material=new THREE.ShaderMaterial({
'uniforms': { 'texture1': { 'type': 't', 'value': texture } }
, 'vertexShader': getVertexShader()
, 'fragmentShader': getFragmentShader({ 'x': 512, 'y': 256 })
});
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);
};
var fixTextureWhenRotateAroundAllAxis=function() {
mesh.rotation.y+=0.01;
mesh.rotation.x+=0.01;
mesh.rotation.z+=0.01;
};
var controls=new THREE.TrackballControls(camera, container);
renderer.setAnimationLoop(function() {
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>
হতে পারে আমার প্রশ্নটির পুনঃব্যবহার করা উচিত, তবে আমি কী সমাধান করতে চাইছি সে সম্পর্কে সঠিকভাবে বর্ণনা করার মতো জ্ঞানের অভাব বোধ করছি, দয়া করে সহায়তা করুন .. (প্যানোরামিক-ট্রান্সফর্ম-উইথ টেক্সচার-লিকিং-এ-ডিরেক্টর-লকড-টু-দ্য ক্যামেরা হতে পারে .. ?)
আপডেট 2
(কোড স্নিপেট প্রয়োগ হওয়ার সাথে সাথে হ্রাস করা হয়েছে))
হালনাগাদ
ঠিক আছে .. আমি 3 টি পদ্ধতি যুক্ত করেছি:
TransformUv
জ্যামিতি এবং ট্রান্সফর্মার পদ্ধতি গ্রহণ করে যা ইউভি-ট্রান্সফর্মকে পরিচালনা করে। কলব্যাক প্রতিটি মুখের জন্য একটি Uvs অ্যারে এবং সংশ্লিষ্ট গ্রহণ Face3
এর geometry.faces[]
তার পরামিতি হিসেবে।
MatcapTransformer
ম্যাটক্যাপ রূপান্তর করতে ইউভি-ট্রান্সফর্ম হ্যান্ডলার কলব্যাক।
এবং
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
সঠিকভাবে করবেন তা সম্পর্কে আমার জ্ঞান নেই । এটি সমাধানের কিছু বিধিনিষেধ রয়েছে:
ক্লায়েন্ট মেশিনগুলির পারফরম্যান্স সমস্যা হতে পারে বলে কিউবক্যামেরা / কিউব্যাপ ব্যবহার করা যাবে না
কেবল জাল lookAt
ক্যামেরা তৈরি করবেন না কারণ শেষ পর্যন্ত তারা কোনও ধরণের জ্যামিতির হয়, কেবলমাত্র গোলকই নয়; একটি ফ্রেমে পছন্দ lookAt
এবং পুনরুদ্ধার কৌশলগুলি .quaternion
ঠিক হবে।
দয়া করে আমাকে ভুল করবেন না যে আমি মালিকানা কোড প্রকাশ করার অধিকার না থাকায় আমি এক্সওয়াই সমস্যা জিজ্ঞাসা করছি বা আমার একটি ন্যূনতম উদাহরণ তৈরির চেষ্টাটি দিতে হবে না :)