2017-02-05 6 views
1

Wie würde ich ein 2D-Sprite unter einem 3D-Objekt auf einer Ebene hinzufügen, um zu zeigen, dass meine Objekte markiert/ausgewählt sind?ThreeJS Highlight/Projector

Auch, wie würde ich das auf unebenem Gelände tun?

Ich füge ein Beispielbild, um besser meine Frage zu erklären:

enter image description here

Antwort

2

Ich bin nicht sicher, dass ein Sprite ist eine gute Idee.

Wie Sie über unebenes Gelände gesagt haben, ist es besser, etwas nicht flach zu verwenden. Zum Beispiel eine Kugel oder ein Zylinder mit einem Material mit .alphaMap.

Wir brauchen etwas Ring-wie für unsere Wirkung der Auswahl.

enter image description here

Nehmen wir an, Sie wählte Kugel, dann können Sie ihr Material des alphaMap aus einer Datei oder eine dynamisch erzeugte Textur aus Leinwand gesetzt:

// alpha texture 
var canvas = document.createElement("canvas"); 
canvas.width = 128; 
canvas.height = 128; 
var ctx = canvas.getContext("2d"); 
var gradient = ctx.createLinearGradient(0, 0, 0, 128); 
gradient.addColorStop(0.35, "black"); 
gradient.addColorStop(0.475, "white"); 
gradient.addColorStop(0.525, "white"); 
gradient.addColorStop(0.65, "black"); 
ctx.fillStyle = gradient; 
ctx.fillRect(0, 0, 128, 128); 
var alphaTexture = new THREE.Texture(canvas); 
alphaTexture.needsUpdate = true; 

Über .alphaMap:

Die Alphakarte ist eine Graustufentextur, die die Opazität über die Oberfläche steuert (schwarz: vollständig transparent; weiß: vollständig deckend). Der Standardwert ist null. Nur die Farbe der Textur wird verwendet, wobei der Alpha-Kanal ignoriert wird, falls einer existiert. Bei RGB- und RGBA-Texturen verwendet der WebGL-Renderer beim Abtasten dieser Textur den grünen Kanal, da in DXT-komprimierten und unkomprimierten RGB 565-Formaten eine zusätzliche Genauigkeit für Grün zur Verfügung steht. Nur-Luminanz- und Luminanz/Alpha-Texturen funktionieren ebenfalls wie erwartet.

Deshalb haben wir dort nur schwarz und weiß.

Lasst uns ein Objekt der simpliest NPC mit einem gelben Ring schaffen, die darauf hinweist, dass unsere NPC ausgewählt ist:

var npc = function() { 
    var geom = new THREE.SphereGeometry(4, 4, 2); 
    geom.translate(0, 4, 0); 
    var mesh = new THREE.Mesh(geom, new THREE.MeshLambertMaterial({ 
    color: Math.random() * 0xffffff 
    })); 

    // highlighter 
    geom.computeBoundingSphere(); 
    var sphereGeom = new THREE.SphereGeometry(geom.boundingSphere.radius, 32, 24); 
    var sphereMat = new THREE.MeshBasicMaterial({ 
    color: "yellow", // yellow ring 
    transparent: true, // to make our alphaMap work, we have to set this parameter to `true` 
    alphaMap: alphaTexture 
    }); 
    var sphere = new THREE.Mesh(sphereGeom, sphereMat); 
    sphere.visible = false; 
    mesh.add(sphere); 
    mesh.userData.direction = new THREE.Vector3(Math.random() - 0.5, 0, Math.random() - 0.5).normalize(); 
    mesh.userData.speed = Math.random() * 5 + 5; 
    mesh.position.set(
    Math.random() * (worldWidth - 10) - (worldWidth - 10) * 0.5, 
    10, 
    Math.random() * (worldDepth - 10) - (worldDepth - 10) * 0.5 
); 
    scene.add(mesh); 
    return mesh; 
} 

Der Rest ist nicht so schwierig. Wir brauchen eine Reihe von unserer NPCs, die wir für Kreuzung

var npcs = []; 
for (var i = 0; i < 10; i++) { 
    npcs.push(npc()); 
} 

überprüfen werden und dann auf mousedown Veranstaltung werden wir unsere ein NPC wählen (aus dem Beispiel interactive cubes genommen und für unsere Bedürfnisse modifiziert):

window.addEventListener('mousedown', onMouseDown, false); 

function onMouseDown(event) { 
    if (event.button != 2) return; 
    mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
    mouse.y = -(event.clientY/window.innerHeight) * 2 + 1; 

    selector.setFromCamera(mouse, camera); 
    var intersects = selector.intersectObjects(npcs); 
    if (intersects.length > 0) { 
     if (INTERSECTED != intersects[ 0 ].object) { 
     if (INTERSECTED) INTERSECTED.children[0].visible = INTERSECTED.selected; 
     INTERSECTED = intersects[ 0 ].object; 
     INTERSECTED.selected = INTERSECTED.children[0].visible; 
     INTERSECTED.children[0].visible = true; 
     } 
    } else { 
     if (INTERSECTED) INTERSECTED.children[0].visible = INTERSECTED.selected; 
     INTERSECTED = null; 
    } 
} 

jsfiddle Beispiel. Hier können Sie Objekte mit der rechten Maustaste auswählen.

+0

Wow! Was für eine detaillierte Antwort mit einem Beispiel, schätze ich Ihre Zeit und Hilfe! Vielen Dank! – gregmax17

+1

@ gregmax17 Gern geschehen. Ich war froh zu helfen;) – prisoner849