three.js中的多次累积渲染

three.js中的多次累积渲染,three.js,rendering,Three.js,Rendering,我已经编写了一些代码来渲染一个场景,其中包含的灯光工作起来像投影仪。但是它们有很多(在一个着色器中使用固定数量的灯光所能表示的更多)。现在我通过创建一个自定义着色器并为每个灯光渲染一次场景来渲染它。碎片着色器的每一次传递都会确定该灯光的贡献,混合器会将该贡献添加到backbuffer中。我发现在three.js中进行设置非常尴尬。我找不到一种方法来做这样的多次传球,因为不同的传球需要不同的材料和不同的几何体。我必须通过多个场景来做到这一点。问题是我不能在多个场景中使用object3d(如果我错了

我已经编写了一些代码来渲染一个场景,其中包含的灯光工作起来像投影仪。但是它们有很多(在一个着色器中使用固定数量的灯光所能表示的更多)。现在我通过创建一个自定义着色器并为每个灯光渲染一次场景来渲染它。碎片着色器的每一次传递都会确定该灯光的贡献,混合器会将该贡献添加到backbuffer中。我发现在three.js中进行设置非常尴尬。我找不到一种方法来做这样的多次传球,因为不同的传球需要不同的材料和不同的几何体。我必须通过多个场景来做到这一点。问题是我不能在多个场景中使用object3d(如果我错了,请纠正我)。所以我需要创建对象的副本-每个场景一个。这一切很快就开始变得非常糟糕。它非常特别,似乎与各种three.js framework功能(如VR渲染)不兼容。每个灯光都需要阴影,但我没有为每个灯光创建阴影缓冲区的内存,因此它会交替渲染灯光的阴影缓冲区,然后是该灯光的累积阶段,然后是下一个灯光的阴影缓冲区,然后是下一个灯光的累加器,等等

我更愿意用一种更“三点js”的方式来设置它。我似乎在写一个接一个的hack来让它工作,每次我都会放弃另外一个3.js框架特性,它不能与我的多通道技术一起正常工作。但我所做的似乎并不是那么不同寻常

我最惊讶的是,我想不出一种方法来设置一个多通道场景,这样可以来回渲染和积累。我的第二个惊喜是,我创建的Object3D不喜欢同时添加到多个场景中,因此我必须为每个场景创建每个对象的副本,以避免它们的状态相互干扰

那么,有没有更好的方法来渲染这种多次累积的场景呢?同样,我会将其描述为一个场景,其中>单个着色器过程中允许的最大灯光数,因此它们的贡献需要交替渲染(阴影缓冲区),然后在多个过程中累积。这些灯的工作原理类似于典型的电影放映机,可以投射图像(而不是统一的纯色光源)

我如何才能像这样进行多次渲染,同时仍然利用好的框架功能,如VR立体渲染和自动阴影缓冲区创建

下面是一个简化的片段,演示了所涉及的场景:

  renderer.render(this.environment.scene, camera, null);
  for (let i = 0, ii = this.projectors.length; i < ii; ++i) {
    let projector = this.projectors[i];
    renderer.setClearColor(0x000000, 1);
    renderer.clearTarget(this.shadowRenderTarget, true, true, false);
    renderer.render(projector.object3D.depthScene, projector.object3D.depthCamera, this.shadowRenderTarget);
    renderer.render(projector.object3D.scene, camera);
  }

  renderer.render(this.foreground.scene, camera, null);
renderer.render(this.environment.scene,camera,null);
for(设i=0,ii=this.projectors.length;i
有一个场景渲染环境中的照明(使用正常照明完成),然后每个投影仪有一个场景,该场景计算投影仪的阴影贴图,然后添加每个投影仪的灯光贡献,然后有一个“前景”场景,其中包含覆盖和UI内容


还有更多的“three.js”方法吗?

不幸的是,我认为答案是
没有

我更愿意用一种更“三点js”的方式来设置它。我似乎在写一篇又一篇的文章来让它工作

欢迎来到three.js开发的世界:)

场景图 不能让一个节点属于多个父节点。我相信三个也不允许你这么做:

const myPos = new THREE.Vector3()

myMesh_layer0.position = myPos
myMesh_layer1.position = myPos
它不适用于欧拉、四元数或矩阵

在多个场景中管理矩阵更新也很棘手

三条路 除非你开始破解内核,否则就没有办法进行“一次又一次的破解”

请注意,现在是2018年,但将three.js纳入web应用程序的官方方式是通过
标记

这是一个很好的例子,说明最好不要使用
three.js方式
,而是使用
现代javascript方式
,即使用导入、npm安装等

Three.js也没有一个健壮的内核,使您能够灵活地处理周围的代码。它相当混乱,并且与有限数量的公开挂钩相混淆,这些挂钩允许您编写所需的效果

三个经常与它的示例混淆在一起,如果您随机选择一个,它将以Three.js的方式编写,但与最佳javascript/编码实践相去甚远,至少在今天是这样

您经常会发现大型单片文件,这些文件将从分解中受益

我相信仍然不可能将示例作为模块导入

查看材料扩展示例,并考虑是否希望在项目中应用该模式。

您可能会遇到更多的痛点,但这足以说明
three.js方式
可能并不总是可取的

补救措施 很少有。我花了一年多的时间尝试在beforerender
和onAfterRender
钩子上推送
。它似乎很有用,并且允许进行一些重构,但必须首先取消另一个特性

另一个功能在那一年中被反复使用,只涉及一个示例,直到人们清楚地认识到,
onBeforeRender
将同时解决这两个示例,并考虑更多

不幸的是,这似乎也是three.js的方式。因为基地是如此的重要