Skip to content

ExtrudeGeometry: extrudePath.closed is ignored when generating Frenet frames #32359

@VISHNU7KASIREDDY

Description

@VISHNU7KASIREDDY

Description

ExtrudeGeometry currently calls computeFrenetFrames(segments, false) with a hardcoded closed = false, even when the provided extrudePath has .closed === true.

When a closed spline is used as the extrudePath, the generated Frenet frames are computed as if the path were open. This produces a visible twist or discontinuity at the seam of the extruded geometry.

There is a TODO in the source about this behavior. The fix is to pass the curve's closed flag through to computeFrenetFrames so closed curves get closed Frenet frames.

Suggested minimal change:

Replace:
const frames = extrudePath.computeFrenetFrames( segments, false );

With:
const frames = extrudePath.computeFrenetFrames( segments, !!extrudePath.closed );

Reproduction steps

  1. Create a closed CatmullRomCurve3 (or other closed curve) and set curve.closed = true.
  2. Create a simple 2D Shape to extrude (e.g. a rectangle or small path).
  3. Create an ExtrudeGeometry with the closed curve as extrudePath and a reasonably high steps (e.g. 100).
  4. Render the geometry and inspect the seam where the path closes — you will see a twist or discontinuity in the surface normals/UVs that disappears when the Frenet frames are computed in closed mode.

Code

// Minimal reproducible example
const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.lineTo(1, 0);
shape.lineTo(1, 1);
shape.lineTo(0, 1);
shape.closePath();

const points = [
new THREE.Vector3(1, 0, 0),
new THREE.Vector3(0, 1, 0),
new THREE.Vector3(-1, 0, 0),
new THREE.Vector3(0, -1, 0)
];

const curve = new THREE.CatmullRomCurve3(points);
curve.closed = true; // important: mark curve closed

const extrudeSettings = {
steps: 100,
bevelEnabled: false,
extrudePath: curve
};

const geom = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const mat = new THREE.MeshStandardMaterial({ color: 0x88ccff, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geom, mat);
scene.add(mesh);

Live example

(If possible, please add a live fiddle or codepen demonstrating the issue. Example template links from the project are below — you can fork one and paste your reproduction)

  • [jsfiddle-latest-release WebGLRenderer] (use the project's template)
  • [jsfiddle-dev WebGLRenderer] (use the project's template)
  • [jsfiddle-latest-release WebGPURenderer] (optional)
  • [jsfiddle-dev WebGPURenderer] (optional)

If you want, I can prepare a ready-to-paste jsfiddle snippet from the code above.

Screenshots

No response

Version

Observed on: r152 and main branch (tested locally as of 2025-11-25). (Please update this if you can reproduce on a different release. The bug is present in current main in my tests.)

Device

No response

Browser

No response

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions