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 yxyx136 · Dec 01, 2014 at 11:11 PM · spherevoxelsmarching cubes

Voxel-Grid rounded Marching Cube values for a sphere

Hey Guys, I'm currently trying to create a planet using the marching cubes algorithm, but I don't really understand the density value! If I set the density value for every point in the sphere to 1, I get a blocky sphere. How can I calculate the right density values to get a round sphere?

Here's my current code to fill the voxel grid:

 public void generatePlanet() {
 
         for (int x=0; x<planetDiameter; x++) {
             for (int y=0; y<planetDiameter; y++) {
                 for (int z=0; z<planetDiameter; z++) {
                     Vector3 pos = new Vector3(x,y,z);
                     float distance = Vector3.Distance(pos, center);
                     if (distance <= planetRadius) {
                         if (distance >= planetRadius -1) {
                             map[x,y,z] = ??
                         }else {
                             map[x,y,z] = 1;
                         }
                     }else {
                         map[x,y,z] = 0;
                     }
                 }
             }
         }
 
     }

Thanks in advance!

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
3

Answer by Blackup · Jul 10, 2019 at 05:36 PM

@yxyx136 Posting for future devs to find....

[This solution assumes you are using a conventional weight based voxel grid intended for generating a mesh topology using marching cubes]

With Marching cubes, you have to set "density" on each point of the grid.

In my case that values for density range from - 1 to 1.

0 is the point where things turn from empty, to solid...

in other words... if two points are at the extremes of -1 and 1, then the vertice for the mesh will appear exactly between them.

This is why, if you only assign absolute solid and empty values, your sphere will show up as "blocky" with either straight or 45 degree angles,

So... the value of density has to alternate as a decimal value, on both the positive and negative side of the sphere radius. This will slide the vertice between the points on the grid. Calculaiting those decimal weight values might seem tricky... but fortunately, doing this for a sphere is actually relatively easy. Here is how...

For each point in the grid, check the following.

If the distance to the point is less than the sphere radius then

     Density = Mathf.Min(1.0f, (radius - distance) / girdBlockSize);

This applies a variance to the density based on the distance to the sphere surface. "(radius - distance) / girdBlockSize" means that within a threshold of one grid block size, the value will alternate between 0 and 1. If the distance is much smaller than the threshold then we assume it is a full density of 1.

That takes care of the value beneath the surface... but we must do the same with the values outside the surface.

(Remember that the vertices of your mesh will be placed on a point between the solid and empty weights on your voxel grid...) We need the vary the outer weights the same way (only this time it will be negative)

so... if the distance to your voxel grid point is BIGGER than the radius then

     Density = Mathf.Max(-1.0f, -(distance- radius) / girdBlockSize);

As you might have guessed, we are using a threshold again for one grid block size.

Any points within that threshold will vary between -1 and 0 depending on it's distance from the surface of the sphere.

With these positive and negative variances on the voxel grid points, your mesh will interpolate correctly and create a perfect sphere.

Going forward, you and add further adjustments to the weights to create noise and turbulence.

I hope this helps new Developers that stumble across this challenge in the future.

Comment
Add comment · 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

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Generating scalar field for a sphere 1 Answer

How to make a smooth voxel world 2 Answers

Voxel Terrain , Trees , Destruction - help please 0 Answers

How to remove small & thin triangles from a marching cubes voxel engine? 2 Answers

Confining Marching Cubes to the Radius of a Sphere 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