Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Kacer · May 04, 2015 at 09:26 PM · generationvoxelbitmap

Creating a voxel grid from several bitmaps

Hello people

A certain degree of knowledge about Dwarf Fortress is a plus for this question ;)

In short, i'll be recieving some bitmaps, to begin with it'll be colors of black and white like these two maps:

alt text

alt text <- this one is supposed to be loaded in twice

And from those two(three) maps, i want to make a script that can generate a 3D scene, so the end result will look like this:

alt text

I've thought about using voxels, as it seems to be the best sulution for something like this, as the final scene will be having about 100*250^2 blocks

This is an absolutely obscene amount of blocks, as well as polygons, of that i am aware. Which is why i'm thinking it'd be a good idea to use a voxels, as i've seen how many "blocks" minecraft can handle.

Before you shout "MINECRAFT CLONE" let me remind you that i'm making a visualizer for this game: http://en.wikipedia.org/wiki/Dwarf_Fortress

So yeah, i dont want anyone to write a tutorial for this, i'm more looking for feedback if this is actually possible, and if so, where can i find reading material about it, i've been googling a bit, and cant seem to find anything.

Thanks in advance

/Kacer

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Zarenityx · Jun 22, 2015 at 07:48 PM 0
Share

Just for all the people who do shout "$$anonymous$$inecraft Clone":

NOT ALL BLOC$$anonymous$$Y VOXEL GRAPHIC GA$$anonymous$$ES ARE $$anonymous$$INECRAFT CLONES! The first game to use voxel graphics was a helicopter sim called Comanche $$anonymous$$aximum Overkill, and nobody shouts "Comanche clone" at $$anonymous$$inecraft, and they didn't even shout "Infini$$anonymous$$er clone", the most recent voxel game before $$anonymous$$ecraft! Voxels are useful for a variety of purposes in games, particularly terrain, and the simplest and fastest way to do so is to make the blocky kind. Tons of games use blocky voxels, many of which were made BEFORE $$anonymous$$INECRAFT! True, $$anonymous$$inecraft did use voxels exceptionally well, but that does NOT mean that every other game that uses them is now somehow a 'clone' or 'ripoff' of $$anonymous$$inecraft. Following that logic, isn't every first person game we play really just a clone of $$anonymous$$aze? $$anonymous$$ojang doesn't even own the algorithm!

In other words, very few games accused of being "$$anonymous$$inecraft clones" actually deserve that shame, and in the meantime we have discouraged many people's development of games or software using voxels, which is a shame, since polygonal meshes are slowly become obsolete as graphics hardware is beco$$anonymous$$g better at rendering volumes.

In other words, those who accuse any blocky game as being a $$anonymous$$ecraft clone are just being ignorant, and unless you are actually attempting to recreate $$anonymous$$inecraft, your game is not going to be a ripoff or a clone.

I just felt that needed to be said.

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by Cherno · May 04, 2015 at 10:56 PM

Absolutely possible and not too difficult either.

Here are the basics:

The bitmaps have to be set to read-enabled in their import settings. It would probably be advisable to create another array for the bitmaps so they are in the right order and we don't have to create seperate variables for each:

 public Texture2D[] textureArray = new Texture2D[];
 private int texture_width = textureArray[0].width;
 private int texture_height = textureArray[0].height;

Note that this array has only one dimension. You can populate it with a simple function, or just set it's length in the editor and drag the textures into it in the right order.

Now we need to create our three-dimensional array. Since we only need to care about wether a cell (a position inside the array) is filled or not, we can just use an array with elements of type int. 0 would be clear, and 1 would be filled. The size of the array depends on the size of the bitmaps, of course, but for this example we can just assume that, as in the screenshot, the bitmap is 3x3 pixels, and there are three bitmaps, so our array has a length of 3 in all dimensions:

 public int[,,] blocks;
 blocks = new int[texture_width, textureArray.Length, texture_height];





Now we will iterate through our block array, one cell at a time, and take the color of the corresponding pixel of the bitmap and convert it to either 0 or 1.

 int x = 0;
 int y = 0;
 int z = 0;
 
 for(x = 0; x < blocks.GetLength(0); x++) {
      for(y = 0; y < blocks.GetLength(1); y++) {
           for(z = 0; z < blocks.GetLength(2); z++) {
                 Texture2D currentTexture = textureArray[y];
                 Color pixelColor = currentTexture.GetPixel(x, z).grayscale;
                 if(pixelColor.r >= 0.5f) {
                      blocks[x,y,z] = 0;
                 }
                 else {
                       blocks[x,y,z] = 1;
                 }
           }
      }
 }
 
 

So now we have the basic information we need to start creating our mesh. There are lots of voxel tutorials so IM' just gonna link to the one that got me started. It's in Unity Script but can easily be converted to C# if you want.

Link

It also uses a three-dimensional int array to it should be a perfect fit. Just delete the part where the int values get randomly assigned.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Kacer · May 05, 2015 at 04:00 PM 0
Share

Thank you for the great reply, way more than i had anticipated :D

The guide you've linked, to create voxels, thats just a chunk though, and from the guide it appears that it is limited to 65000 points, do you have a theory as to how i'd load a map like this into several chunks?

This is a whole new chapter in program$$anonymous$$g for me, and i find it quite complicated :)

avatar image Cherno · May 05, 2015 at 04:22 PM 1
Share

Yes, you need to implement chunks, but that is rather trivial really. It's basically like this:

The script that generated the mesh sits on a gameObject (one chunk). You pass it the whole block array as well as the starting and ending xyz values. Then you do the normal mesh generation, but you don't iterate through every block in the block array, but rather only through the blocks inside that specific chunk's xyz values.

The chunk objects themselves are referenced in their own three-dimensional array, with this array's dimensions being deter$$anonymous$$ed by the cell dimensions each chunk should have. So if you have a block array with a xyz length of, say, 9, and your chunk should have xyz lengths of 3, then your chunk array would have a xyz length of 3 (9/3).

So to put things in order:

  1. Define chunk array ( GameObject[,,] or ChunkRender[,,])

  2. Iterate through chunk array, instantiating a prefab at each position. The prefab would be a gameObject with meshfilter, meshrenderer, meshcollider, and the ChunkRender script.

  3. Access the instantiated chunk's ChunkRender script and set the xyz starting and end values

  4. When the loops are finished, you can call another function that iterates through the chunk array again and calls the ChunkRender function on their scripts. This is what you would do if you would want to update all the chunks during runtime.

Edit: Oh, and if you want more information... After playing $$anonymous$$ecraft...

Edit2:

 int x = 0;
 int y = 0;
 int z = 0;
 
 int worldSize_x = 9;
 int worldSize_y = 9;
 int worldSize_z = 9;
 
 int chunkSize_x = 3;
 int chunkSize_y = 3;
 int chunkSize_z = 3;
 
 ChunkRenderer[,,] chunkArray = new ChunkRenderer[worldSize_x / chunkSize_x,worldSize_y / chunkSize_y,worldSize_z / chunkSize_z];
 
 //create chunks... note that it doesn't matter where the chunk gameobject is located because it's the mesh's vertices that count
 for (x = 0; x < chunkArray.GetLength(0); x ++) {
      for (y = 0; y < chunkArray.GetLength(1); y++) {
           for (z = 0; z < chunkArray.GetLength(2); z++)    {
            GameObject chunkCur = Instantiate(chunkPrefab, transform.position, Quaternion.identity) as GameObject;
                ChunkRenderer chunkRenderer = chunkCur.GetComponent<ChunkRenderer>();
                
                chunkRenderer.start_x = x * chunkSize_x;
                chunkRenderer.start_y = y * chunkSize_y;
                chunkRenderer.start_z = z * chunkSize_z;
                 
                chunkArray[x,y,z] = chunkRenderer ;
           }
      }
 }
 
 //Update all chunks
 for (x = 0; x < chunkArray.GetLength(0); x ++) {
      for (y = 0; y < chunkArray.GetLength(1); y++) {
           for (z = 0; z < chunkArray.GetLength(2); z++)    {
                chunkArray[x,y,z].ChunkRender(blockArray);
           }
      }
 }



avatar image Cherno · May 05, 2015 at 04:37 PM 1
Share

Inside the ChunkRender function, the xyz loop would look like this

 for (x = chunkStart_x; x < chunkStart_x + chunkSize_x; x++)
         {
             for (y = chunkStart_y; y < chunkStart_y + chunkSize_y; y++)
             {
                 for (z = chunkStart_z; z < chunkStart_z + chunkSize_z; z++)
avatar image Cherno · May 05, 2015 at 04:40 PM 1
Share

I also edited my original answer, one paragraph waas at the wrong place, this one:

Note that this array has only one dimension. You can populate it with a simple function, or just set it's length in the editor and drag the textures into it in the right order.

Belongs under the code that declares the Texture array.

avatar image Kacer · May 05, 2015 at 04:54 PM 0
Share

Wish i could give you more upvotes on this, you're really helping me a lot :)

Show more comments
avatar image
1

Answer by $$anonymous$$ · May 04, 2015 at 11:18 PM

First of all huge Dwarf Fortress fan! Love the game. Must dig deeper!!!

Alright on to serious talk...

Is it feasible?

Short answer: Yes

Long answer: I've dabbled in mesh generation, voxel terrain, and such multiple times so I have a little experience but not a lot. Generating the mesh from the heightmaps is going to be the easy bit. It will be optimizing performance that will be hard.

You simply put cannot generate the entire dwarf fortress region at once (even as one mesh) as there will be too much vertices data for the engine to efficiently process so you'll need to create the mesh in chunks.

As well you will want to ensure you do not render any hidden faces and not render any faces that the camera cannot see. (I.E. the back of the mesh) Note Unity does perform optimizations if the face is not visible or if it is outside the camera's view, but I found that it wasn't always enough. (Mind you that may just be my bad coding...)

You can definitely do it but it just has a few layers of hidden complexity that you will need to be aware of before you embark.

If you want to see some code I would be happy to provide some that I wrote a while back.

Some of the tutorials that helped me out: http://studentgamedev.blogspot.co.uk/2013/08/unity-voxel-tutorial-part-1-generating.html https://www.youtube.com/watch?v=bpB4BApnKhM&list=PLbghT7MmckI4qGA0Wm_TZS8LVrqS47I9R (It's 2D but goes over mesh generation well)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Kacer · May 05, 2015 at 04:02 PM 0
Share

Thanks for the answer, i've bookmarked the thread, and will watch the videos later. $$anonymous$$eep an eye on the DF forums if i ever manage to finish this :P

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Voxel mesh generation not working. 1 Answer

Voxel based Terrain generation. Pointers please. 2 Answers

Huge C# Procedural Generation Errors. Why? 1 Answer

Cube Voxel not working. Help please 1 Answer

how to create chunks in voxel terrain generation 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges