Hi guys!
This is a mini project just I started. Hopefully it won't take much time. I'm trying to figure out a neat system to generate various car bodies with as little geometry as possible. So extremely low poly but still in realistic proportions. The system is meant to be used in another project that needs a bunch of simple but diverse car designs. I'm hoping to get some feedback on how to tackle this from art/design and procedural 3d modeling point of view.

Aesthetics-wise I'm inclined towards extreme simplicity of original Elite Frontier spaceships. Due to technical reasons they consisted of only few triangles but still managed to look cool, if somewhat same-y:

So the idea is to use a single mesh topology consisting of as few polys as possible. This topology should be driven by some parameters that can rearrange it into multiple body types. The less parameters the better. So the main problem here is what topology to use and which parameters should drive it for maximal versatility.

Here are the types of car bodies I'd like to be able to build:

  • micro
  • hatchback/suv
  • sedan/coupe
  • 70s muscle
  • sports
  • limo
  • pickup
  • (mini)van
  • truck
  • bus

After some thinking I came up with this:

We'll see if it can be formed into all of the car types listed above.

Sounds cool. I think it wouldn't be too hard if you stick with a retro style 3D.

The concern for me would be the vehicle controller itself because I have found it to be a tricky sod at times setting things up in Godot, not as bad as Unity, but the VehicleWheels as an example have their quirks you need to work out and it can get frustrating. The mesh part should be fairly straightforward but yeah, physics lol.

  • xyz replied to this.

    Lethn Yeah, car physics are nasty 🙂 Luckily I intend to stay away form it here. The focus will mainly be on looks/proportions. In the project this is built for, all cars move "on rails". Maybe they'll even be completely wheel-less and hover on antigrav fields.

    So I've written some staple helper code. Most importantly a boring function that spits out mesh patches with smoothed normals. It takes a list of line strips as an input. Works basically like a multi-profile loft tool in a 3d app:

    I'm planning to combine multiple such patches to get some hard edges between smooth surfaces. Although it'll be only couple of quads per patch, I'd like this to mimic hard/soft edge balance on real car designs.

    And here's the beforementioned basic topology constructed out of such patches:

    Earth shattering stuff, I know 😃

    I think perhaps the most dominate identifier for a block of play dough being a car is definitely the wheels. I would generate 2-6 pairs of wheels and force the mesh generation to form a mesh around them.

    • xyz replied to this.

      Erich_L Got it!

      1. make wheels
      2. do mesh magick around them
      3. ????
      4. PROFIT!!!

      Seriously though, it's ok to start from wheels but there's still a question of what to do with the body mesh. The wheels only establish some sort of bounding rectangle. Yeah they sure do communicate that the thing is a vehicle but I'd like to have something more streamlined than a playdough potato attached to them.

      I'm looking forward to how this project progresses. I want to possibly generate terrain, but it's down the line from where I am right now.

      • xyz replied to this.

        fire7side Thanks. Yeah, terrain generation is fun and there's a ton of info out there. I'm sure you'll be able to pull it off without problems.

        Following @Erich_L expert advice, I implemented a function that makes cylinder and circle meshes. We can now have some wheels. Since there will be no physics, all wheels are crammed into a single mesh to avoid excess transforms.

        Also started implementing parameters for shaping the body mesh. Went with some "no brainers" first, like overall dimensions (width, length, height)


        And then cabin size, position and slopes. There is a separate parameters for side, front and back slope of the cabin. I think this is important because these slopes contribute a lot to car's overall "character".

        Added a bunch of parameters to control elevation and sloping of car's front and back boxes, as well as wheel radius/thickness and spoke size. Some parameters have absolute values while others are normalized to 0-1 range to keep them constrained to "parent" dimensions. This is done to minimize the number of situations in which the output mesh can "fall apart" when using randomized parameters.

        Also added vertex coloring to the mesh builder so paint/glass/spokes can be differently colored.

        And just to make things a bit more pleasant to look at I added this dummy road and some lights/shadows.

        I've sat here watching this gif for maybe 5 minutes, man. It's got a spell on me.

        Yeessssss! I knew you could whip up some wheels without any problem and they really are IMO the first place to start on this kind of project. I know you're not going to regret having wheels - said every car designer ever. I too spent quite some time staring at the gif lolol.

        @Erich_L @packrat Thanks guys! Glad you've been enticed to ogle the gif for prolonged periods of time 🥳

        I've now added parameters to control two chamfers that go all along the length of the body (top and bottom). They refine the form somewhat, make it less raw/boxy. The parameters control chamfers' overall width and angle. The top chamfer's width/angle can additionally vary in front and back. It works like a variable radius fillet but only consisting of one step:

        I've also taken this potato-on-wheels on a test drive. No sure how it handles the bends though.

        Are you constructing the mesh with meshdatatool and surfacetool or array mesh or are you using some csg magic for it?

        • xyz replied to this.

          Woo hoo that car is THIIIIIIIIIIIIIIIIIIIIIIICK. I absolutely love it. Probably a good time to make this part of the main project now? No? Ok, probably need to add procedural textures then. Turn some Perlin noise into dirt, scaling opacity 1 near the bottom and 0.08 at the top.

          • xyz replied to this.

            Megalomaniak Are you constructing the mesh with meshdatatool and surfacetool or array mesh or are you using some csg magic for it?

            It's plain ArrayMesh. The key vertices are arranged into edge loops according to descriptive parameters mentioned before and the mesh is then lofted each time there is a change in parameters. It's fast. There is less than 100 vertices in total, including symmetrical ones.

            I was considering CSG. At first it indeed looked like a good idea. However, I figured with such low polycount, controlling it may be more cumbersome than fiddling with vertices directly. And god only knows what the final topology would look like, possibly complicating uv and vertex color handling. I'm also not sure if the resulting mesh can at all be plucked out of Godot's CSG system.

            The main challenge really was to figure out the topology. I wanted it as simple as possible yet versatile enough. The final topology (shown in the first post) looks like an instant obvious choice. However I spent quite some time in a 3d modeling app figuring it out. Needed to make sure it can be reshaped into a range of decently looking car forms. I initially thought a much denser mesh will be required.

            cybereality This is amazing.

            Thanks! It ended up looking and behaving better than I expected.

            Erich_L Woo hoo that car is THIIIIIIIIIIIIIIIIIIIIIIICK. I absolutely love it. Probably a good time to make this part of the main project now? No? Ok, probably need to add procedural textures then. Turn some Perlin noise into dirt, scaling opacity 1 near the bottom and 0.08 at the top.

            Not yet my dudebro! Still some loose ends to tie up. We'll see about the dirt 🙂

              Damn, that's some impressive work. Gives me that f-zero vibes, but with wheels. Wish I could make something half as amazing. 😍

              • xyz replied to this.

                xyz I'm also not sure if the resulting mesh can at all be plucked out of Godot's CSG system.

                In 3.x at least it could. I think you went about it the correct way tho. 🇦 +

                • xyz replied to this.

                  SuperDoomKing Damn, that's some impressive work. Gives me that f-zero vibes, but with wheels. Wish I could make something half as amazing. 😍

                  Thanks! F-zero vibe is close to what I'm aiming for.

                  Erich_L In 3.x at least it could. I think you went about it the correct way tho. 🇦 +

                  Right. Much cleaner this way and I know exactly what's in the mesh. I suspect CSG could produce artifacts, visible or not, for example when consecutive operands' faces or edges coincide. It'd certainly make more mesh data for the same look. Plus I like this self-imposed limitation of reducing everything to the same topology. Prevents me from piling more and more stuff on.