在THREE.js中创建50000多个文本粒子(Create 50000+ Text Particles in THREE.js)

编程入门 行业动态 更新时间:2024-10-27 13:24:23
在THREE.js中创建50000多个文本粒子(Create 50000+ Text Particles in THREE.js)

我试图创建一个超过50000个单字母的字符粒子系统。

找到类似的东西,但在这里用XG写的。

创建它的问题是应用程序的性能。

这里有一些简短的伪代码:

var field = new THREE.Object3D(); for (var i = 0; i < 50000; i++) { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.fillText(char); var texture = new THREE.Texture(canvas) texture.needsUpdate = true; var spriteMaterial = new THREE.SpriteMaterial({map: texture}); var sprite = new THREE.Sprite(spriteMaterial); sprite .position.set(x, y, z); field.add(textSprite); } scene.add(field);

所以现在我的问题是,是否有一些例子或其他什么我可以看到创建这个文本数量的最佳方法?!

我也试过这个例子而没有一个好的结果。

Im trying to create a character particlesystem with more than 50000 single letters.

Found something similar but written with XG here.

Problem with creating this is the performance of the application.

Here some short pseudo code:

var field = new THREE.Object3D(); for (var i = 0; i < 50000; i++) { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.fillText(char); var texture = new THREE.Texture(canvas) texture.needsUpdate = true; var spriteMaterial = new THREE.SpriteMaterial({map: texture}); var sprite = new THREE.Sprite(spriteMaterial); sprite .position.set(x, y, z); field.add(textSprite); } scene.add(field);

So my question is now, is there some example or something where i can see the best way to create this number of textsprites?!

I've also tried this example without a good result.

最满意答案

正如vals所说,你正在为每个字母创建材质和纹理。 你创建一个画布的事实也不重要,这只是一次性的开销。

您创建的每个纹理都必须占用图形内存。 在纹理之后,每个渲染过程都会单独计算每个材质,因此对于50000个材质,您需要进行大量计算。

加速你所拥有的一个简单方法是使用查找表:

var materialLUT = {}; function getMaterialForLetter(c){ var m = materialLUT[c]; if(m === void 0){ //material doesn't exist, lets create it var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.fillText(c); var texture = new THREE.Texture(canvas) texture.needsUpdate = true; m = materialLUT[c] = new THREE.SpriteMaterial({map: texture}); } return m; } var field = new THREE.Object3D(); for (var i = 0; i < 50000; i++) { var spriteMaterial = getMaterialForLetter(char); var sprite = new THREE.Sprite(spriteMaterial); sprite.position.set(x, y, z); field.add(textSprite); } scene.add(field);

我认为应该改进的另一件事是使用PointCloud 。 最后 - 我认为最好使用单个纹理并通过UV获取相关字符。

As vals noted, you are creating material and a texture for every letter. The fact that you are creating a canvas too is beside the point, that's just a one-off overhead.

Every texture you create will have to take up graphics memory. After the fact of texture, every material is computed separately in every render pass, so for 50000 materials you have a lot of computation.

A simple way to speed what you have up would be to use look-up tables:

var materialLUT = {}; function getMaterialForLetter(c){ var m = materialLUT[c]; if(m === void 0){ //material doesn't exist, lets create it var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); context.fillText(c); var texture = new THREE.Texture(canvas) texture.needsUpdate = true; m = materialLUT[c] = new THREE.SpriteMaterial({map: texture}); } return m; } var field = new THREE.Object3D(); for (var i = 0; i < 50000; i++) { var spriteMaterial = getMaterialForLetter(char); var sprite = new THREE.Sprite(spriteMaterial); sprite.position.set(x, y, z); field.add(textSprite); } scene.add(field);

Another thing i see that should be improved here is use of PointCloud. And lastly - I think it would be best to use a single texture and get relevant characters via UV.

更多推荐

本文发布于:2023-07-05 08:52:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1035441.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   粒子   文本   js   Text

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!