You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么我在Three.js中无法将纹理正常映射到3D物体上?

问题原因

  • 你加载的WaltHeadLo_buffergeometry.json头部模型未预配置UV映射属性:UV坐标是实现纹理与3D模型顶点一一对应的必要参数,缺失时ThreeJS会默认所有顶点使用同一UV取值,最终仅呈现纹理平均色。
  • MeshStandardMaterial的color参数设置为灰色0xcccccc,会与纹理色彩叠加导致纹理整体偏暗,无法正常显示原图效果。

修复方案

在模型加载的成功回调中,先为无UV属性的模型手动生成UV坐标,再将材质基础色改为纯白色即可。你也可以根据需求调整纹理的重复参数,适配模型显示效果。

修复后完整JS代码

import * as THREE from 'https://threejs.org/build/three.module.js';
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(45, 4 / 3, .1, 500)
camera.position.set(240, 240, 240);
camera.lookAt(scene.position);

var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdddddd);
renderer.setSize(800, 600);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;

var tl = new THREE.TextureLoader();
var texture = tl.load('https://threejs.org/examples/models/json/lightmap/rocks.jpg');
// 可选:配置纹理重复模式
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(2, 2); // 可自行调整重复次数

const loader = new THREE.BufferGeometryLoader();
loader.load(
  'https://threejs.org/examples/models/json/WaltHeadLo_buffergeometry.json',
  function (geometry) {
    // 新增:手动生成UV坐标
    if (!geometry.hasAttribute('uv')) {
      geometry.computeBoundingBox();
      const box = geometry.boundingBox;
      const size = new THREE.Vector3();
      box.getSize(size);
      const position = geometry.attributes.position;
      const uvs = new Float32Array(position.count * 2);
      for (let i = 0; i < position.count; i++) {
        // 基于模型X、Y轴归一化生成UV,可根据需求更换映射轴
        const x = (position.getX(i) - box.min.x) / size.x;
        const y = (position.getY(i) - box.min.y) / size.y;
        uvs[i * 2] = x;
        uvs[i * 2 + 1] = y;
      }
      geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));
    }
    // 修改:color改为纯白色避免覆盖纹理色彩
    var material = new THREE.MeshStandardMaterial({ color: 0xffffff, map: texture });
    var object = new THREE.Mesh(geometry, material);
    object.name = "head";
    scene.add(object);
  },
  function (xhr) {
    console.log('loaded');
  },
  function (err) {
    console.log('An error happened');
  }
);

var spotLight1 = new THREE.SpotLight(0xffffff);
spotLight1.name =  "SpotLight1";
spotLight1.position.set(150, 300, 500);
spotLight1.castShadow = true;
scene.add(spotLight1);

var canvas = document.getElementById("canvas");
canvas.appendChild(renderer.domElement);
renderer.render(scene, camera);

const controls = new OrbitControls(camera, renderer.domElement);

animate();
function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
}

HTML代码无需修改

<html>
<body>
    <div id="canvas" width="800px" height="600px"></div>
</body>
</html>

内容的提问来源于stack exchange,提问作者Mehmet Emre Özer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 04:36:03