Create a bufferGeometry with several particles sizes. Best performance? - javascript

I created a THREE.Point object, using a bufferGeometry, to render thousands of particles, and I used the PointsMaterial material. I update the material on runtime, changing between the normal square particle (default one) with some other textures and colors, and it works fine.
The problem comes when I want to create particles with different sizes. I can't do it just setting a BufferAttribute. I tried make a custom shader, Three.js Particles of various sizes but I couldn't make it works, some Three version problem maybe? I duno.
So I thought grouping all my particles by sizes and create one bufferGeometry for each particles sizes. But I'm not sure this is the best approach. Is this the best choice in terms of performance? Or do I have to create a custom shader to achieve this goal?
Three.js revision:72

An example of what you want to do is given in this answer -- just use the alpha attribute value in the example to vary the point size instead: http://jsfiddle.net/8mrH7/196/
gl_PointSize = 8.0 * alpha; // use alpha to vary point size, instead
three.js r.73

Related

Is it more performant to use a sprite or a BufferedGeometry in Three.js?

I'm rewriting a legacy visualization built several years ago with an older version of Three.js. The visualization is ~20k 2D circles (nodes from a graph) drawn on a screen with positions and coloring already determined.
There's no animation involved other than when interaction occurs (zooming, clicking, etc). The previous author used sprites for the circles (nodes) to show different states (node selected: glowing effect, node hidden: transparent, etc)
I've been able to successfully reproduce much of the visualization using CircleBufferGeometry instead of a sprite.
I know this is potentially too vague a question, given it might be too specific to my use case, but I'm wondering if anyone has any insight into whether it's more performant to render ~20k sprites or ~20k CircleBufferGeometry with Three.js / webgl.
Thanks!
CircleBufferGeometry will have many more vertices per entity than a sprite would since sprites should be drawn with gl.POINTS ( one point == one vertex ). Your vertex shader would process more vertices with the circle than it would with a sprite.

Reuse image in three.js textures

