Three.js:改变精灵的枢轴点 [英] Three.js: change the pivot point of a sprite

查看:58
本文介绍了Three.js:改变精灵的枢轴点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了一个 3D 地图,我正在通过 Sprites 在这张地图上标记点.这本身就很好用,除了精灵标签的定位.

I've created a 3D map and I'm labelling points on this map through Sprites. This in itself works fine, except for the positioning of the sprite labels.

因为我正在创建地图,所以相机可以从 0 度倾斜到 90 度,而理想情况下,标签始终在屏幕上标记的项目正上方保持一定距离.但不幸的是,由于精灵总是以它们的原点为中心并且与项目重叠,我必须在 Y 世界轴上向上移动精灵,并且精灵的中心位置会随着相机的倾斜而变化.如果查看的项目偏离中心,这看起来很奇怪,并且当相机直视下方时效果不佳.

Because I'm creating a map the camera can tilt from 0 to 90 degrees, while ideally the label always stays some distance directly above the item it is labelling on the screen. But unfortunately, as sprites are always centred around their origin and that overlaps the item, I have to move the sprite up on the Y world axis and with that the centre location of the sprite changes as the camera is tilted. This looks weird if the item looked at is off centre, and doesn't work too well when the camera is looking straight down.

没有方便的 jsfiddle,但我在 http://leeft.eu/starcitizen/ 的申请应该给出对它的外观印象很好.

No jsfiddle handy, but my application at http://leeft.eu/starcitizen/ should give a good impression of what it looks like.

THREE.SpritePlugin 的代码向我建议应该可以使用matrixWorld"在渲染时将精灵在屏幕的 Y 轴上向上移动一些距离,但我不知道如何使用它,也不知道我完全确定这是我首先需要使用的.

The code of THREE.SpritePlugin suggests to me it should be possible to use "matrixWorld" to shift the sprite some distance up on the screen's Y axis while rendering, but I can't work out how to use that, nor am I entirely sure that's what I need to use in the first place.

是否可以在渲染时在屏幕上向上移动精灵,或者改变它们的原点?或者有没有其他方法可以达到同样的效果?

Is it possible to shift the sprites up on the screen while rendering, or perhaps change their origin? Or is there maybe some other way I can achieve the same effect?

Three.js r.67

Three.js r.67

推荐答案

根据 WestLangley 的建议,我通过根据视角更改精灵位置创建了一个可行的解决方案,尽管我花了几个小时来计算出几行使数学工作所需的代码.我也更新了我的应用程序,请查看现场演示.

As suggested by WestLangley, I've created a workable solution by changing the sprite position based on the viewing angle though it took me hours to work out the few lines of code needed to get the math working. I've updated my application too, so see that for a live demo.

使用从 OrbitControls.js 中的相机计算的倾斜角 phi 和航向角 theta,以下代码计算精灵偏移这正是我想要的:

With the tilt angle phi and the heading angle theta as computed from the camera in OrbitControls.js the following code computes a sprite offset that does exactly what I want it to:

// Given:
// phi = tilt; 0 = top down view, 1.48 = 85 degrees (almost head on)
// theta = heading; 0 = north, < 0 looking east, > 0 looking west

// Compute an "opposite" angle; note the 'YXZ' axis order is important
var euler = new THREE.Euler( phi + Math.PI / 2, theta, 0, 'YXZ' );
// Labels are positioned 5.5 units up the Y axis relative to its parent
var spriteOffset = new THREE.Vector3( 0, -5.5, 0 );
// Rotate the offset vector to be opposite to the camera
spriteOffset.applyMatrix4( new THREE.Matrix4().makeRotationFromEuler( euler ) );

scene.traverse( function ( object ) {
   if ( ( object instanceof THREE.Sprite ) && object.userData.isLabel ) {
      object.position.copy( spriteOffset );
   }
} );

请注意使用此代码的任何人:精灵标签是它们所指对象组的子对象,这仅设置与该父对象的本地偏移量.

Note for anyone using this code: that the sprite labels are children of the object group they're referring to, and this only sets a local offset from that parent object.

这篇关于Three.js:改变精灵的枢轴点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