This devlog is absolutely packed with shinies!!! And since I know most of y'all want to get straight to the good stuff, here's the link:
Limit Theory Devlog Gallery - Lindsey 11.10.17
Since I'm doing every other week, Josh added some pictures of what I was working on last week in his last devlog. BUT, he did not go into detail about how those shapes were made, so I'll talk a bit about it more today.
Keep in mind that I'm still in the basic stages of creating the pieces that will make up ships. These images don't represent whole ships and stations, but rather pieces that will go into their formation.
I've started writing tutorials to document everything that I'm learning about procedural geometry. I feel like there's a huge deficit in the game devlopment community about procedural & computational geometry, so I hope the blog helps people get started. They'll also be super interesting for those of you who want to know as much about the nitty-gritty of how LT is made. HOWEVER!!!! This is not Official LT work. I write them in my spare time, mostly for fun- don't interpret them as official documentation of LT code or official LT tutorials. They're written in general pseudocode that could be adapted for any language in any engine, and don't use real LT code. In addition, they do NOT replace the devlogs, but I will link them to augment the logs for those of you who want to learn about procedural geometry. OK! Now that we have that out of the way, here's the link: Lindsey Reid's graphics tutorials blog on Wordpress.
On to the devlog!!
10.27.17 - 11.10.17
- With lots of collaboration with Josh, refactored shape library for architecture & performance.
- Added Icosahedron
- Added Stellation
- Added Extrusion
- Tweaked Torus
- Added mushroom-y shaped function
- Tweaked Hypocycloid (formerly "Hypotrochoid", now named as specific case) so that number of points on the star can be customized
- Added JointField object, for storing list of joints
- Began writing cluster functions, for creating groups of shapes. And groups of groups of shapes.
- Added linear cluster
- Added Bezier curve cluster
- Added circle cluster
- Josh added a few warping functions that are very relevant to list here:
- [Josh] Added AxialPush function
- [Josh] Added Sphereize function
- [Josh] Added ExponentialStretch function
What's with Shapes?
The Shape object is our way of storing information about the meshes we generate. We (now) make no distinction between 'basic', low-poly Shapes like boxes and spheres and Shapes that are generated as combinations of other Shapes. This allows us to pass in a combination of Shapes to a combination-maker, allowing us to create complex Shapes like these rings made out of curvy tendrils. Here, the curvy tendrils are their own Shape that get passed into the Ring function.
Shapes store a list of verticies and a list of polygons. Polygons are arbitary-length list of indicies. Storing indicies grouped into polys instead of tris was Josh's idea and implementation, so thank you massively, Josh! We also now convert the Shape into an engine-level Mesh at the very LAST step of Station/ Ship creation before passing that Mesh onto the renderer. This was another piece of Josh's refactoring work that gives us a little performance boost.
After Josh did all of this refactoring for how Shapes work, I then refactored the shape-creation functions & Joint functions to use new Shape system. Josh and I have found that using n-length polys instead of only tris for shape creation better... describes shapes. This concept is hard to put into words, but if you think about it, many shapes like the dodecahedron with its pentagon faces, is better described with 5-index polygons than as triangles. Then, when we go to perform warping functions like extrusion on the Shape, the output looks much better if the polys of the shape are accurately represented in code AS the polys they are, instead of subdivided into tris.
Icosahedron & New Torii Join the Party!!
Not much fancy to say here: I wrote an Icosahedron shape! w00t
In addition, I added a gumdrop/mushroom shaped Torus function, and tweaked the Hypocycloid so that it can have an arbitrary number of points on its 'star' shape.
New Torus Hypocycloids with N points
Stellation & Extrusion & Other New Warps
Lots of the pretties from the last devlog gallery are a result of applying the new Stellation, Extrusion, and warping functions to the Icosahedron and circular Torii. I wrote the Stellation & Extrusion functions and the shapes, and Josh added the fancy warps.
I detailed how Stellation and Extrusion work on my personal blog, so I'll leave those links there for those of you who want the details. Put simply, stellation turns every polygon on a mesh into a pyramid shape, and extrusion turns every polygon into a prism.
Here's a sequence of stellations & extrusions applied to an icosahedron. Here's an example of stellation applied to every face on a torus. Notice how the torus is now "pointy": And here's an example of extrusion applied to a torus. Notice how the quads of the torus now "stick out", or "extrude", from the body: Those torii also have a combination of AxialPush, Sphereize, or ExponentialStretch warp applied to them. I'm going to explain these later because I'm running out of time to write this devlog, and Josh wrote these functions anyway OOPS.
Joint Fields & Cluster Fu...nctions
Now that I've got quite a robust library of basic shapes, I'm beginning to experiment with how to join those shapes together into interesting looking groups. While writing all of these cluster functions, there are two important things I'm keeping in mind:
- I'm keeping my reference library of stations and ships close, and trying to write clusters that create patterns often found on space ships. In general, this means lots of regular, geometric patterns made of low-poly shapes, with a rare occurance of something more natural or irregular. My functions therefore need to reflect that linear patterns should be more common, with curvy or other more complicated patterns being rarer. Maintaining this has a lot to do with the probability distributions I used for choosing what patterns a station is made out of and what shapes go in to those patterns. I'm refining these balances as I go.
- The distribution of the types of patterns ALSO has to do with the personality of the race that created them. For example, the spiky patterns you see in the gallery are better suited for an aggressive race. When you see a station made of dark, spiky boys like this one here, the player should be able to safely assume that the race who created it is likely to attack. My functions need to be able to take input such that high-level information about race personality can customize the general look of their architecture. We don't have that code yet, but I don't want to have to go back and refactor my generation algorithms to support it, so I'm planning early.
All of these patterns are built on the backbone of JointFields. Quite simply, a JointField is a list of Joints. Joints define a position and a direction, so that when you snap a shape onto a Joint, it is placed at that joint's position and is facing that joint's direction. The JointField object comes with functions that will help you generate them in lots of different patterns: lines, circles, curves, and lots of others yet to be written.
Joints can ALSO be generated from a Shape, with the joint's position placed in the center of each poly, facing the direction of the poly's surface (AKA the normal). This means that you can also snap Shapes to other Shapes! This has been possible since last devlog, but has been refactored to be able to work with any n-length poly instead of just tris & quads.
In addition, the cluster-generating functions have the ability to scale shapes based on their position in the cluster. Notice how some of the curvy clusters seem to taper off in size. This is just one example of ways I'll be able to randomize clusters so that we get extremely unique results every time. There is much else to be done in the way of customizing clusters so that they can combine to create a unique aesthetic for each civilization. This is only the beginning...
Here are a few clusters I worked on this week! Fancier examples can be found in the rest of the devlog gallery.
Linear cluster: quite simply, just a straight line of shapes. Bezier curve cluster: a curvy line created using a quadratic Bezier curve algorithm. Circle cluster: shapes arranged in a circle.
Notice how the direction that the shapes are facing is sometimes all the same direction regardless of the arrangement, and sometimes the shapes all point towards the center. Having Joints specify a direction in addition to a postion allows us to do this! Circular cluster OF curves?!?!?!?!?!?!!! :000
That's what I have to show for these last two weeks! Lots of good archiecture, and lots of fun new shapes and clusters. We're really starting to see how powerful it can be when two similar, yet unique brains combine: Josh's brain with his amazing math skills and practical computational geometry experience, and my brain with my artistic eye and creative coding ability. I can't wait to see what we come up with in the following weeks
As always, I'm up for comments & suggestions about what y'all want to see in the devlogs and how well I'm balancing technical details with simple pretties. Thank you for reading! <3
Gallery link again!!!