I'm trying to load with three.js the same image in a large number (~ 1000) of bidimensional shapes but with different offsets in every shape.
I've taken this demo from the official website and customized it into this other demo, with all my shapes and a random background texture.
The problem is that if I clone the texture once per shape the page eats a lot of RAM and it ends up crashing.
You can see this in action by going in the javascript and changing the comments in the addShape function (you'll find the instructions in the code).
I've done some research and found some results, like this open issue or this older question where it's recommended to clone the texture; anyway nothing seems to work in my example.
Am I doing something wrong? It's changed something since these last posts about this problem?
Maybe I´m misunderstanding the problem, but why don´t you change the UV coordinates of the individual shapes to align the texture and use just one texture?
From documentation:
Geometry.faceVertexUvs
Array of face UV layers, used for mapping textures onto the geometry.
Each UV layer is an array of UVs matching the order and number of
vertices in faces.
To signal an update in this array, Geometry.uvsNeedUpdate needs to be
set to true.

Three.js method for adding high resolution textures for planets

So I found out that texturing planets can be really hard. I created a 4096k image and wrapped it around a high poly sphere. Apart from the possible memory management performance issue that comes with a 3-4 mb image, the texture looks bad / pixelated on a close up (orbital) view.
I was thinking that I could maybe increase the resolution significantly by splitting up the picture. Then create a low, medium and high version of each section. If the camera viewport is very close to that particular section then render the high resolution image. If far away remove image from memory and apply low or medium version.
To be honest I am not sure what strategy to use to render high quality planets. Should I maybe avoid textures and just use height maps and color the planet with Javascript? Same thing for the clouds. Should I create a sphere with an alpha map or should I use shaders?
As you can see this is the issue im having and hopefully you could enlighten me. Performance with Webgl / three.js has significantly improved over time but since this is all done within the browser I assume thinking about the right solution is vital in the long term.
You're going to need to implement a lod system. lod = "level of detail" and in 3d it means generally means switching from high-polygon to low-polygon models but in general it means doing anything to switch high detail to low-detail
Because you can't make textures 1000000x100000 which is pretty much what you'd need to do to get the results you want you'll need build a sphere out of multiple sections and texture each one separately. How many sections depends on how close you want to be able to zoom in. Google Maps has millions of sections. At the same time, if you can zoom out to see the whole planet (like you can in Google Maps) you can't draw millions of sections. Instead you'd switch to a single sphere. That process is called "LODing"
There is no "generic" solution. You generally need to write your own for your specific case.
In the case of something like Google Maps what they most likely do is have several levels of detail. A single sphere when you can see the whole planet. A sphere made of say 100 pieces when slightly closer. A sphere made of 1000 pieces when closer, A sphere made of 10000 pieces when closer, etc etc. They also only show the pieces you can see. Deciding and managing which pieces to show with a generic solution would be way to slow (look at millions of pieces every frame) but you, as the application writer know what pieces are visible so you can make sure only those pieces are in your scene.
Another thing that people often do is fade between LODs. So when Google Maps is showing the single mesh sphere when all the say zoomed out and they transition to the 100 piece or 1000 piece sphere they crossfade between the two.
Some examples of lodding
http://acko.net/blog/making-worlds-1-of-spheres-and-cubes/
http://vterrain.org/LOD/spherical.html
You could create a sphere with different topology.
Say you create 6 square planes, arranged in such a way that they form a box. You can tesselate these planes to give the sphere enough resolution. These planes would have UV mapping that would work similar to cube-mapping, each will hold a cubemap face.
Then you loop through all the vertices, take the position vector and normalize it. This will yield a sphere.
You can convert an equirectangular panorama image into a cubemap. I think it will allow you to to get more resolution and less stretching for cheap.
For starters, the 4096 x 4096 should be 4096x2048 on the default sphere with equirectangular, but the newly mapped sphere can hold 6 x 4096 x 4096 with no stretching, and can be drawn in 6 draw calls.
Further splitting these could yield a good basis for what gman suggests.

threejs (r72) point cloud movement

I'm working with the most recent r72 of THREEJS, and am trying to accomplish some effects that I used to do with pointclouds, which has now been replaced with the Points object.
I've set up a codepen http://codepen.io/shomanishikawa/pen/NGaWdW - both orbs are made by creating a geometry and pushing Vector3's to them.
I'd like to have individual points in the points object move at different velocities/directions, which was previously accomplished easily by setting something like
particle.velocity.y = 20
Which now seems to have no effect.
The orb on the left uses a BufferGeometry with a ShaderMaterial
The orb on the right uses a Geometry with a PointsMaterial
How can I set velocities on individual points so I can have them orbit around the radius instead of just rotating the parent Points object?
I'd like to accomplish this with a regular Geometry if possible, since I'd like finer control of moving the vertices individually. Provided examples of both just in case it's only feasible with one version.

Background with three.js

Can anybody help me with three.js?
I need to draw background, something, like a THREE.Sprite, but it neet to be UNDER any 3d object, that will draw later. I have a camera, that can be move only on Z axis.
I tryed to use:
cube mapping shader - PROBLEM: artefacts with shadow planes, it's unstable draw
THREE.Sprite that dublicate camera moving - PROBLEM: artefacts with shadow plane - it have a edge highlighting OR drawing only other spirtes without objects.
HTML DOM Background - PROBLEM: big and ugly aliasing in models.
What can I try more? Thanks!
You could maybe try drawing in several passes, i.e. making a first render of the background scene to a buffer, and then a second one over the first "buffer". Maybe using the buffer as background (painting it in 2D with an orthographic projection, and disabling depth buffer writes in that pass).
I haven't tried it myself with three.js, but that's how I'd do that with "traditional" OpenGL.
If you want a "3d" background i.e. something that will follow the rotation of your camera, but not react to the movement (be infinitely far), then the only way to do it is with a cubemap.
The other solution is a environment dome - a fully 3d object.
If you want a static background, then you should be able todo just a html background, i'm not sure why this would fail and what 'aliasing in models' you are talking about.

Categories