Best rendering optimization strategy for 25.000 hexagons?

I have created a planet made of 25.000 hexagons using hexasphere.js. It works great on my gaming computer, but not so much on my basic laptop. I think there is a lot of room for optimization. I have been looking at the following:
1 - InstanceMesh. With 25.000 hexagons it seems the way to go. However, their geometries are not 100% the same. They get a little stretched and squished here and there to fit together. Is it possible to create a “base” hexagon first with InstanceMesh, and then slightly adjust each geometry afterwards?
2 - Merge meshes. If I merge alle the hexagons into 1 single mesh, then that would only require 1 render call per tick, correct?
3 - Culling hexagons not visible on the other side of the planets. Could I create a sort of culling system, where hexagons on “the dark side of the planet” that are not visible are not rendered?
4 - BufferGeometryUtils.mergeBufferGeometries. I am not sure, but it seems like this could help if the geometries in question are similar, but not necessarily identical, which I is what I am guessing the hexagons are in this context?

Also, I want raycasting to work on each hexagon. Does this exclude any of the beforementioned strategies?

1 Like

I have looked up the hexasphere.js you linked - quite an interesting concept with an attractive visual result. Digging deeper, I found this illustration:

The “6-frequency subdivision” comprises perfectly regular and identical triangles only. This could well lend itself to InstancedMeshes, as a 1st step.
In a 2nd step, the “stretching and squishing” is the result of the projection of triangle vertices onto a sphere. This might(!) possibly(!) be accomplished by a cleverly designed vertex shader?
@prisoner849 ?

I generated these hex planets using a subdivided tetrahedron.
Hit space to generate a new solar system.
You can see both the magic and pain of tiling spheres with hexagons.. namely that you can’t do it without using some pentagons as well.. which means all your logic for pathfinding etc have to be more general than something hardcoded for hexes.

5 Likes

Why not for instancing?
Write the data of vertices into a data texture, read it in vertex shader :thinking:

1 Like

I have zero knowledge of writing shaders and what they can do.

The resulting hexagons are not identical, plus there will inevitably be 12 pentagons, when starting out from an icosahedron, like the TO does.

1 Like

The hexasphere object comes with neighbour tiles information for all tiles, so pathfinding should be pretty simple using something like A*

yeah. I wrote an astar for this, it was tricky to get right. :slight_smile:

3 Likes

I’m wondering if it’s possible to apply skewing to the instances via their transformation matrices, though that would depend on the type of data returned by hexasphere.js.

That’s where I’m a little confused; when using instances are you only allowed to changes meshes using transforms, or can you also change specific points of the geometry so that the points are identical to what i get from the hexasphere object?

If not, I don’t think I can get the hexagons to line up as well as I do with the current non-instanced method

Skewing the matrices is an option and doesn’t affect the vertices, and no, you can’t update the vertices, when instancing, any change to the original geometry will be reflected in all instances!

I know how to skew a square or a cube, but I’ve never tried it with a hexagon. Since your hexes are flat, it should be doable to some extent. I’m looking into it now and will let you know when I inevitably fail miserably :sweat_smile:

1 Like

Well… I tried it.

A single InstancedBufferGeometry for hexagons and pentagons.
Pentagon is hexagon, but with one degenerated triangle.

Demo: https://codepen.io/prisoner849/full/azOBGKq

Just had a thought, that there is also BatchedMesh. Which might be an option :thinking:

5 Likes

Yeah I think it would be tough to pull off by instancing… since each hex is a slightly different shape. All of this is pretty academic tho.. this is best implemented as just a single mesh + geometry imo.

@vielzutun.ch

how do you call a projection inside a center?
eg. for cubic it is simple: top, floor; left, right; front, rear

Good technical thread on Mastodon here, with advice about rendering hexagons:

4 Likes

You were right, the idea of skewing instances was appealing, and I spent way too much time fiddling with it, but that’s just not how it works! (You can’t blame me, I did predict it would fail :sweat_smile:)

On the bright side, I managed to put together a demo using merged geometry. It’s a bit brute-force for my taste, but it was the best I could do with the time I had. I’ll explore other approaches and see if there’s a cleaner way to make it work.

[live Demo] - [github repo]

8 Likes

I would prefer to use exactly this approach over instancing with writing data to texture and patching of shaders :slight_smile:

4 Likes

The maestro has spoken, case closed. :smiling_face_with_sunglasses:

3 Likes

Jesus, that was fast!

1 Like

Very, very cool! But doesn’t his scenario involve many hexagon columns of the same geometry, just adjusted for height?

Yes, but even with identical hexagons, the overall consensus of the thread was to put the hexes into large batch geometries and not try to be fancy with instancing. So I think that goes double if your hexes are more complex to instance than his. :slight_smile: