OBJLoader 和 OBJLoader2 似乎都可以正常工作。
您只需在所有材质(或所有具有顶点颜色的材质)上设置material.vertexColors = true
objLoader.load('assets/faceimage9.obj', function(object) {
scene.add(object);
object.traverse(node => {
if (node.material) {
node.material.vertexColors = true;
}
});
});
html, body {
margin: 0;
height: 100%;
}
#c {
width: 100%;
height: 100%;
display: block;
}
<canvas id="c"></canvas>
<script type="module">
// Three.js - Load .OBJ
// from https://threejsfundamentals.org/threejs/threejs-load-obj-auto-camera-xz.html
import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/build/three.module.js';
import {OrbitControls} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/controls/OrbitControls.js';
import {OBJLoader2} from 'https://threejsfundamentals.org/threejs/resources/threejs/r115/examples/jsm/loaders/OBJLoader2.js';
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
const fov = 45;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 50;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, 0.7);
const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 0, 0);
controls.update();
const scene = new THREE.Scene();
scene.background = new THREE.Color('white');
{
const skyColor = 0xB1E1FF; // light blue
const groundColor = 0xB97A20; // brownish orange
const intensity = 1;
const light = new THREE.HemisphereLight(skyColor, groundColor, intensity);
scene.add(light);
}
{
const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(5, 10, 2);
scene.add(light);
scene.add(light.target);
}
{
const objLoader = new OBJLoader2();
// note: this model is CC-BY-NC 4.0 from
// here: https://sketchfab.com/3d-models/book-vertex-chameleon-study-51b0b3bdcd844a9e951a9ede6f192da8
// by: Oleaf (https://sketchfab.com/homkahom0)
objLoader.load('https://greggman.github.io/doodles/models/book-vertex-chameleon-study/book.obj', (root) => {
scene.add(root);
root.updateMatrixWorld();
root.traverse(node => {
if (node.material) {
if (Array.isArray(node.material)) {
node.material.forEach(m => m.vertexColors = true);
} else {
node.material.vertexColors = true;
}
}
})
});
}
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
</script>
至于错误
OBJLoader2.js:6 Uncaught SyntaxError: Cannot use import statement outside a module
如果你使用的是 ES6 模块,你需要将你的脚本放在<script type="module"> 脚本标签中,并按照它们在three.js repo 中的组织方式来组织文件。即
+-somefolder
|
+-build
| |
| +-three.module.js
|
+-examples
|
+-jsm
|
+-controls
| |
| +-OrbitControls.js (if you're using this)
|
+-loaders
|
+-OBJLoader2.js
然后使用 import 语句加载所有内容
<script type="module">
import * as THREE from 'somefolder/build/three.module.js';
import {OrbitControls} from 'somefolder/examples/jsm/controls/OrbitControls.js';
import {OBJLoader2} from 'somefolder/examples/jsm/loaders/OBJLoader2.js';
...
见:this answer
如果您想使用多个脚本标签而不是 import 以旧的弃用方式执行此操作,请使用 examples/js 中的文件而不是 examples/jsm 在这种情况下,您可以将它们放在任何地方,但假设您将它们保留在然后在同一个地方
<script src="somefolder/build/three.min.js"></script>
<script src="somefolder/examples/js/controls/OrbitControls.js"></script>
<script src="somefolder/examples/js/loaders/OBJLoader2.js"></script>
注意它使用three.min.js 而不是three.module.js