在React Three Fiber中管理许多动态对象的最佳实践是什么?

huangapple go评论65阅读模式
英文:

What is the best practice to manage many dynamic objects in react three fiber?

问题

使用React Three Fiber,我想在屏幕上显示多达1000个对象。对象将根据业务逻辑在运行时创建,并在不再需要时销毁。

大多数我见过的示例都使用固定数量的对象。位置会重置,而不是真正创建/销毁对象。(例如:飞行香蕉气泡,各种粒子示例)

示例场景

一个交通模拟器。场景是几个城市街区的固定俯视图。

车辆在场景中行驶,每辆车都具有唯一的属性。
屏幕上的车辆数量和类型将根据用户可配置的设置而变化。

车辆将在场景的边缘“生成”。当它们离开场景时,它们将不再存在。

我正在尝试的方法

A)使用instancedMesh。这允许进行优化。但我找不到一个示例,其中要跟踪可变数量的对象。此外,似乎我可能需要创建多个instancedMeshes来处理每种可绘制的车辆类型(卡车 vs 小汽车等)。

B)保存所有车辆的数组。我可以存储一个包含所有车辆的数组,并使用类似以下代码来渲染它们:

vehicles = [ { id: 'a', position: [1,2,3] } ]

// 更新车辆属性
useFrame(( _, delta) => {
  // 有条件地添加车辆。忽略id/位置
  if( Math.random() < 0.2 ) { vehicles.push( { id: '?', position: [2,3,4] } ) } 

  // for循环。速度 * 时间计算。更新每辆车的位置值。
  // 如果车辆在边界之外,将其标记为已删除。

  // 在循环之外移除标记的车辆
  vehicles = vehicles.filter( v => v.toBeRemoved !== true )
})
return vehicles.map((vehicle) =>
  (<Vehicle key={vehicle.id} position={vehicle.position} />)
)

(上述受到 https://stackoverflow.com/questions/66131246/react-three-fiber-for-loop 的启发)

如果我正确理解事情(不能保证),这种策略可能会在每一帧重新分配数组,并为React引起许多变化检测问题。

C)miniplex(ECS)

这似乎是可行的,但我似乎找不到任何可用的示例,而且文档要么不适用,要么是待办事项。

我在图形领域是新手,所以可能有遗漏的内容。

英文:

Using react three fiber, I want to show as many as 1000 objects on screen. Objects will be created during runtime based on business logic, and later destroyed when no longer needed.

Most examples I've seen used a fixed count of objects. Positions are reset rather than an actual create/destroy. (ex: Flying bananas, bubbles, various particle examples)

An example scenario

A traffic simulator. The scene is an fixed overhead view of a few city blocks

Vehicles drive through the scene, each with unique properties.
The number and type of vehicles on screen will vary based on user configurable settings.

Vehicles will 'spawn' at edges of the scene. When they leave the scene, they no longer exist.

What I'm trying

A) Using instancedMesh. This allows for optimization. But I cannot find an example with a variable number of objects to track. Additionally, it seems I may need to create multiples instancedMeshes to account for each drawable type of vehicle (truck vs car, etc).

B) Holding an array of all vehicles. I can store an array with all vehicles, and render them with some code akin to:

vehicles = [ { id: &#39;a&#39;, position: [1,2,3] } ]

// update vehicle properties
useFrame(( _, delta) =&gt; {
  // Conditionally add vehicles. Ignore id/position
  if( Math.random() &lt; 0.2 ) { vehicles.push( { id: &#39;?&#39;, position: [2,3,4] } ) } 

  // for loop. Velocity * time computations. Update position values for each vehicle.
  // if the vehicle is outside the boundaries, mark it as removed. 

  // Outside the loop remove marked vehicles 
  vehicles = vehicles.filter( v =&gt; v.toBeRemoved !== true )
})
return vehicles.map((vehicle) =&gt;
  (&lt;Vehicle key={vehicle.id} position={vehicle.position} /&gt;)
)

(above, inspired by https://stackoverflow.com/questions/66131246/react-three-fiber-for-loop)

If I understand things correctly (not guaranteed), this strategy might be reallocating arrays on every frame, and causing lots of change detection difficulty for react.

C) miniplex (ECS)

This seems plausible, but I can't seem to find any working examples, and the documentation is either not applicable, or a TODO.

I am novice in the graphics domain, so something may have been missed.

答案1

得分: 0

最佳解决方案是使用实例化网格方法。

每种类型的车辆都有自己的数组。数组的大小是可能的车辆数量的最大值。

数组存储所有状态,包括位置和生命周期状态。控制逻辑决定生命周期是“在屏幕上”还是“不在屏幕上”。控制器更新位置。如果“不在屏幕上”,则位置在可见空间之外,以避免显示出来。

绘制循环使用通常的实例化网格解决方案进行渲染,仅绘制该类型的车辆。

for循环解决方案导致帧速率显著下降(从60到约35)。

英文:

My best solution has been to use the instanced mesh approach.

Each type of vehicle has it's own array. The size of the array is the maximum number of vehicles possible.

The array stores all state, including position and lifecycle status. Controller logic decides if lifecycle is 'on-screen' or 'off-screen'. The controller updates position. If 'off-screen' the position is outside the visible space to avoid it showing up.

The draw loop renders using the usual instanced mesh solutions, and only draws that type of vehicle.

The for-loop solution caused significant frame rate drop (from 60 to ~35).

huangapple
  • 本文由 发表于 2023年6月29日 02:54:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76575970.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定