まず、ここでは(ほとんど)のために書き直さあなたの関数の例で最適なパフォーマンス、renderloopが明らかに呼び出す行うに説明するための単なる一例である:
var width = renderer.context.canvas.width;
var height = renderer.context.canvas.height;
// has to be called whenever the canvas-size changes
function onCanvasResize() {
width = renderer.context.canvas.width;
height = renderer.context.canvas.height;
});
var projMatrix = new THREE.Matrix4();
// renderloop-function, called per animation-frame
function render() {
// just needed once per frame (even better would be
// once per camera-movement)
projMatrix.multiplyMatrices(
camera.projectionMatrix,
projMatrix.getInverse(camera.matrixWorld)
);
hudObjects.forEach(function(obj) {
toScreenPosition(obj, projMatrix);
});
}
// wrapped in IIFE to store the local vector-variable (this pattern
// is used everywhere in three.js)
var toScreenPosition = (function() {
var vector = new THREE.Vector3();
return function __toScreenPosition(obj, projectionMatrix) {
// this could potentially be left away, but isn't too
// expensive as there are 'needsUpdate'-checks in place
obj.updateMatrixWorld();
vector.setFromMatrixPosition(obj.matrixWorld);
vector.applyMatrix4(projectionMatrix);
vector.x = (vector.x + 1) * width/2;
vector.y = (1 - vector.y) * height/2;
// might want to consider returning a Vector3-instance
// instead, depends on how the result is used
return {x: vector.x, y: vector.y};
}
})();
しかし、 HUDをレンダリングしたいと考えると、メインシーンとは独立して、上記の計算をすべて廃止し、HUD要素のサイズと配置のために異なる座標系を選択することができます。
ここには例としてhttps://codepen.io/usefulthink/pen/ZKPvPBがあります。そこでは、正射投影カメラと別のシーンを使用して、3Dシーンの上にHUD-Elementsをレンダリングしました。余分な計算は必要ありません。また、HUD要素のサイズと位置をピクセル単位で指定することもできます(パースペクティブカメラを使用しても同じことができますが、これを正しく行うには三角法を必要とします)。
関数が呼び出されるたびに新しい 'THREE.Vector3'をインスタンス化しないでください。それを作成して再利用してください。関数が戻るときに新しいオブジェクトをインスタンス化しないでください。すべての呼び出しで 'width/heighHalf'を再計算しないでください。また、 'obj.updateMatrixWorld()'も呼び出さないでください。レンダラーはフレームごとにそれを呼び出します。 – WestLangley
@WestLangleyあなたのソリューションをテストしましたか?私はそれが私の問題を解決することができないと思う100以上の2次元の画面で位置を計算するシーンの泥オブジェクト。私は今object3dを使用していないので、object3dの中心点をVector3だけと言って計算してください。 –
@WestLangleyが書いたことはほぼ普遍的に真実であり、ある程度パフォーマンスを向上させるでしょう。しかし、十分ではないかもしれません。もう一つの可能な最適化は '.project()' -callです。これは内部的にカメラのmatrixWorldInverseを計算する必要がありますが、これは非常に高価な操作です。フレーム全体に渡って変換行列の計算をキャッシュする方法で再実装することを検討する必要があります:https://github.com/mrdoob/three.js/blob/ae2cda96f52b763b27b9c0cf77f1a9ed498fd706/src/math/Vector3.js#L318 -L323 - あなたはJSがうまく処理できるいくつかの計算を残します –