Three.js:使用图像作为表面纹理绘制地球时出现缩放问题

Three.js: Scaling issue when drawing earth with an image as surface texture

我试图用一堆卫星和地球上的用户以及从卫星指向用户的线来绘制地球,但我完全失败了。

缩放问题:

当我缩小一点时:

import React, { useRef } from "react";
import { useLoader, useFrame } from "@react-three/fiber";
import { TextureLoader } from "three";
import { OrbitControls, Stars } from "@react-three/drei";
import * as THREE from "three";
import data from "../data.json";

import EarthDayMap from "../assets/img/earth_texture_map_1000px.jpg";

const COLORS = {
  0: 'white',
  1: 'lightgrey',
  2: 'orange',
  3: 'pink'
};

const EARTH_RADIUS = 4000;

export function Earth(props) {
  const [colorMap, normalMap, specularMap, cloudsMap] = useLoader(
    TextureLoader,
    [EarthDayMap]
  );

  const earthRef = useRef();
  const cloudsRef = useRef();
  const satellitesRef = useRef([]);
  const usersRef = useRef([]);

  useFrame(({ clock }) => {
    const elapsedTime = clock.getElapsedTime();

    earthRef.current.rotation.y = elapsedTime / 24;
    cloudsRef.current.rotation.y = elapsedTime / 24;
  });

  return (
    <>
      <ambientLight intensity={1} />
      <pointLight color="#f6f3ea" position={[5000, 0, 5]} intensity={1.2} />
      <Stars
        radius={30000}
        count={20000}
        factor={7}
        saturation={0}
        fade={true}
      />
      <mesh ref={cloudsRef} position={[0, 0, 0]}>
        <sphereGeometry args={[0, 32, 32]} />
        <meshPhongMaterial
          map={cloudsMap}
          opacity={0.1}
          transparent={true}
          side={THREE.DoubleSide}
        />
      </mesh>
      <group>
        {data.satellites.map(({ coordinate: { x, y, z }, id }, i) => <mesh
          key={id}
          ref={el => satellitesRef.current[i] = el}
          position={[x, y, z]}>
          <sphereGeometry args={[100, 32, 32]} />
          <meshPhongMaterial
            color='red'
            side={THREE.DoubleSide}
          />
        </mesh>)}
      </group>
      <group>
        {data.satellites.map(({ coordinate: { x, y, z }, id }, i) => <mesh
          key={id}
          ref={el => usersRef.current[i] = el}
          position={[x, y, z]}>
          <sphereGeometry args={[100, 32, 32]} />
          <meshPhongMaterial
            color='green'
            side={THREE.DoubleSide}
          />
        </mesh>)}
      </group>
      <group>
        {data.mappings.map(({ satellite: satelliteId, user: userId, color }, id) => {

          const satellite = data.satellites.find(s => s.id === satelliteId);
          const user = data.users.find(u => u.id === userId);

          return <line key={id}
            points={[
              [satellite.coordinate.x, satellite.coordinate.y, satellite.coordinate.z],
              [user.coordinate.x, user.coordinate.y, user.coordinate.z]
            ]}
            color={COLORS[color]}
          />
        })}
      </group>
      <mesh ref={earthRef} position={[0, 0, 0]}>
        <sphereGeometry args={[EARTH_RADIUS, 256, 256]} />
        <meshPhongMaterial specularMap={specularMap} />
        <meshStandardMaterial
          map={colorMap}
          normalMap={normalMap}
          metalness={0.4}
          roughness={0.7}
        />
        <OrbitControls
          enableZoom={true}
          enablePan={true}
          enableRotate={true}
          zoomSpeed={0.6}
          panSpeed={0.5}
          rotateSpeed={0.4}
        />
      </mesh>
    </>
  );
}

Repository

您的地球半径似乎是 4000 个单位。默认情况下,透视相机的近距和远距范围为 0.1 到 2000,因此大部分球体可能位于相机的截锥体之外。您必须调整这些值。对于初学者,我会尝试 camera.near = 100 到 10000。

https://threejs.org/docs/?q=camer#api/en/cameras/PerspectiveCamera.far