I've finally managed to get this planet project done. It is mostly a study in tilesets, but it also ventured into fluid dynamics, atmosphere shading, and a bunch of other interesting stuff on the way.
The tech is built upon the core principles behind Brick Block, but with triangular instead of cubic tilesets. Triangular tilesets creates way fewer permutations than square ones, but it's a pain not to be able to snap things to an orthogonal grid.
This project took quite some time. Mostly because I pivoted back and forth a few times in both style and tech. Here are some screenshots from the journey. Hopefully, they also give some clue as to how it all works:
@stilobique , for sharing the planet you've built? That would be awesome. I don't really know how to build that though Yes ; adding a social option can be great ^^ .
Don't mean to infringe upon your craft, but have you had any thoughts on using use for more nefarious purposes, because i know some tabletop rpg'ers who'd probably give their souls for a map creator as dynamic and intuitive as this (they're always looking for ways to better the experience of long distance play).
@aFungusAmongUs , that's a niche I don't really know anything about. Would it just be a map to keep as a reference for your d&d adventures, sort of?
basically, but part of it being the whole "immersion" aspect of it. though im hardly an expert on these sorts of things, so if you consider it as a potential venture im sure there's a number of forums or subreddits that could help.
@Lee3dee , thanks. Yeah, the bridges where a bit tricky to make, because they require the triangles to know more about their neighbors than they otherwise would need to. They fill a great aestheticall function and they really give you a sense of 3D that a heightfield alone can not. Especially when you have bridges over a city, so that it looks like people can pass both below and above the bridge. I deliberately chose to not show the bridges in my presentation-GIFs, because I figured people would be pleasantly surprised when they discovered them by themselves.
St4lis, you've created something really amazing here! I just flat out love it. Solid work. Solid demonstration. Where are you going with this project? It's just beautiful!
... I couldn't resist.. None shall stand against the new galactic empire!!
really cool! a question though; do you make a tile (triangle mesh) for every possible transition or is there some procedural magic happening?
All the tiles are hand made. That is sort the key idea here, since it allows you to turn each tile into its own handcrafted diorama (though admittedly, I haven't taken the model work quite that far). It does combine meshes from several tilesets though, so that it uses the same cliff beneath a forest as it does beneath a city. And it sometimes use the same tiles for several transitions. The city wall, for example, looks the same if it is up against a plain, a slope, or a cliff. In the end, the basic land tileset consist of maybe 25 tiles, and the city wall consists of maye 6 (plus some extra for bridges and gates)
My only remark and nitpick would be about the interaction model for tile creation. I wish it was possible for the user to paint a continuous stroke over the sphere to lay multiple tiles, as opposed to having to click on each desired slot individually (which often causes tiles to pile up rather than be laid next to each other). In that context I could see the rotation of the camera (or of the planet) to be done zbrush-style, by clicking and dragging over the empty space around the model.
That said I've only tried the demo in browser, and not on a touch device - so maybe this might not work there.
My only remark and nitpick would be about the interaction model for tile creation. I wish it was possible for the user to paint a continuous stroke over the sphere to lay multiple tiles, as opposed to having to click on each desired slot individually (which often causes tiles to pile up rather than be laid next to each other). In that context I could see the rotation of the camera (or of the planet) to be done zbrush-style, by clicking and dragging over the empty space around the model.
That said I've only tried the demo in browser, and not on a touch device - so maybe this might not work there.
Awesome work regardless !
Interesting thought. I think that would be a tradeoff where some intuitiveness is lost and some functionality is gained. My goal was to mimic the camera behaviour from google maps, as I figured a camera like that would be easier to understand for inexperienced users that aren't used to spinning around 3D models all day.
Really nice work. I'd actually like to ask you about the skybox. It looks like a gradation of colour between points/verts rather than something painted.
This is so good, I love these mini worlds you do. Just a question, how do you come up with the ideas for all these small worlds you make? Is it the technical challenge that is driving you? Or is it just an urge to create tiny awesome worlds? Like what is the end goal? Whatever it is they are awesome, so do not stop. ^^
This is so good, I love these mini worlds you do. Just a question, how do you come up with the ideas for all these small worlds you make? Is it the technical challenge that is driving you? Or is it just an urge to create tiny awesome worlds? Like what is the end goal? Whatever it is they are awesome, so do not stop. ^^
Thanks!
On the creative side, they are mostly tech-driven: I have some idea that I want to test or some problem that I want to solve. In both this one and Brick Block, I wanted to find a good and systematic way of working with handcrafted tilesets. Along the way, I find other interesting problems I also want to tackle. In this case, I stumbled into some fluid dynamics, some atmosphere shading, and I had to get a lot more comfortable with quaternions.
My projects typically pivot several times during the process, as I like to follow all the implications where I think they should lead.
Apart from the technical side, I always want to make things beautifull. There are so many people out there making super cool technical experiments with poor presentation, be it a boring blog post or a gray boxed youtube video with a low-quality voice over. That is a waste. My philosophy is that If I'm gonna make a cool system, I might as well wrap it in some slick UI and add sound effects.
I don't think I'm done with tilesets yet, and maybe my final goal will be to make an actual Unity tool that developers can use for fast and good looking level design, either with their own or some included tilesets.
Okay, that's awesome! How did you generate the triangular vert color model from the image? I've never figured out a way to do that that's not terrible.
Really inspiring stuff. How did you deal with the 5-sided faces each sphere consisting of hexagons inevitably gets? Did you model special tiles for those faces?
Okay, that's awesome! How did you generate the triangular vert color model from the image? I've never figured out a way to do that that's not terrible.
It took a while to make it work. I used the tool found in Simons blog post. That tool only gave me a tessellated plane though, without functioning vertex colors. I imported that plane into Maya, and applied the texture as vertex colors in Maya. To turn my plane into a sphere, I used Mayas transform attributes tool to transform the vertex positions from a poly sphere, using the UV as sample space.
Really inspiring stuff. How did you deal with the 5-sided faces each sphere consisting of hexagons inevitably gets? Did you model special tiles for those faces?
My tiles are neither pentagonal nor hexagonal, but triangular. Hexagonal tilesets would require so many permutations for all the transitions that I don't even wanna think about it. My triangular implementations could theoretically be placed on top of any triangulated 3D mesh. There are some clues in my WIP pictures on how the triangular tilesets work.
Interesting approach but probably the one that saves your mind from insanity.
Code-wise: I guess you ensure that your initial triangulation of the sphere is based on equidistant vertices with a distance that resembles your tiles' edge length? So that when you spawn a tile it fits nicely into place?
No wait - you can also build at different heights which means that your tile meshes need to taper from max height to min height (where height equals radius of the different click-spheres). Was the tapering done by code (as in directly adjusting vertex positions in the mesh class) or by vertex shader?
Interesting approach but probably the one that saves your mind from insanity.
Code-wise: I guess you ensure that your initial triangulation of the sphere is based on equidistant vertices with a distance that resembles your tiles' edge length? So that when you spawn a tile it fits nicely into place?
No wait - you can also build at different heights which means that your tile meshes need to taper from max height to min height (where height equals radius of the different click-spheres). Was the tapering done by code (as in directly adjusting vertex positions in the mesh class) or by vertex shader?
Again, really cool project.
Yeah, you've got it. The vertex deformation is done by code. I couldn't figure out a good way to do it in a vertex shader that wouldn't require me to either have separate materials for each tile (thus making the rendering much more expensive), or to loop through all the vertices in code anyway. The taper is more a byproduct than a feature.
Interesting approach but probably the one that saves your mind from insanity.
Code-wise: I guess you ensure that your initial triangulation of the sphere is based on equidistant vertices with a distance that resembles your tiles' edge length? So that when you spawn a tile it fits nicely into place?
No wait - you can also build at different heights which means that your tile meshes need to taper from max height to min height (where height equals radius of the different click-spheres). Was the tapering done by code (as in directly adjusting vertex positions in the mesh class) or by vertex shader?
Again, really cool project.
Yeah, you've got it. The vertex deformation is done by code. I couldn't figure out a good way to do it in a vertex shader that wouldn't require me to either have separate materials for each tile (thus making the rendering much more expensive), or to loop through all the vertices in code anyway. The taper is more a byproduct than a feature.
Does the vertex deformation warp the tiles to the actual icosphere faces as well as handling the height tapering? There always seems to be some level of distortion around the 5-poles/pentagons for me, so trying to fit together identical triangular tiles won't work without some "massaging".
Would you be able to elaborate a little on the basic approach of your vertex deformation? (i.e. barycentric coordinates, some sort of deformation cage, etc.)
Related question: Is the animated "bulge" effect when placing terrain handled with the same approach?
Does the vertex deformation warp the tiles to the actual icosphere faces as well as handling the height tapering? There always seems to be some level of distortion around the 5-poles/pentagons for me, so trying to fit together identical triangular tiles won't work without some "massaging".
Would you be able to elaborate a little on the basic approach of your vertex deformation? (i.e. barycentric coordinates, some sort of deformation cage, etc.)
Related question: Is the animated "bulge" effect when placing terrain handled with the same approach?
Amazing work btw.
I first calculate the barycentric coordinates for each vertex within a module with a bunch of cross and dot products.
The x and z position of a vertex in the deformed module is just the tile corners multiplied with the barycentric coordinates of the vertex. I then add the Y position of the in-vertex multiplied with the tile corner normals (as derived from the mesh that is used to generate the grid). So if I've got a convex surface, the tapering just happens by default.
As you correctly anticipate, there is indeed some distortion around the pentagons, It's just not very noticeable. In the towns and forest I also add an extra mesh at the corner between the tiles. That mesh has no internal deformation, but is only randomly rotated. It really helps in breaking up the repeating pattern.
The animated bulge is way less complicated than that. I just offset the verts along their normals with a magnitude derived from how far from the mouse click they are. It's such a simple animation, but it really adds to interactive feeling. Its very low hanging fruit.
Hi again. Another question for you (if you don't mind that is). What was your solution for highlighting around the cursor location?
I assumed a projector, but that doesn't allow for shader based mesh displacement. On closer inspection the line width around the highlight seems to be in screenspace, which is also interesting.
Hi again. Another question for you (if you don't mind that is). What was your solution for highlighting around the cursor location?
I assumed a projector, but that doesn't allow for shader based mesh displacement. On closer inspection the line width around the highlight seems to be in screenspace, which is also interesting.
The highlight is actually surprisingly complicated.
I've built a system for creating and projecting cubemaps onto the planet. This system is used for the shading, for the texture splatting and for the highlighting.
The values are baked down to the vertexcolors on the mesh used to create the planet. That mesh is then drawn to a cubemap from the inside. That cubemap is then sampled in the shader.
The pixel thickness is just a sweet trick I've developed where you divide a gradient by it's fwidth, and thus get a pixel perfect line. It can be used on any gradient.
Replies
I wonder how you managed to get these shading results in Unity.
This project took quite some time. Mostly because I pivoted back and forth a few times in both style and tech. Here are some screenshots from the journey. Hopefully, they also give some clue as to how it all works:
Looks very similar to a game concept I developed some 10 years ago but I never had the tech to realize it.
Oscar
... I couldn't resist..
None shall stand against the new galactic empire!!
My only remark and nitpick would be about the interaction model for tile creation. I wish it was possible for the user to paint a continuous stroke over the sphere to lay multiple tiles, as opposed to having to click on each desired slot individually (which often causes tiles to pile up rather than be laid next to each other). In that context I could see the rotation of the camera (or of the planet) to be done zbrush-style, by clicking and dragging over the empty space around the model.
That said I've only tried the demo in browser, and not on a touch device - so maybe this might not work there.
Awesome work regardless !
For the base image, I'm using a creative commons picture of the milky way with a bunch of smart blur and noise reduction filters to remove the stars.
The stars in my skybox are added as quads, so they can be numerous and sharp.
On the creative side, they are mostly tech-driven: I have some idea that I want to test or some problem that I want to solve. In both this one and Brick Block, I wanted to find a good and systematic way of working with handcrafted tilesets. Along the way, I find other interesting problems I also want to tackle. In this case, I stumbled into some fluid dynamics, some atmosphere shading, and I had to get a lot more comfortable with quaternions.
My projects typically pivot several times during the process, as I like to follow all the implications where I think they should lead.
Apart from the technical side, I always want to make things beautifull. There are so many people out there making super cool technical experiments with poor presentation, be it a boring blog post or a gray boxed youtube video with a low-quality voice over. That is a waste. My philosophy is that If I'm gonna make a cool system, I might as well wrap it in some slick UI and add sound effects.
I don't think I'm done with tilesets yet, and maybe my final goal will be to make an actual Unity tool that developers can use for fast and good looking level design, either with their own or some included tilesets.
In maya, start with a platonic solid (an icosahedron or a dodecahedron) then subdivide it.
In blender, I believe they are called Icospheres.
Really inspiring stuff. How did you deal with the 5-sided faces each sphere consisting of hexagons inevitably gets? Did you model special tiles for those faces?
Interesting approach but probably the one that saves your mind from insanity.
Code-wise: I guess you ensure that your initial triangulation of the sphere is based on equidistant vertices with a distance that resembles your tiles' edge length? So that when you spawn a tile it fits nicely into place?
No wait - you can also build at different heights which means that your tile meshes need to taper from max height to min height (where height equals radius of the different click-spheres).
Was the tapering done by code (as in directly adjusting vertex positions in the mesh class) or by vertex shader?
Again, really cool project.
Would you be able to elaborate a little on the basic approach of your vertex deformation? (i.e. barycentric coordinates, some sort of deformation cage, etc.)
Related question: Is the animated "bulge" effect when placing terrain handled with the same approach?
Amazing work btw.
The x and z position of a vertex in the deformed module is just the tile corners multiplied with the barycentric coordinates of the vertex. I then add the Y position of the in-vertex multiplied with the tile corner normals (as derived from the mesh that is used to generate the grid). So if I've got a convex surface, the tapering just happens by default.
As you correctly anticipate, there is indeed some distortion around the pentagons, It's just not very noticeable. In the towns and forest I also add an extra mesh at the corner between the tiles. That mesh has no internal deformation, but is only randomly rotated. It really helps in breaking up the repeating pattern.
The animated bulge is way less complicated than that. I just offset the verts along their normals with a magnitude derived from how far from the mouse click they are. It's such a simple animation, but it really adds to interactive feeling. Its very low hanging fruit.
What was your solution for highlighting around the cursor location?
I assumed a projector, but that doesn't allow for shader based mesh displacement.
On closer inspection the line width around the highlight seems to be in screenspace, which is also interesting.
I've built a system for creating and projecting cubemaps onto the planet. This system is used for the shading, for the texture splatting and for the highlighting.
The values are baked down to the vertexcolors on the mesh used to create the planet. That mesh is then drawn to a cubemap from the inside. That cubemap is then sampled in the shader.
The pixel thickness is just a sweet trick I've developed where you divide a gradient by it's fwidth, and thus get a pixel perfect line. It can be used on any gradient.