ewice
October 20, 2020, 11:17am
1
In my first project with ThreeJS I try to create a ring. I first create a cross section, which I then extrude with the following formula.
const radius = 25;
const path = new THREE.CatmullRomCurve3();
path.getPoint = (t) => {
const radians = 2 * Math.PI * t;
return new THREE.Vector3( radius * Math.cos( radians ),
radius * Math.sin( radians ),
0 );
};
const shape = new THREE.Shape();
shape.ellipse(0, 0, 5, 3, 0, 0, true, 0);
const extrudeSettings = {
steps: 100,
bevelEnabled: false,
extrudePath: path,
curveSegments: 10
};
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
Is there a way to prevent this horrible looking connection?
Mugen87
October 20, 2020, 12:39pm
2
I’ve converted your code to a live example but I’m unable to see the glitch: Edit fiddle - JSFiddle - Code Playground
It does not make sense create an instance of CatmullRomCurve3
if you are going to overwrite getPoint()
. Use the Curve
class instead.
ewice
October 20, 2020, 1:41pm
3
The glitch is only visible, when I do this (live example ):
const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
geometry.center();
geometry.computeVertexNormals();
for (const face of geometry.faces) {
if (face.materialIndex === 1) {
for (const vertex of face.vertexNormals) {
vertex.z = 0;
vertex.normalize();
}
}
}
const buffer = new THREE.BufferGeometry().fromGeometry(geometry);
That happens because of this line. When computing normals like that, you produce a seam where the (unconnected) start and end vertices meet.
In general, recomputing normals via computeVertexNormals()
is not supported by all geometry generators.
1 Like
ewice
October 20, 2020, 2:28pm
5
First of all, many thanks for the explanation. As I am still quite new to the subject, I do not know how to proceed at the moment. How would you connect the ends? Or would a different geometry be more useful?
Could you produce your geometry in a DCC tool like Blender instead and then import it via GLTFLoader
?
ewice
October 20, 2020, 2:44pm
7
In the future, I would like to visualize parameter adjustments directly on the object in the browser, which is why constructing the object in a DCC tool would probably be to inflexible. Or is that wrong?
If you need to generate geometries on-the-fly then importing 3D assets is indeed the wrong approach.
hofk
October 20, 2020, 4:01pm
9
You might find some suggestions in my addons. There shapes are also dynamically changed. I used self defined Geometry, indexed BufferGeometry and non-indexed BufferGeometry.
See
For the first time, I came across three.js in January 2016. Since September I have been working on this issue.
In three.js core elementary geometries are defined.
When designing my “Bumblebee Mara” I needed other shapes and produced them by deformation of sphere and cylinder. http://codepen.io/hofk/pen/eWdZMb
Additionally inspired by https://threejs.org/examples/js/ParametricGeometries.js ( @author zz85 <<< old link, no longer available, see revision 100)
I have programmed a three.js addo…
updated NOTE:
Modular bundling of multiple geometry definitions has some advantages, but also disadvantages if the overview and maintainability suffers.
Therefore I created newer geometry creations in extra files and collect them on Github at GitHub - hofk/threejsResources: Resources for three.js There are also extra posts about it here in the forum.
The THREEg addon is used to create special / extended geometries.
[20180208-2112-21658]
The addon generates non indexed BufferGeometries. Th…
Try it out
https://hofk.de/main/threejs/sandbox/
ewice
October 21, 2020, 11:40am
10
Do you have another idea how I could solve the problem?
Mugen87
October 21, 2020, 11:54am
11
I have to correct my previous post. The problem is that you convert to Geometry
and back to BufferGeometry
. The usage of computeVertexNormals()
is actually fine as long as you don’t do it with Geometry
. Try to make your geometry modifications without using Geometry
.
ewice
October 21, 2020, 12:24pm
12
Ok, but if I only use the BufferGeometry in combination with computeVertexNormals(), I get this result (live example ):
Not a glitch, but completely normal and expected. Imagine forming a cylinder from a piece of paper. Where the edges meet, a seam is formed.
The light distortion you see is caused by vertices occupying the same space, but having different normals.
Since the geometry is mono-grouped and has no hard edges , the solution is to make sure these vertices also share the same normal values.
ewice
October 22, 2020, 5:47am
14
So should I push the first values from the extrusion into the array again?
Image
Solution: ewice.txt (3.1 KB)
ewice
October 23, 2020, 7:02am
16
Thank you very much for your effort. The only problem I have now is this black border.
GlifTek
October 24, 2020, 1:18am
17
This is very interesting to me…
Is there any reason you’re not using LatheGeometry for this?
(I’m learning from this code, so may be a naive question)
The border is caused by modifying the vertex normals.
To counter it, any of the following might work.
Add emissive att to Pong Mat.
Revert back to your own light set up [upper left img]
Soften the effect by assigning vertex.z to Math.sign(vertex.z)*0.005; [upper right img]
Do not modify vertex normals [ lower middle img