Round-edged box

As I couldn’t find the solution for round-edged boxes, I took the way of least resistance - “re-invent and build the bicycle, if you don’t have one” :blush:
THREE.Shape() and THREE.ExtrudeBufferGeometry() helped me.

Criticism is very welcomed.

function createBoxWithRoundedEdges( width, height, depth, radius0, smoothness ) {
  let shape = new THREE.Shape();
  let eps = 0.00001;
  let radius = radius0 - eps;
  shape.absarc( eps, eps, eps, -Math.PI / 2, -Math.PI, true );
  shape.absarc( eps, height -  radius * 2, eps, Math.PI, Math.PI / 2, true );
  shape.absarc( width - radius * 2, height -  radius * 2, eps, Math.PI / 2, 0, true );
  shape.absarc( width - radius * 2, eps, eps, 0, -Math.PI / 2, true );
  let geometry = new THREE.ExtrudeBufferGeometry( shape, {
    amount: depth - radius0 * 2,
    bevelEnabled: true,
    bevelSegments: smoothness * 2,
    steps: 1,
    bevelSize: radius,
    bevelThickness: radius0,
    curveSegments: smoothness
  return geometry;

And a funny scene with this kind of geometries, animates with Tween.js (I hope I cycled it correctly):


Nice! There was also a PR for this type of geometry but with a different approach. Your solution is much more compact. It would be actually interesting to know if both approaches provide the same visual output.

And the corresponding npm package:


Yeah, interesting.
In the beginning, I had the same thought, like what pailhead did. Then, I imagined the scope of work on this and it made me sad. So I decided to rely on the framework, letting it to do all the job for me :slight_smile: I’ve just simply remembered, that the examples with text have the thing I want, and then it was not so difficult to suppose to use similar approach with extrusion for rectangular shape.
And this is all the cool story of creation :laughing:
Not sure, that it worth to be in the core of three.js as a type of geometry. It’s just a method of using core things to achieve such result with round-edged boxes :thinking:

Very nice! :star:

After I try to look a little deeper into three js, I am totally in the opinion of Mugen87.

Yes, not all geometries support multiple materials. The general philosophy of three.js is to keep things simple. Only some selected geometries …

A few basic geometries are sufficient.

But having a collection of more specific geometries wouldn’t be bad. Accessing my addon shows that people are interested.

The views of this article are also high:

Currently I am working on exporting BufferGeometry from THREEf.js addon. As finished three.js definition.


Where could be a suitable place to collect three.js geometries?

I think this fits into the category of discussion?


Yep, I agree with Mugen87 too.
And I like the idea about a collection of geometries :slight_smile:

wow, this is incredibly compact, nice job!

1 Like

The only thing i notice is that the innermost loop/edge kinda kinks as it goes to the fillet. I think it’s generally a problem of this type of operation, the edges between the straight section and the rounded corner think that there is an angle there, instead of being a straight line. It should be half of 180degrees, but it’s half of 170 or something like that. It becomes obvious when the segments are lower, the square in the middle of the face is smaller than it should be if all the lines were straight.

Still, this makes me think if the shape abstraction should be used nonetheless. Based on the segments we can know how many vertices there should be ahead of any computation. We could extrude and lathe an arc multiple times, mirror it, translate it, writing to the same buffer each time. Should be much more compact and just as precise as my super long solution.

1 Like

44 PM

The top square is bigger than the square in the front. The rounded corner meets at a sharp angle, but it should be 90 degrees exactly.

In 3ds max land, the push modifier could never do this right, while the shell modifier could.

1 Like

Yeah, the solution is as imperfect as simple )
When I made it, I had a thought that that stuff is just a sphere, split at 8 parts (8 pieces) - they are corners; then the corners are joined with edges made of a fourth of a cylinder (12 pieces, 4 for width, 4 for height, 4 for depth) and finally the sides of a box are made of planes (6 pieces).

I’m looking for this so long, but this method does not respect material indices. I would like to have different color and map for different sides but it’s not working, here is the code

Is there any other way to achieve this.

You can try another approach:

1 Like

Extended variant:

An overview of boxes with rounded corners can be found in the middle of the page.

WOW this method works, but raycaster.intersectObjects() is not working. I need to find object I’m clicking on, is there any workaround for it.

Looks like you bumped into this issue:

If you apply a single material, intersection works as expected:

MultiMaterial should be fully functional from R95.

See contribution @Mugen87
Modify indexed BufferGeometry (mouse or input)

1 Like

This issue is fixed in three r95 and one more issue I’m finding clicked side of object using raycaster with faceIndex property, previously faceindex value is within 0 to 7, right now the values are between 1 to 800(or something). Is there a way to calculate faceIndex or any other way to do this.

hi. thanks for this code. @prisoner849 I need it to let my sphere well defined on the edges. but when I try to add the sun texture it not fits perfect. would you help me with this issue ?
const sunTexture = textureLoader.load(“”);

Hi! Could you provide an editable live code example, that shows the problem? jsfiddle, codepen etc.

@prisoner849 Im using your fiddle example at the top of this topic. I only did some changes to add the sun texture

Just out of curiousity: why do you use this kind of geometry instead of simply THREE.SphereGeometry() or THREE.SphereBufferGeometry(), if you need a sphere? (line 67 on JS tab)