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

如何在Next.js 14+Three.js的3D地球模型上固定显示大洲名称

解决Next.js 14中Three.js地球模型固定大洲名称的问题

要实现大洲名称随地球旋转保持固定位置,核心是将文本作为地球Mesh的子元素,继承地球的旋转属性,同时通过坐标计算将文本定位到对应大洲区域。以下是具体实现方案:

步骤1:修改Earth.jsx组件

在地球组件中引入Text组件和THREE,添加大洲数据并将文本作为地球Mesh的子元素:

"use client"

import React, { useRef } from "react";
import { useGLTF, Text } from "@react-three/drei";
import { useFrame } from "@react-three/fiber";
import * as THREE from "three";

// 大洲名称及大致经纬度(可根据实际需求调整)
const continents = [
  { name: "亚洲", lat: 30, lon: 100 },
  { name: "欧洲", lat: 50, lon: 10 },
  { name: "非洲", lat: 0, lon: 20 },
  { name: "北美洲", lat: 40, lon: -100 },
  { name: "南美洲", lat: -20, lon: -60 },
  { name: "大洋洲", lat: -25, lon: 135 },
  { name: "南极洲", lat: -90, lon: 0 },
];

// 将经纬度转换为三维坐标(半径设为比地球大0.1,避免文本被模型遮挡)
const latLonToVector3 = (lat, lon, radius = 3.1) => {
  const phi = (90 - lat) * (Math.PI / 180);
  const theta = (lon + 180) * (Math.PI / 180);
  const x = -(radius * Math.sin(phi) * Math.cos(theta));
  const y = radius * Math.cos(phi);
  const z = radius * Math.sin(phi) * Math.sin(theta);
  return new THREE.Vector3(x, y, z);
};

export default function Earth(props) {
  const { nodes, materials } = useGLTF("/globe/earth.gltf");
  const earthRef = useRef();

  useFrame(() => {
    if (earthRef.current) {
      earthRef.current.rotation.y -= 0.002;
    }
  });

  return (
    <group {...props} dispose={null}>
      <mesh
        ref={earthRef}
        geometry={nodes.Object_4.geometry}
        material={materials["Scene_-_Root"]}
        scale={3}
      >
        {/* 渲染大洲名称文本 */}
        {continents.map((continent, idx) => {
          const position = latLonToVector3(continent.lat, continent.lon);
          return (
            <Text
              key={idx}
              position={position}
              fontSize={0.2}
              color="#ffffff"
              anchorX="center"
              anchorY="middle"
              rotation-y={Math.PI} // 调整文本朝向,确保正面面向相机
              outlineWidth={0.02}
              outlineColor="#000000"
            >
              {continent.name}
            </Text>
          );
        })}
      </mesh>
    </group>
  );
}

useGLTF.preload("/globe/earth.gltf");

关键说明

  • 子元素继承旋转:将Text组件放在地球Mesh内部,地球旋转时文本会自动跟随旋转,保持与大洲的相对位置不变。
  • 经纬度转三维坐标:通过公式将地理经纬度转换为Three.js的三维坐标,半径设为比地球模型稍大,避免文本被地球表面遮挡。
  • 文本样式优化:添加描边、调整字体大小和朝向,确保文本在旋转过程中始终清晰可见。

可选优化:使用GLTF内置大洲节点定位

如果你的GLTF模型中已经包含各个大洲的独立Mesh节点(例如nodes.Asia),可以直接使用节点的位置来定位文本,精度更高:

// 替换上述的Text渲染部分
{[
  { name: "亚洲", node: nodes.Asia },
  { name: "欧洲", node: nodes.Europe },
  // 其他大洲...
].map((item, idx) => (
  <Text
    key={idx}
    position={item.node.position}
    scale={0.15}
    color="#ffffff"
    anchorX="center"
    anchorY="middle"
  >
    {item.name}
  </Text>
))}

内容的提问来源于stack exchange,提问作者Pavitar Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:44:57