Best rendering optimization strategy for 25.000 hexagons?

@donmccurdy
is there a balance between instancing same hexes and between using variation of hexes (combinatorial choice), eg. instancing same hexes (how many, 1-2?) and then decide to use variation of hexes instead of same hex

I would personally not use instancing unless I am drawing something considerably more complex than a hexagon. Too small and too cheap to spend time/complexity/overhead trying to reuse them. Think of them like triangles (1 hex = 4 triangles), you can have many triangles in a Mesh or BufferGeometry and it’s fine that they’re not reused, because they’re very cheap.

2 Likes

You can do whatever you want to instances. You could even chain a bunch of if/else and do completely different logic on each instance.

I’m curious about the math to create the instance matrices to make a hexagon sphere out of instances.

Sounds like a nightmare.. position is easy enough.. but orientation?

edit: aaand yeaaaa.. just asked gpt4o about this:

Even on a geodesic sphere from a tetrahedron, the hexagons near the pentagons get compressed or distorted to "make room."

So every hexagon coming from one surface of the tetrahedron has a slightly different shape/edge lengths.

So you literally just can’t instance all this.. unless you can encode the distortion of the hexes mathematically into shears and scales in the instance matrix?

Sending out a :bat: signal:
@PavelBoytchev

2 Likes

@manthrax Signal received.

Of course it is possible to have different hexagons as traditional instances .. even hexagons that are deformed beyond matrixability. I’m sure of this, because I have done it 4 years ago. Here are some videos. All the people are instances of one single geometry. The magic happens in the vertex shader there vertices are adjusted; and in the fragment shader where clothes are drawn.

https://x.com/PavelBoytchev/status/1424316107893137409

https://x.com/PavelBoytchev/status/1425439353535336450

https://x.com/PavelBoytchev/status/1470035586719309828

However this magic comes at a cost - more memory is used. All info that the shader needs in order to adjust the vertices could come from instance attributes. In the worst case scenario the actual coordinates could be precalculated in JS and then passed as attributes.

I could try to cook a demo (if needed), but not before this weekend.

6 Likes

i remember that we have physics

and that threejs engine may emulate physics using glsl either particles

and in physics we have van-der-waltz powers (electronics, eg. small robots can create small robots and further, but when we have enough small robots then robots cannot reproduce robots cause of van-der-waltz powers, vertices becomes sticky)
it is near to term of fluctuation (puankare, john von neinman)

is there way to use different context when we speak about triangles in context of hex

trippy. In my mind that sorta brings up raytracing.. I wonder if there are any cool raytraced hexspheres out there..

Yes, my question also. If the sphere is one giant mesh, how can the user select at specific hexagon tile?

In my planet thing, I got the UV coordinate and projected it back onto the texture… I don’t know if it really was “correct” but it worked ok.

This is the style of texture that sent me down the original rabbit hole:

2 Likes

yes, that is a really question why with optimization provided out of the box
we need to do keep in mind that 1 hex = 4 triangles, to make computation work with hexagon

One could instance the large triangle in the middle here:

Or even single triangels and arrange them into these 10-12 however many large faces.

Then just pos = normalize(pos) and you get a sphere. Hexeagons will be what i think is a “dual graph” for these triangles. If this is delauney, hexagons will be the voronoi version. Id maybe remove the three triangles that touch the vertices, and see how far i get with that.

2 Likes

You don’t have to imagine, this was the best result I could get with instancing.

3 Likes

damn… close! :smiley:

1 Like

I think it is getting clear what direction will work, but just to cover all bases: what about, instead of merging meshes, keep the individual meshes and perform culling on tiles that are out of view, meaning on the other side of the planet? Then I only need to render about 12.500 tiles. Should also make raytracing easier?

Had to give it a try:

  • 25161 plates on a sphere (hexagons and a few pentagons)
  • raycasting and changing color of individual instances
  • no external library is used, only Three.js and its stuff
  • no custom shader involved, just plain vanilla Three.js

The result (black plates are the mouse cursor path):

https://codepen.io/boytchev/full/bNdWvrW

image

Before you kick my @ss, here are my confessions:

  • the plates are not polygons, they are cones
  • actually just one cone instanced 25k times
  • to keep it simple, the code is not optimized
  • thanks @dubois for mentioning Voronoi
  • here is the same approach for different usecase: Voronoiless
11 Likes

I didn’t get why it works, until I saw the parameters of cylinders :sweat_smile:

3 Likes

Wauw, that runs super smooth.

Is it possible to define the neighbours of each tile, for pathfinding purposes?

Each tile has a center. All other tiles with centers within some range are neighbours.

5 Likes

…aand cut and scene.

very cool @PavelBoytchev

(For anyone wondering about cones / voronoi:)

This was the way I first saw voronoi implemented in fixed function gl in the 90s.

3 Likes

Ok, so if I want some kind of mapping of that, I can just run a loop of all the tiles, get all tiles within x radius if each tile, save those 6 or 5 neighbours, and Bob’s your uncle :+1:

2 Likes