-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
Open
Labels
Description
Description
When trying to create TextGeometry instance for some Chinese Font (such as simsun), it can't generate correct shape for certain characters such as (面、8、①、④、⑧、⑩)
I created [one demo app](https://codepen.io/mlightcad/pen/XJXoKdw) to reproduce this bug. This demo code is based on THREE.js r146. But it occurs in latest version too.
Reproduction steps
- In order to make it easier to reproduce the bug, let's reate one custom font which containing only one character '面' extracted from font 'simsun'. You can download the full font file here.
const simsunLikeFontData = {
glyphs: {
"面": {
ha: 256,
x_min: 0,
x_max: 256,
o: "m 148 47 l 106 47 l 106 3 l 148 3 l 148 47 z m 50 143 l 99 143 q 110 186 107 166 l 110 186 l 46 186 q 20 183 31 186 l 20 183 l 11 192 l 211 192 l 227 207 l 245 186 l 120 186 l 135 178 l 125 175 q 105 143 113 158 l 105 143 l 203 143 l 210 153 l 226 141 l 219 134 q 220 -16 219 44 l 220 -16 l 205 -23 l 205 -3 l 50 -3 l 50 -17 l 35 -24 q 36 66 36 11 q 35 151 36 120 l 35 151 l 50 143 z m 93 137 l 50 137 l 50 3 l 93 3 l 93 137 z m 205 137 l 161 137 l 161 3 l 205 3 l 205 137 z m 148 137 l 106 137 l 106 99 l 148 99 l 148 137 z m 148 93 l 106 93 l 106 53 l 148 53 l 148 93 z"
}
},
resolution: 1000,
boundingBox: { yMin: -200, yMax: 250 },
underlineThickness: 0,
familyName: "DemoSimSun"
};
const font = new THREE.Font(simsunLikeFontData);- Create TextGeometry based on font created above
const textGeometry = new THREE.TextGeometry("面", {
font: font,
size: 800,
height: 50,
curveSegments: 12,
bevelEnabled: false
});
textGeometry.center();
- add this TextGeometry into scene.
Code
// --- Renderer ---
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// --- Scene ---
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);
// --- Camera ---
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 100, 400);
// --- Controls ---
const controls = new THREE.OrbitControls(camera, renderer.domElement);
// --- Light ---
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);
scene.add(new THREE.AmbientLight(0x888888));
// --- Create minimal font containing only character '面' ---
const simsunLikeFontData = {
glyphs: {
"面": {
ha: 256,
x_min: 0,
x_max: 256,
o: "m 148 47 l 106 47 l 106 3 l 148 3 l 148 47 z m 50 143 l 99 143 q 110 186 107 166 l 110 186 l 46 186 q 20 183 31 186 l 20 183 l 11 192 l 211 192 l 227 207 l 245 186 l 120 186 l 135 178 l 125 175 q 105 143 113 158 l 105 143 l 203 143 l 210 153 l 226 141 l 219 134 q 220 -16 219 44 l 220 -16 l 205 -23 l 205 -3 l 50 -3 l 50 -17 l 35 -24 q 36 66 36 11 q 35 151 36 120 l 35 151 l 50 143 z m 93 137 l 50 137 l 50 3 l 93 3 l 93 137 z m 205 137 l 161 137 l 161 3 l 205 3 l 205 137 z m 148 137 l 106 137 l 106 99 l 148 99 l 148 137 z m 148 93 l 106 93 l 106 53 l 148 53 l 148 93 z"
}
},
resolution: 1000,
boundingBox: { yMin: -200, yMax: 250 },
underlineThickness: 0,
familyName: "DemoSimSun"
};
// --- Create custom Font ---
const font = new THREE.Font(simsunLikeFontData);
// --- Create TextGeometry ---
const textGeometry = new THREE.TextGeometry("面", {
font: font,
size: 800,
height: 50,
curveSegments: 12,
bevelEnabled: false
});
textGeometry.center();
const textMaterial = new THREE.MeshPhongMaterial({ color: 0x156289, side: THREE.DoubleSide });
const textMesh = new THREE.Mesh(textGeometry, textMaterial);
scene.add(textMesh);
// --- Create shape geometry and mesh ---
const shapes = font.generateShapes("面", 100);
const shapeGeometry = new THREE.ShapeGeometry(shapes);
const shapeMaterial = new THREE.MeshBasicMaterial({ color: 0x0000ff, side: THREE.DoubleSide });
const shapeMesh = new THREE.Mesh(shapeGeometry, shapeMaterial);
scene.add(shapeMesh);
// --- Draw outlines in red for debugging ---
shapes.forEach(shape => {
const points = shape.getPoints();
const geometryLine = new THREE.BufferGeometry().setFromPoints(points.map(p => new THREE.Vector3(p.x, p.y, 0)));
const line = new THREE.Line(geometryLine, new THREE.LineBasicMaterial({ color: 0xff0000 }));
scene.add(line);
});
// --- Axes helper ---
scene.add(new THREE.AxesHelper(100));
// --- Animate ---
function animate() {
requestAnimationFrame(animate);
textMesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
Live example
Screenshots
The results:
This is the current rendered result by TextGeometry for character '面'.

Expected:
The correct rendered result for character '面' should be similar to image shown in the following screenshot.

Version
r146
Device
No response
Browser
No response
OS
No response