three.js
ऑब्जेक्ट पिकिंग
खोज…
ऑब्जेक्ट पिकिंग / रेकास्टिंग
रेकास्टिंग का मतलब है कि स्क्रीन पर माउस की पोजिशन से किरण को दृश्य में फेंकना, यह इस प्रकार है कि थ्रीजे यह निर्धारित करता है कि यदि आपने इसे लागू किया है तो आप किस ऑब्जेक्ट पर क्लिक करना चाहते हैं। थ्रीज को एक ओक्ट्री का उपयोग करके वह जानकारी मिलती है , लेकिन उत्पादन में आप प्रत्येक फ्रेम में या mousemove
इवेंट पर परिणाम की गणना नहीं करना चाहते हैं, बल्कि कम आवश्यकताओं के साथ अधिक सुलभ ऐप के लिए click
इवेंट पर।
var raycaster, mouse = { x : 0, y : 0 };
init();
function init () {
//Usual setup code here.
raycaster = new THREE.Raycaster();
renderer.domElement.addEventListener( 'click', raycast, false );
//Next setup code there.
}
function raycast ( e ) {
//1. sets the mouse position with a coordinate system where the center
// of the screen is the origin
mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
//2. set the picking ray from the camera position and mouse coordinates
raycaster.setFromCamera( mouse, camera );
//3. compute intersections
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
console.log( intersects[ i ] );
/*
An intersection has the following properties :
- object : intersected object (THREE.Mesh)
- distance : distance from camera to intersection (number)
- face : intersected face (THREE.Face3)
- faceIndex : intersected face index (number)
- point : intersection point (THREE.Vector3)
- uv : intersection point in the object's UV coordinates (THREE.Vector2)
*/
}
}
सावधान! यदि आप अगले भाग को नहीं पढ़ते हैं, तो आप अपना समय खाली स्क्रीन पर टकटकी लगाए रख सकते हैं।
यदि आप लाइट हेल्पर का पता लगाना चाहते हैं, तो raycaster.intersectObjects( scene.children );
का दूसरा पैरामीटर सेट करें raycaster.intersectObjects( scene.children );
सच करने के लिए।
इसका मतलब है raycaster.intersectObjects( scene.children , true);
रेकास्ट कोड केवल हल्के सहायक का पता लगाएगा।
यदि आप चाहते हैं कि यह सामान्य वस्तुओं के साथ-साथ हल्के सहायक का भी पता लगाए, तो आपको उपरोक्त रेकास्ट फ़ंक्शन को फिर से कॉपी करने की आवश्यकता है। इस प्रश्न को देखें।
पूरा रेकास्ट कोड है
function raycast ( e ) {
// Step 1: Detect light helper
//1. sets the mouse position with a coordinate system where the center
// of the screen is the origin
mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
//2. set the picking ray from the camera position and mouse coordinates
raycaster.setFromCamera( mouse, camera );
//3. compute intersections (note the 2nd parameter)
var intersects = raycaster.intersectObjects( scene.children, true );
for ( var i = 0; i < intersects.length; i++ ) {
console.log( intersects[ i ] );
/*
An intersection has the following properties :
- object : intersected object (THREE.Mesh)
- distance : distance from camera to intersection (number)
- face : intersected face (THREE.Face3)
- faceIndex : intersected face index (number)
- point : intersection point (THREE.Vector3)
- uv : intersection point in the object's UV coordinates (THREE.Vector2)
*/
}
// Step 2: Detect normal objects
//1. sets the mouse position with a coordinate system where the center
// of the screen is the origin
mouse.x = ( e.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( e.clientY / window.innerHeight ) * 2 + 1;
//2. set the picking ray from the camera position and mouse coordinates
raycaster.setFromCamera( mouse, camera );
//3. compute intersections (no 2nd parameter true anymore)
var intersects = raycaster.intersectObjects( scene.children );
for ( var i = 0; i < intersects.length; i++ ) {
console.log( intersects[ i ] );
/*
An intersection has the following properties :
- object : intersected object (THREE.Mesh)
- distance : distance from camera to intersection (number)
- face : intersected face (THREE.Face3)
- faceIndex : intersected face index (number)
- point : intersection point (THREE.Vector3)
- uv : intersection point in the object's UV coordinates (THREE.Vector2)
*/
}
}
ऑब्जेक्ट पिकिंग / जीपीयू
रेकास्टिंग का उपयोग करते हुए ऑब्जेक्ट चुनना आपके सेटअप के आधार पर आपके सीपीयू के लिए एक भारी काम हो सकता है (उदाहरण के लिए यदि आपके पास सेटअप जैसा ऑक्ट्री नहीं है) और दृश्य में वस्तुओं की संख्या।
यदि आपको माउस कर्सर के तहत दुनिया के निर्देशांक की आवश्यकता नहीं है, लेकिन केवल उस वस्तु की पहचान करने के लिए जिसके तहत आप GPU पिकिंग का उपयोग कर सकते हैं।
संक्षिप्त विवरण, GPU कम्प्यूटेशन के लिए एक शक्तिशाली उपकरण हो सकता है लेकिन आपको यह जानना होगा कि परिणाम कैसे प्राप्त करें। विचार यह है, यदि आप वस्तुओं को एक रंग के साथ प्रस्तुत करते हैं जो उनकी आईडी का प्रतिनिधित्व करता है, तो आप कर्सर के नीचे पिक्सेल का रंग पढ़ सकते हैं और उस ऑब्जेक्ट की आईडी ढूंढ सकते हैं जिसे चुना गया है। याद रखें RGB सिर्फ एक हेक्स वैल्यू है इसलिए आईडी (पूर्णांक) और रंग (हेक्स) के बीच एक रूपांतरण मौजूद है।
- अपनी वस्तु के लिए एक नया दृश्य और एक नया प्रतिपादन लक्ष्य बनाएँ
var pickingScene = new THREE.Scene();
var pickingTexture = new THREE.WebGLRenderTarget(renderer.domElement.clientWidth, renderer.domElement.clientHeight);
pickingTexture.texture.minFilter = THREE.LinearFilter;
- ऑब्जेक्ट पिकिंग के लिए एक नया shader सामग्री बनाएं;
var vs3D = `
attribute vec3 idcolor;
varying vec3 vidcolor;
void main(){
vidcolor = idcolor;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0);
}`;
var fs3D = `
varying vec3 vidcolor;
void main(void) {
gl_FragColor = vec4(vidcolor,1.0);
}`;
var pickingMaterial = new THREE.ShaderMaterial(
{
vertexShader: vs3D,
fragmentShader: fs3D,
transparent: false,
side: THREE.DoubleSide
});
- अपने जाल / रेखा ज्यामिति को RGB में उनकी आईडी का प्रतिनिधित्व करने वाली एक नई विशेषता जोड़ें, एक ही ज्यामिति का उपयोग करके pickObject बनाएं और इसे पिकिंग दृश्य में जोड़ें, और वास्तविक जाल को एक id-> ऑब्जेक्ट डिक्शनरी में जोड़ें
var selectionObjects = [];
for(var i=0; i<myMeshes.length; i++){
var mesh = myMeshes[i];
var positions = mesh.geometry.attributes["position"].array;
var idColor = new Float32Array(positions.length);
var color = new THREE.Color();
color.setHex(mesh.id);
for (var j=0; j< positions.length; j+=3){
idColor[j] = color.r;
idColor[j+1] = color.g;
idColor[j+2] = color.b;
}
mesh.geometry.addAttribute('idcolor', new THREE.BufferAttribute(idColor, 3));
var pickingObject = new THREE.Mesh(mesh.geometry, pickingMaterial);
pickingScene.add(pickingObject);
selectionObjects[mesh.id] = mesh;
}
- अंत में, अपने माउस क्लिक हैंडलर पर
renderer.render(pickingScene, camera, pickingTexture);
var pixelBuffer = new Uint8Array(4);
renderer.readRenderTargetPixels(pickingTexture, event.pageX, pickingTexture.height - event.pageY, 1, 1, pixelBuffer);
var id = (pixelBuffer[0] << 16) | (pixelBuffer[1] << 8) | (pixelBuffer[2]);
if (id>0){
//this is the id of the picked object
}else{
//it's 0. clicked on an empty space
}