A 3D artist would probably create something like this by cutting the mesh and applying Catmull-Clark subdivision (assuming they didn't have a proper bevel tool). If you have a library of generic mesh manipulation functions lying around, the programmatic way and the artists' way would likely be the same. Creating those generic functions is a lot of work but it pays off fairly quickly. You need generic functions eventually anyway, to create more complex shapes.
It's also worth noting that the optimized mesh has some unfortunate drawbacks. Mesh properties are generally only stored on the vertex, and are interpolated across the attached faces. Having long, thin triangles or big differences in triangle area will often create problems when vertex properties are interpolated across the face. So, you may need to break those big faces into multiple triangles anyway.
That can definitely be a problem in general, but is it likely to crop up in this case?
Those long triangles are flat so the normal is constant. Neither 2D nor 3D texture coordinates will have too much distortion.
And if it was a problem, you could fix it by scaling back the optimization, no?
If you have a library of generic mesh manipulation functions lying around, the programmatic way and the artists' way would likely be the same. Creating those generic functions is a lot of work but it pays off fairly quickly.
Yes, you’re right about that. I think this is still interesting and useful from the perspective of understanding how to build a basic mesh programmatically. And sometimes it’s easier to crank something out in a brute-force way like this than to figure out how to combine your general-purpose tools in just the right way.
Only issue I can think of is slight loss of precision along big surfaces, as partial derivatives will have bigger deltas. It's only a problem if your fragment shader maths is numerically sensitive to such things.
I think it’s worth mentioning the ray marching (signed distance field) method for creating rounded boxes, because of how surprisingly simple it is - a single subtraction added to the sharp-cornered box does the trick. Even more fun, and relevant to the Apple story, it works exactly the same in 2d, and it can be used to anti-alias your 2d rounded boxes beautifully! (Useful if you want to render dynamic-radius rounded corners in real-time.)
If you can identify lots of locations of points on the isosurface, it could probably be fairly easily triangulated in this case too since a rounded cube is a fairly simple and convex shape.. but the result will also be inherently noisy I think.
Guess it's all about the use case eh?
"Posers" use G1 continuity, Apple uses G2 at a minimum if not G3. More complex math but smoother corners and surfaces. There's actually no 'radii' on Apple products.
A good 99 Percent Invisible podcast on this:
They look much better than rounded rectangles, and probably work with less and more equally spaced polygons in 3d. You can probably calculate the points as slices in azimuth, or as a continuous helical spiral.
They give larger curvature smoothness than rounded rectangles, and superformula gives a wide variety of shapes and smooth transition between a circle and a square with changing parameters.
Superformula is a generalisation of superellipse, and works in 2D and 3D. Superellipsoid is the 3D counterpart:
* [Superformula - Wikipedia] (https://en.wikipedia.org/wiki/Superformula)
* [Superellipse - Wikipedia](https://en.wikipedia.org/wiki/Superellipse)
* [Superellipsoid - Wikipedia](https://en.wikipedia.org/wiki/Superellipsoid)
Squircle is a special case of superellipse with parameters a and b equal and n set to 4:
* [Squircle - Wikipedia](https://en.wikipedia.org/wiki/Squircle)
Danish Piet Hein invented the Superegg:
* [Superegg - Wikipedia](https://en.wikipedia.org/wiki/Superegg)
If anything I'd argue that for professional appliances the circular corners convey a less organic, more industrial look that feels, to me, more suitable.
But then again, I enjoy brutalist architecture, so you can probably safely discard my opinion.
In the Medium article, the comparison between the Apple and non-Apple would be less striking if the non-Apple version had a larger radius.
One way to think about it is in terms of the derivative of the path (which is what “Gn” means). A straight edge has a constant straight derivative, parallel to the path. A circle has a constant derivative perpendicular to the path. When you connect the two, there is a discontinuity in the derivative, the rate of change of the path jerks suddenly from circle to straight edge. And you can see it visually, even though it’s pretty subtle. With a smoother curve, the derivative is also smooth, and then there’s no abruptness in the curvature where the two edges meet.
Start with a mesh with 24 vertices which results in the cube with all vertices and all edges cut with planes. Each vertex of the original cube becomes a triangle.
Then iteratively split edges in half, projecting the split points onto the desired surface. The algorithm only needs to split edges near the vertices of the original cube, so the split+project step is like this:
float3 midpoint = ( v1 + v2 ) * 0.5;
float3 rv = (midpoint - sphereCenter).normalize();
midpoint = sphereCenter + rv * sphereRadius;
That's how people are usually generating good quality spherical meshes: start with icosahedron, then a few iterations of splitting edges in half + reprojecting back to the sphere.
To me it produces more pleasant resulting mesh, which gets important with fewer subdivisions. Here's what it looks like: https://i.imgur.com/o3RFfZx.mp4
But the criticisms from slavik81 still applies, it produces long triangles with insufficient surface information for the flat parts.
(Still a useful link, though, as it’s a great writeup from a slightly different perspective)
Edit to add: doh, you’re right! I was too quick on the draw. Cube versus octahedron.
It would have been *so cool* to have had a course that could focus on just the neat graphics algorithms like this by having WebGL sandboxes for both the lecture notes and maybe even the homeworks!
Procedural generation normally is a randomized process that does not try to get an optimal solution. Instead, it typically aims to be a generator for a large diverse population of "interesting" outcomes, where "interesting" is often a subjective metric, but does not really have to be.
Where I work there's lots of use of SideFX Houdini, and we regularly talk about how "procedural" any given setup is, where "more procedural" means either that it has a 'seed' that can be randomised, to generate an infinite number of varieties, or (more importantly) the setup is more capable of working with new versions of input assets (a new version of animation or a different 3d model, say), whilst still robustly producing a correct-enough result.
It sounds like gp might mean this sense, but you've got something more formal in mind?
Even something like Mandelbrot or Julia sets (or similar fractals) are fully deterministic algorithms, but the choice of the position and scale (quite a small initial input) is sufficient to generate a large variety of interesting results => procedural generation.
The procedure must be making some kind of sequence of choices that leads to a set of diverging final outcomes. The choices can be prescribed by some kind of input value, or determined by a PRNG of the generation procedure itself (also actually a deterministic sequence).
However, not everything made by a computed program should be called "procedurally generated". Word docs are not a result of procedural generation. Arithmetic operators and sorting algorithms are not procedural generation techniques by themselves (although they can be used in procedural generation as building blocks).
Where we mainly might not agree yet is about setups that instead process input-assets, and the idea is not for them to explore the parameter-space, but just to re-execute the effect as close to as it was intended as possible, and how reliably they do this can be called how 'procedural' they are. It is not usually expected to involve huge amounts of extra exploration to find something that works for a new input, as long as the effect is set up to be 'procedural' enough. This is a VFX-based perspective and I'd expect a games-perspective on this stuff to be quite different!
Cool website. 3D is so cool, I struggled with it using 3js but it's neat. The basic cube rotation tutorial/camera rendering pane... I hope to get into this stuff again.