Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Three.js在Object3D和Sprite之间绘制形状_Javascript_Three.js_Sprite_Shapes - Fatal编程技术网

Javascript Three.js在Object3D和Sprite之间绘制形状

Javascript Three.js在Object3D和Sprite之间绘制形状,javascript,three.js,sprite,shapes,Javascript,Three.js,Sprite,Shapes,我有一个旋转的Object3D,周围贴着精灵标签。精灵的位置正确,并与Object3D一起旋转,始终面向摄影机 我需要在标签上绘制语音气泡样式的尾部,并让它们指向Object3D上的位置。这对于线条来说相当简单,但是对于形状来说就更复杂了 绿色是Object3D立方体 蓝色是需要旋转的形状 白色是雪碧标签 到目前为止,我有蓝色的形状大小和位置正确。但是,旋转y轴需要相对于Object3D旋转和相机位置进行动态更新。我试过了。lookAt(),但它不工作,因为它会旋转所有轴。我只需要y旋转就

我有一个旋转的Object3D,周围贴着精灵标签。精灵的位置正确,并与Object3D一起旋转,始终面向摄影机

我需要在标签上绘制语音气泡样式的尾部,并让它们指向Object3D上的位置。这对于线条来说相当简单,但是对于形状来说就更复杂了

  • 绿色是Object3D立方体
  • 蓝色是需要旋转的形状
  • 白色是雪碧标签
到目前为止,我有蓝色的形状大小和位置正确。但是,旋转y轴需要相对于Object3D旋转和相机位置进行动态更新。我试过了。lookAt(),但它不工作,因为它会旋转所有轴。我只需要y旋转就可以被影响

还质疑这是否是总体上最好的方法

谢谢

//场景设置
var scene=new THREE.scene();
var摄像机=新的三透视摄像机(75,window.innerWidth/window.innerHeight,0.11000);
摄像机位置z=5;
var renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
var ambientLight=新的三个ambientLight(0xffffff.5);
场景。添加(环境光);
var directionalLight=新的三个方向灯(0xffffff,1);
directionalLight.position.set(1,1,1).normalize();
场景。添加(方向光);
var group=新的三个.group();
场景。添加(组);
//立方体
var cubeSize=1;
var geometry=新的三个.BoxGeometry(立方大小、立方大小、立方大小);
var material=新的3.0网格LambertMaterial({
颜色:0x00ff00
});
var cube=新的三个网格(几何体、材质);
添加组(立方体);
//文本标签
变量配置={
字体:“Arial”,
字体大小:64,
重量:500,
线宽:1,
填充:20
};
var text='Hello world!';
var canvas=document.createElement('canvas');
var ctx=canvas.getContext('2d');
ctx.font=`${config.fontwweight}${config.fontsize}px/${config.lineheight}${config.fontface}`;
const textMetrics=ctx.measureText(文本);
var textWidth=textMetrics.width;
var textHeight=config.fontsize*config.lineheight;
canvas.width=textWidth+config.padding*2;
canvas.height=textHeight+config.padding*2;
ctx.fillStyle='白色';
ctx.fillRect(0,0,textWidth+config.padding*2,textHeight+config.padding*2);
ctx.fillStyle='黑色';
ctx.textAlign='左';
ctx.textb基线='top';
ctx.font=`${config.fontwweight}${config.fontsize}px/${config.lineheight}${config.fontface}`;
fillText(text,config.padding,config.padding);
var纹理=新的三个纹理(画布);
texture.needsUpdate=true;
var spriteMaterial=新的三个spriteMaterial({
贴图:纹理
});
var aspectRatio=spriteMaterial.map.image.height/spriteMaterial.map.image.width;
变量sprite=新的三个sprite(spriteMaterial);
sprite.position.set(0,立方*2,0);
sprite.scale.set(1,aspectRatio,1);
添加(雪碧);
//形状测量网格
变量arrowWidth=textHeight/220;
变量箭头高度=精灵位置y/1.41;
var arrowShape=新的三个.Shape();
箭头形状。移动到(0,0);
箭头形状.lineTo(-arrowWidth/2,arrowHeight);
箭头形状.lineTo(箭头宽度/2,箭头高度);
arrowShape.lineTo(0,0);
var arrowGeometry=新的三种形状测量法(arrowShape);
var arrowMaterial=新的三网格基本材质({
颜色:0x0000ff,
//depthWrite:false,
侧面:三个。双面
});
var arrow=新的三点网格(箭头几何体、箭头材质);
箭头位置设置(0,立方尺寸/2,0);
/*arrow.up.copy(新的3.Vector3(0,1,0))*/
组。添加(箭头);
window.group=组;
var animate=函数(){
请求动画帧(动画);
旋转组x+=0.005;
旋转组y+=0.005;
组旋转z+=0.005;
//将lookAt与depthWrite:false一起使用几乎有效
//arrow.lookAt(摄像机位置);
//arrow.rotation.x=0;
//箭头。旋转。z=0;
渲染器。渲染(场景、摄影机);
};
制作动画()
正文{
保证金:0;
}
帆布{
宽度:100%;
身高:100%;
}

为什么不为语音气泡使用
THREE.Sprite
呢?我最初的方法是将语音气泡尾部绘制为文本Sprite的一部分:缺点是必须在渲染时重新绘制(密集),或者我需要9个不同的版本来覆盖每个可能的方向,指针从来没有真正指向所需的精确点。看看用画布画的尾巴:现在想清楚了,我可以把它当作一个单独的精灵,它面对着相机,但在计算出与标签匹配的材质旋转方面仍然有相同的困境:精灵也不会从中心旋转,所以这增加了复杂性。我相信我需要这样的东西:使用lookAt()获得接近我需要的效果,然后将其他旋转重置为0,然后在材质上使用depthrite:false:为什么不使用
THREE.Sprite
作为语音气泡,也是吗?我最初的方法是将语音气泡尾作为文本精灵的一部分绘制:缺点是要么在渲染时重新绘制(密集),要么我需要9个不同的版本来覆盖所有可能的方向,指针永远不会真正指向所需的准确点。看看用画布画的尾巴:现在想清楚了,我可以把它当作一个单独的精灵,它面对着相机,但在计算出与标签匹配的材质旋转方面仍然有相同的困境:精灵也不会从中心旋转,所以这增加了复杂性。我相信我需要这样的东西:使用lookAt()获得接近我需要的效果,然后将其他旋转重置为0,然后在材质上使用depthWrite:false: