Procedural planet slicing triangles problem

Hi guys,

I have been working on a little planet generator by generating a icosahedron and applying some 3d perlin noise to it to generate mountains on it.

Now I wanted to slice the planets vertices at a certain distance from the planets origin. This means I can add a loopcut at a certain mountain height. I used http://www.xbdev.net/java/tutorials_3d/clipping/index.php as a reference for triangle cutting.

It works. But there are a few problems as some cutted triangles have a reversed vertex order which results in some triangles not showing up unless I view them from within the planet.

I also havent figured out how to share vertexes to get smooth normals but thats the next step :slight_smile:

Could someone have a look why some triangles are flipped?

Cheers

3004926–224072–planetgenerator.unitypackage (1.11 MB)

I just started randomly flipping triangle winding orders and solved it…

Not sure if you had typos or if there is some other issue, but I enclose a screenshot of my source control diff of what changed from your posted script to the functioning one so you can hand-apply and sorta see if it makes sense.

(Highly recommend you use source control if you are not using it already!)

1 Like

Thank you so much for looking at it! I tried your fix and it does indeed closes the mesh :smile:

Unfortunately the cut got messed up with it and it needed a little more tweaking, but thanks to you I know where to look now!

Correct code:

            } else if(iCount == 1) {
                 if( p0in ){ pA=p0; pB=p2; pC=p1;};
                 if( p1in ){ pA=p1; pB=p0; pC=p2;};
                 if( p2in ){ pA=p2; pB=p1; pC=p0;};


                 int a = getSplitPoint(vertList[pA], vertList[pB]);
                int b = getSplitPoint(vertList[pA], vertList[pC]);

                faces3.Add(new TriangleIndices(pA, b, a));
                faces3.Add(new TriangleIndices(pB, b, pC));
                faces3.Add(new TriangleIndices(pB, a, b));

                Debug.DrawLine(vertList[a], vertList[b], Color.red);
            } else if(iCount == 2) {

                 if( !p0in ){ pA=p1; pB=p2; pC=p0; };
                if( !p1in ){ pA=p2; pB=p0; pC=p1; };
                if( !p2in ){ pA=p0; pB=p1; pC=p2; };


                int a = getSplitPoint(vertList[pB], vertList[pC]);
                int b = getSplitPoint(vertList[pA], vertList[pC]);

             
                faces3.Add(new TriangleIndices(pC, b, a));
                faces3.Add(new TriangleIndices(pB, a, pA));
                faces3.Add(new TriangleIndices(pA, a, b));

                Debug.DrawLine(vertList[a], vertList[b], Color.yellow);
            }

Now it’s time to let the new triangles share vertexes for smooth normals. Gonna be a hard one :frowning:

Cheers @Kurt-Dekker

1 Like

It’s harder than I thought it would be but I can’t get the vertex sharing properly :frowning:

I looked at the code where the sphere got subdivided and how the subdivided triangle vertex got their number assigned and it looks to me it should work for the sliced triangles aswell which is the following:

bool firstIsSmaller = p1 < p2;
        long smallerIndex = firstIsSmaller ? p1 : p2;
        long greaterIndex = firstIsSmaller ? p2 : p1;
        long key = (smallerIndex << 32) + greaterIndex;
        int ret;
        if (middlePointIndexCache.TryGetValue(key, out ret))
        {
            return ret;
        }

Although the normal shading does look better, there are still some vertex sharing problems:

I have attached the updated script. Hope someone could take a look.

3005911–224178–IcoSphere.cs (9.84 KB)

Haven’t looked at your code yet but did you consider that a vertex could be shared by more than two three or even four faces?? You want to tally up ALL the faces that it is shared by, then take that normal as the new shared normal.

ALSO… just be sure you honestly don’t just have two vertices that are vanishingly close to each other, because then you will actually not be able to smooth properly, unless you actually weight the normal averages according to size of each triangle, which would really get tricky, considering triangles can be long and slender, and you care about the direction of the normal sampling.

Not fully sure if I understand you right but I don’t think there are multiple vertices very close to each other. Probably an order thingy again. Maybe it’s out of my league, it frustrates me I suck at math :stuck_out_tongue: Im still trying :slight_smile:

It’s not an easy thing to solve. It requires multiple “depths” of smoothing, not just averaging nearby face normals.

See attached image: the bottom line is the “side view” of the dotted traverse line across your planet, a line that passes two edges. As those edges get closer together, naive averaging of normals is going to produce a sharp normal discontinuity across a very narrow triangle slice (the middle triangle), such as when the line of traverse taken lower and lower on the top three faces. Does that make sense?? In any case, that’s just one possible answer as to why you might still be seeing a discontinuity in normal.

Hmm, it’s hard to understand. I thought that shared vertexes have automatic smoothing as it is an avarage of all neighbours.

I updated the code with a new way to calculate the intersection points which makes the slices a lot smoother.
Unfortunately the shared vertex problem persists.

Edit: I exported the mesh and imported it into Blender > Recalculate normals… Stays the same :open_mouth:

(GIF won’t display for some reason. Here is the link: Imgur: The magic of the Internet)

3006408–224213–IcoSphere.cs (11.7 KB)