Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 Chimera3D · Feb 02, 2014 at 02:39 PM · proceduralspheresmoothgenerated

How to Procedurally Generate Smooth Meshes

This is somewhat related to my tangent smoothing angle question which I now don't think is what the problem is, so let me elaborate a bit. Basically I am procedurally generating a hex-sphere but it doesn't look smooth when it has six times the amount of vertices as the unity primitives sphere which looks far smoother. There is a screenshot below. My sphere starts as a cube then every vertex of the cube is normalized then set a specific distance (the radius of the sphere) from the center of it, in order to "spherize" it. My question is how can I get my sphere to look smooth like the unity primitives one?

alt text

EDIT: Okay so one thing I tried was not recalculating normals when I did this and my result was smooth but the lighting was messed up - maybe I should also mention that my sphere is made out of six different planes initially arranged as a cube. The six faces of the sphere seem to be under different lighting conditions. Screenshot below.

png

comparison.png (40.5 kB)
hexspherescreen.png (42.4 kB)
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
0

Answer by nesis · Feb 02, 2014 at 03:01 PM

The normals for each vertex should be the average of the faces that vertex is a part of. Surface shading comes from the normals of a mesh (which I'm guessing you know), but what you might not know is that, for each triangle, the intensity of shadowing is interpolated from vertex to vertex.

Now you just need to figure out a way a) get the triangles a vertex is part of, b) calculate the normals of those triangles, c) get the average of those normals, and d) set the vertex's normal to that average.

Comment
Add comment · Show 10 · 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 Chimera3D · Feb 02, 2014 at 03:56 PM 0
Share

This was my interpretation of what you said, I'm pretty sure I misunderstood. The code below doesn't improve anything though.

     void CalculateNormals ($$anonymous$$esh mesh) {
         
         Vector3[] normals = mesh.normals;
         int[] trigs = mesh.triangles;
         
         for(int i = 0; i < trigs.Length; i+=3) {
             
             Vector3 avg = (normals[trigs[i]] + normals[trigs[i+1]] + normals[trigs[i+2]])/3;
             normals[trigs[i]] = avg;
             normals[trigs[i+1]] = avg;
             normals[trigs[i+2]] = avg;
             
         }
         
     }
avatar image Chimera3D · Feb 02, 2014 at 05:34 PM 0
Share

Perhaps the fact that my sphere is separated into six faces makes that solution still not work properly.

avatar image Chimera3D · Feb 02, 2014 at 08:47 PM 0
Share

Help? Please?

avatar image nesis · Feb 03, 2014 at 01:53 AM 1
Share

In pseudocode:

 //In C#, you'd add `using System.Collections.Generic` to the top of your file for List<> to work
 Vector3[] normals = mesh.normals;
 List<Vector3>[] vertexNormals = new List<Vector3>[normals.Length]; //array of lists, so each element stores a list of normals for that vertex, to be averaged later

 //create list of normals for each vertex
 for (int i=0; i<trigs.Length; i+=3) {
     Vector3 currNormal = /*calculate current triangle's normal*/;
     vertexNormals[trigs[i]].Add(currNormal);
     vertexNormals[trigs[i+1]].Add(currNormal);
     vertexNormals[trigs[i+2]].Add(currNormal);
 }

 //now we have the lists, calculate average normal for each vertex from its list of normals
 for (int i=0; i<vertexNormals.Length; i++) {
     normals[i] = Vector3.zero; //ensure the normal starts as a zero vector
     //declared as float so we can divide as float with it later, might be ok as int though?
     float numNormals = vertexNormals[i].Count;
     for (int j=0; j<numNormals; j++) {
         normals[i] += vertexNormals[i][j];
     }
     //gets the average of the normals now they're added together
     normals[i].Scale(1f/numNormals,1f/numNormals,1f/numNormals);
 }
 mesh.normals = normals;
avatar image Psyco92 nesis · Jul 05, 2017 at 11:18 AM 0
Share

Thank you! Here is pseudo converted to C# :

         Vector3[] normals = new Vector3[verts.Length];
         List<Vector3>[] vertexNormals = new List<Vector3>[verts.Length];
         for (int i = 0; i < vertexNormals.Length; i++)
         {
             vertexNormals[i] = new List<Vector3>();
         }
         for (int i = 0; i < triangles.Length; i += 3)
         {
             Vector3 currNormal = Vector3.Cross(
                 (verts[triangles[i + 1]] - verts[triangles[i]]).normalized,
                 (verts[triangles[i + 2]] - verts[triangles[i]]).normalized);
 
             vertexNormals[triangles[i]].Add(currNormal);
             vertexNormals[triangles[i + 1]].Add(currNormal);
             vertexNormals[triangles[i + 2]].Add(currNormal);
         }        
         for (int i = 0; i < vertexNormals.Length; i++)
         {
             normals[i] = Vector3.zero;
             float numNormals = vertexNormals[i].Count;
             for (int j = 0; j < numNormals; j++)
             {
                 normals[i] += vertexNormals[i][j];
             }
             normals[i] /= numNormals;
         }
         mesh.normals = normals;
avatar image JPhilipp Psyco92 · Jun 27, 2018 at 09:43 AM 0
Share

Thanks for sharing this code! I can get it to work, but it doesn't do anything visible to the mesh in my tries. Did you ever succeed?

avatar image Chimera3D · Feb 03, 2014 at 06:41 AM 0
Share

I just don't get this psuedocode at all.

Show more comments

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

24 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 avatar image avatar image avatar image

Related Questions

Normalizing several meshes towards a sphere. 1 Answer

Procedural generated mesh problem 1 Answer

SOLVED: Calculate sphere UV from position (without discontinuity) 1 Answer

Camera Follow sphere with ridgidbody? 4 Answers

Procedural Generated Levels 3D Third Person Runner 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