Three.js 实例化形状中的透明度

Three.js 实例化形状中的透明度,three.js,Three.js,我一直在玩3.0。我终于得到了一个例子来工作,现在一直在玩着色器。我尝试的第一件事是设置透明度。下面是我的示例代码 初始状态,以及从大量其他摄影机角度(例如向左拖动鼠标),透明度似乎没有任何效果。但在其他相机角度,例如重新加载并向右拖动鼠标,形状明显重叠,这正是我所期望的 对于实例形状,深度排序的处理方式是否不同,或者我是否做错了什么,或者遗漏了什么?我是否需要更新形状,以便相机知道它们在场景中的适当深度 var cubeGeo=new THREE.InstancedBufferGeometr

我一直在玩3.0。我终于得到了一个例子来工作,现在一直在玩着色器。我尝试的第一件事是设置透明度。下面是我的示例代码

初始状态,以及从大量其他摄影机角度(例如向左拖动鼠标),透明度似乎没有任何效果。但在其他相机角度,例如重新加载并向右拖动鼠标,形状明显重叠,这正是我所期望的

对于实例形状,深度排序的处理方式是否不同,或者我是否做错了什么,或者遗漏了什么?我是否需要更新形状,以便相机知道它们在场景中的适当深度

var cubeGeo=new THREE.InstancedBufferGeometry.copynew THREE.BoxBufferGeometry10,10; //cubeGeo.maxInstancedCount=8; cubeGeo.addAttributecubePos,新的3.InstancedBufferAttributenew Float32Array[ 25, 25, 25, 25, 25, -25, -25, 25, 25, -25, 25, -25, 25, -25, 25, 25, -25, -25, -25, -25, 25, -25, -25, -25 ], 3, 1; 变量vertexShader=[ 精密高精度浮点;, , 一致mat4 modelViewMatrix;, 一致mat4投影矩阵;, , 属性vec3位置;, 属性vec3 cubePos;, , 空主{, , gl_位置=投影矩阵*modelViewMatrix*vec4立方体+位置,1.0;, , } ]。加入\n; var fragmentShader=[ 精密高精度浮点;, , 空主{, , gl_FragColor=vec41.0,0.0,0.0,0.5;, , } ]。加入\n; var mat=新的3.RawShaderMaterial{ 制服:{}, vertexShader:vertexShader, fragmentShader:fragmentShader, 透明:正确 }; var mesh=新三个。MeshcubeGeo,mat; scene.addmesh; html*{ 填充:0; 保证金:0; 宽度:100%; 溢出:隐藏; } 主人{ 宽度:100%; 身高:100%; } 变量宽度=window.innerWidth, 高度=窗内高度, FOV=35, 近=1, FAR=1000; var renderer=new THREE.WebGLRenderer{ 反别名:对 }; renderer.setSizeWIDTH,高度; document.getElementById'host'.appendChildrenderer.doElement; var stats=新的stats; stats.domElement.style.position='绝对'; stats.domElement.style.top='0'; document.body.appendChildstats.doElement; var摄像机=新的三视角摄像机视野、宽度/高度、近距离、远距离; 摄像机位置z=250; var trackballControl=new THREE.TrackballControlscamera,renderer.doelement; trackballControl.rotateSpeed=2.0;//需要加速一点吗 var场景=新的三个场景; var light=新的三点光源0xFFFFFF,1,无穷大; 照相机。addlight; scene.addlight; 函数渲染{ 如果更新的类型!==未定义{ 更新文章; } renderer.renderscene,摄影机; 统计数据更新; } 函数动画{ 请求动画帧动画; trackballControl.update; 提供 } 使有生气 将InstancedBufferGeometry与半透明网格一起使用

实例将按照它们在缓冲区中出现的顺序进行渲染。每个实例的面都按几何体指定的顺序渲染

因此,如果将实例化与半透明一起使用,则可能会根据观察角度产生瑕疵

根据您的用例,您可以尝试设置material.depthWrite=false,但这可能会导致其他工件

如果网格纹理具有完全透明的区域而不是部分透明的区域,则应能够使用material.alphaTest丢弃不需要的碎片,而不产生瑕疵

three.js r.84

您使用的InstancedBufferGeometry具有半透明的网格

实例将按照它们在缓冲区中出现的顺序进行渲染。每个实例的面都按几何体指定的顺序渲染

因此,如果将实例化与半透明一起使用,则可能会根据观察角度产生瑕疵

根据您的用例,您可以尝试设置material.depthWrite=false,但这可能会导致其他工件

如果网格纹理具有完全透明的区域而不是部分透明的区域,则应能够使用material.alphaTest丢弃不需要的碎片,而不产生瑕疵


three.js r.84

在评论中与WestLangley讨论后,我为我的实例添加了一个分类器。它根据实例与摄影机的距离对其位置进行排序

旁注:如果我还有其他三个.InstancedBufferAttributes,我需要同时对它们重新排序

最大的缺点是,随着场景越来越大,无论是在实例化形状还是非实例化形状中,它都变得越来越昂贵

//实例分类器,称为每个帧 函数sortObjectInstancesobj{ 如果对象几何{ 如果obj.geometry instanceof THREE.InstancedBufferGeometry{ var array=obj.geometry.attributes.cubePos.array, 向量数组=[]; 对于变量i=0,l=array.length/3;ib.distanceTocamera.position{ 返回-1; } 如果a.distanceTocamera.position在评论中与WestLangley讨论之后,我为我的实例添加了一个分类器。它根据实例与摄影机的距离对其位置进行排序

旁注:如果我还有其他三个.InstancedBufferAttributes,我需要同时对它们重新排序

最大的缺点是,随着场景越来越大,无论是在实例化形状还是非实例化形状中,它都变得越来越昂贵

//实例分类器,称为每个帧 函数sortObjectInstancesobj{ 如果对象几何{ 如果obj.geometry instanceof THREE.InstancedBufferGeometry{ var array=obj.geometry.attributes.cubePos.array, 向量数组=[]; 对于变量i=0,l=array.length/3;ib.distanceTocamera.position{ 返回-1; } 如果a.distanceTocamera.position如果我理解正确的话,唯一可行的方法就是以深度排序的方式重新排列我的cubePos缓冲区,对吗?包括这样的每帧任务可能会扼杀通过使用实例获得的任何性能优势,尽管内存仍然会受益不要使用几何体面:使用已实施的背面-正面技巧。不过,您可能需要对实例重新排序。关于不改变几何体,我们意见一致。cubePos是我的实例,实际上我让它以这种方式工作,它只是效率低下,我将用代码发布一个答案。我将尝试背面-正面的技巧,尽管我不太喜欢它,因为我在场景中添加了更多的网格。如果我理解正确,唯一可行的方法是以深度排序的方式重新排列我的cubePos缓冲区,对吗?包括这样的每帧任务可能会扼杀通过使用实例获得的任何性能优势,尽管内存仍然会受益不要使用几何体面:使用已实施的背面-正面技巧。不过,您可能需要对实例重新排序。关于不改变几何体,我们意见一致。cubePos是我的实例,实际上我让它以这种方式工作,它只是效率低下,我将用代码发布一个答案。我将尝试“背面-正面”技巧,但由于向场景中添加了更多网格,我对此并不感兴趣。一个较小的效率变化是将3.Vector3对象数组存储在网格本身上,而不是每次生成。一个较小的效率变化是将3.Vector3对象数组存储在网格本身上,而不是每次都生成它。