Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.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 裁剪一个3.js精灵以适合它';s父对象';界_Javascript_Three.js - Fatal编程技术网

Javascript 裁剪一个3.js精灵以适合它';s父对象';界

Javascript 裁剪一个3.js精灵以适合它';s父对象';界,javascript,three.js,Javascript,Three.js,我有一个精灵,创建如下,并添加为具有透明材质的对象的子对象: let mySprite = new THREE.Sprite(new SpriteMaterial({ map: myTexture })); mySprite.scale.set(2, 2, 1.0); mySprite.position.set(0, 0, 0); myObject.add(mySprite); 对象具有depthWrite:false,因此我可以通过它看到精灵,但是,由于对象是球体,精灵是方形的,精

我有一个精灵,创建如下,并添加为具有透明材质的对象的子对象:

let mySprite = new THREE.Sprite(new SpriteMaterial({
    map: myTexture
}));

mySprite.scale.set(2, 2, 1.0);
mySprite.position.set(0, 0, 0);
myObject.add(mySprite);
对象具有
depthWrite:false
,因此我可以通过它看到精灵,但是,由于对象是球体,精灵是方形的,精灵的角溢出对象


是否有一种方法可以剪裁精灵的角,以便仅显示球形对象边界内的内容?

一种方法是让父对象为模具缓冲区绘制唯一的ID

const parentMaterial = new THREE.MeshPhongMaterial({
  ...
  stencilWrite: true,                    // turn on stenci writing
  stencilRef: stencilId,                 // write this value
  stencilZPass: THREE.ReplaceStencilOp,  // write if the depth buffer test passes
});
const spriteMaterial = new THREE.SpriteMaterial({
  stencilWrite: true,                   // turn on writing
  stencilRef: stencilId,                // 
  stencilFunc: THREE.EqualStencilFunc,  // draw only if stencil = stencilRef;
  depthTest: false,
});
并将精灵设置为仅在该id显示在模具缓冲区中的位置绘制

const parentMaterial = new THREE.MeshPhongMaterial({
  ...
  stencilWrite: true,                    // turn on stenci writing
  stencilRef: stencilId,                 // write this value
  stencilZPass: THREE.ReplaceStencilOp,  // write if the depth buffer test passes
});
const spriteMaterial = new THREE.SpriteMaterial({
  stencilWrite: true,                   // turn on writing
  stencilRef: stencilId,                // 
  stencilFunc: THREE.EqualStencilFunc,  // draw only if stencil = stencilRef;
  depthTest: false,
});
注意:写入模具有3个案例。如果模具测试失败怎么办,如果深度测试失败怎么办,如果两者都通过怎么办。所有3个的默认设置是什么也不做。因此,即使我们为精灵启用了
stencilWrite
true,因为3个默认值是doNothing(3.KeepStencilOp),绘制精灵时也不会写入任何内容

你需要确保先画父母,再画孩子。如果他们有相同的立场,那么我认为这已经是事实。如果他们有不同的位置,那么您可能需要设置。在上面的示例中,精灵是透明的,实体是不透明的,默认情况下,透明对象在不透明之后绘制

注意,这只适用于255个精灵,因为模具通常只有256个可能的值。除此之外,还需要以255个对象为一组来渲染对象,清除组之间的模具缓冲区

函数main(){
const canvas=document.querySelector(“#c”);
const renderer=new THREE.WebGLRenderer({canvas});
常数fov=75;
const aspect=2;//画布默认值
常数近=0.1;
常数far=50;
常量摄影机=新的三个透视摄影机(视野、方位、近距离、远距离);
摄像机位置设置(0,2,5);
const controls=新的三个轨道控制(摄像机、画布);
控制目标集(0,2,0);
控件更新();
const scene=new THREE.scene();
scene.background=新的三种颜色(“白色”);
功能添加灯(位置){
常量颜色=0xFFFFFF;
常数强度=1;
恒定光=新的三个方向光(颜色、强度);
灯。位置。设置(…位置);
场景。添加(灯光);
场景。添加(灯光。目标);
}
addLight([-3,1,1]);
addLight([2,1,5]);
常数bodyRadiusTop=.4;
const bodyRadiusBottom=.2;
常数体高=2;
const bodyRadialSegments=6;
const bodyGeometry=新的三柱面缓冲几何体(
车身半径顶部、车身半径底部、车身高度、车身半径分段);
常数头半径=体半径顶部*0.8;
const headLonSegments=12;
常量海岬段=5;
const headGeometry=新的3.SphereBufferGeometry(
前照灯、前照灯分段、前照灯分段);
函数makeLabelCanvas(基本宽度、大小、名称){
常数borderSize=2;
const ctx=document.createElement('canvas').getContext('2d');
常量字体=`${size}px粗体无衬线`;
ctx.font=font;
//测量名称的长度
const textWidth=ctx.measureText(name).width;
常量doubleBorderSize=borderSize*2;
const width=baseWidth+doubleBorderSize;
常量高度=大小+双边框大小;
ctx.canvas.width=宽度;
ctx.canvas.height=高度;
//调整画布大小后需要重新设置字体
ctx.font=font;
ctx.textb基线='中间';
ctx.textAlign='中心';
//可根据需要调整尺寸,但不可拉伸
const scaleFactor=Math.min(1,baseWidth/textWidth);
ctx.平移(宽度/2,高度/2);
ctx.标度(标度因子,1);
ctx.fillStyle='白色';
ctx.fillText(名称,0,0);
返回ctx.canvas;
}
函数makePerson(模具ID、x、标签宽度、大小、名称、颜色){
const canvas=makeLabelCanvas(标签宽度、大小、名称);
const纹理=新的三个。CanvasTexture(canvas);
//因为我们的画布可能不是2的幂
//在这两个维度中,适当设置过滤。
texture.minFilter=THREE.LinearFilter;
texture.wrapps=3.ClampToEdgeWrapping;
texture.wrapT=3.claptoedgewrapping;
const labelMaterial=新的3.SpriteMaterial({
贴图:纹理,
透明:是的,
stencilWrite:是的,
stencilRef:stencilId,
stencilFunc:3.EqualStencilFunc,
深度测试:假,
});
const bodyMaterial=新的三点网格材质({
颜色
对,,
stencilWrite:是的,
stencilRef:stencilId,
stencilZPass:3.ReplaceStencilOp,
});
const root=new THREE.Object3D();
根位置x=x;
const body=新的三个网格(bodyGeometry,bodyMaterial);
根。添加(体);
车身位置y=车身高度/2;
const head=新的三个网格(头部几何体、车身材质);
根。添加(头);
头部位置y=身体高度+头半径*1.1;
常量标签=新的3.Sprite(labelMaterial);
root.add(标签);
标签位置y=车身高度*4/5;
//如果单位为米,则此处的0.01表示尺寸
//将标签的长度改为厘米。
常数labelBaseScale=0.01;
label.scale.x=canvas.width*labelBaseScale;
label.scale.y=canvas.height*labelBaseScale;
scene.add(root);
返回根;
}
制造者(1,-3,128,128,'