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

Three.js地球模型添加随动头像的实现方法求助

实现Three.js地球表面同步旋转的头像标记

你已经完成了地球模型的基础旋转效果,要添加附着在地球表面并同步旋转的头像,可以通过将头像作为地球Mesh的子节点来实现自动同步旋转,同时通过球面坐标计算头像的表面位置。以下是修改后的完整代码及关键步骤说明:

完整代码

HTML

<canvas id="canvas"></canvas>

JavaScript

let camera;
let renderer;
let scene; // 补充声明scene变量

function main() {
    const canvas = document.querySelector('#canvas');

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.z = 2;
    scene.add(camera);

    renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);

    renderer.autoClear = false;
    renderer.setClearColor(0x000000, 1.0); // 修正背景色透明度,避免画布透明问题

    // 替换废弃的ImageUtils,使用官方推荐的TextureLoader
    const textureLoader = new THREE.TextureLoader();

    // 创建地球模型
    const earthgeometry = new THREE.SphereGeometry(0.6, 32, 32);
    const earthmaterial = new THREE.MeshPhongMaterial({
        roughness: 1,
        metalness: 0,
        map: textureLoader.load('https://zinannadeem.sirv.com/Images/earthmap1k.jpg'),
        bumpMap: textureLoader.load('https://zinannadeem.sirv.com/Images/earthbump.jpg'),
        bumpScale: 0.3,
    });
    const earthmesh = new THREE.Mesh(earthgeometry, earthmaterial);
    scene.add(earthmesh);

    // --- 添加头像标记 ---
    // 创建头像几何体(平面)
    const avatarGeometry = new THREE.PlaneGeometry(0.15, 0.15); // 可调整头像大小
    const avatarMaterial = new THREE.MeshPhongMaterial({
        map: textureLoader.load('你的头像图片路径'), // 替换为实际头像资源地址
        transparent: true, // 开启透明通道
        alphaTest: 0.1, // 过滤透明区域边缘锯齿
        side: THREE.DoubleSide // 确保头像正反两面都可见
    });
    const avatarMesh = new THREE.Mesh(avatarGeometry, avatarMaterial);

    // 经纬度转笛卡尔坐标,计算头像在地球表面的位置
    const latitude = 30; // 纬度范围:-90~90
    const longitude = 120; // 经度范围:-180~180
    const radius = 0.61; // 略大于地球半径,避免被地球表面遮挡
    const phi = (90 - latitude) * (Math.PI / 180);
    const theta = (longitude + 180) * (Math.PI / 180);

    avatarMesh.position.x = -(radius * Math.sin(phi) * Math.cos(theta));
    avatarMesh.position.y = radius * Math.cos(phi);
    avatarMesh.position.z = radius * Math.sin(phi) * Math.sin(theta);

    // 让头像始终朝向相机,也可改为lookAt(earthmesh.position)让头像向外
    avatarMesh.lookAt(camera.position);

    // 将头像添加为地球的子节点,自动同步地球旋转
    earthmesh.add(avatarMesh);
    // --- 头像添加结束 ---

    // 环境光
    const ambientlight = new THREE.AmbientLight(0xffffff, 0.1);
    scene.add(ambientlight);

    // 点光源
    const pointlight = new THREE.PointLight(0xffffff, 0.9);
    pointlight.position.set(5, 3, 5);
    scene.add(pointlight);

    const animate = () => {
        requestAnimationFrame(animate);
        earthmesh.rotation.y += 0.0015;
        render();
    }

    const render = () => {
        renderer.render(scene, camera);
    }

    animate();
}

window.onload = main;

关键实现逻辑

  • 子节点同步旋转:把头像Mesh设为地球Mesh的子节点,地球旋转时头像会自动跟随转动,无需额外编写旋转同步代码。
  • 球面坐标定位:通过经纬度计算头像在地球表面的三维坐标,保证头像贴合在地球外侧。
  • 头像材质优化:开启透明通道并设置alphaTest,解决头像背景透明显示问题;DoubleSide确保头像从任意角度都可见。
  • 朝向控制:通过lookAt方法让头像始终面向镜头或向外朝向,提升视觉效果。

注意事项

  • 替换代码中你的头像图片路径为实际可访问的头像资源地址,注意处理跨域问题。
  • 可通过调整latitude和longitude参数修改头像在地球表面的位置,调整PlaneGeometry的尺寸修改头像大小。

内容的提问来源于stack exchange,提问作者Zinan Nadeem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 10:02:29