直接看效果 Konnect: For every human
上react组件
EarthComponent
import { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import s from "./index.module.scss"
import earth4 from "@/assets/earth/earth4.jpg";
import earthBump from "@/assets/earth/earth_bump.jpg";
import earthSpec from "@/assets/earth/earth_spec.jpg";
import earthCloud from "@/assets/earth/earth_cloud.png";
export default function EarthComponent(props) {
// 当前容器引用
const curContainerRef = useRef(null);
let scene, camera, renderer, controls;
let WIDTH, HEIGHT, sphere, mesh_cloud;
let requestAnimationFrameNum;
// 初始化渲染
function initRender() {
WIDTH = props.width ?? window.innerWidth;
HEIGHT = props.height ?? window.innerHeight;
renderer = new THREE.WebGLRenderer({
antialias: true,
})
renderer.setSize(WIDTH, HEIGHT);
renderer.setPixelRatio(WIDTH / HEIGHT);
renderer.physicallyCorrectLights = true;
curContainerRef.current!.appendChild(renderer.domElement);
}
// 设置场景
function initScene() {
scene = new THREE.Scene();
// 设置背景
scene.background = new THREE.Color(0xff010811);
}
// 初始化相机
function initCamera() {
camera = new THREE.PerspectiveCamera(
50,
WIDTH / HEIGHT,
1,
10000,
)
camera.position.set(0, 0, 300);
camera.minZoom = 1; // 设置最小缩放级别
camera.maxZoom = 10; // 设置最大缩放级别
controls = new OrbitControls(camera, renderer.domElement);
// controls.enableDamping = true;
// controls.dampingFactor = 1;
// 禁止缩放
controls.enableZoom = false;
}
// 初始化 环境光源
function initLight() {
//环境光
// #4d4d4d
const light = new THREE.AmbientLight(0x4d4d4d);
scene.add(light);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(100, 1000, 1000);
scene.add(directionalLight);
// #080820
const light2 = new THREE.HemisphereLight(0xffffff, 0x080820, 0.5);
scene.add(light2);
//聚光灯
const spotLight = new THREE.PointLight();
spotLight.position.set(0, 0, 0);
// spotLight.position.set(300, 100, 400);
spotLight.angle = 45 * (Math.PI / 180);
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 500;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 30;
scene.add(spotLight);
}
function initObject() {
const tmap = new THREE.TextureLoader().load(earth4);
const tbumpMap = new THREE.TextureLoader().load(earthBump);
const tlarmap = new THREE.TextureLoader().load(earthSpec);
const tcloud = new THREE.TextureLoader().load(earthCloud);
let geometry = new THREE.SphereGeometry(90, 32, 32);
let material = new THREE.MeshPhongMaterial();
sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
material.map = tmap;
/*凹凸贴图用于为材质增加厚度。我们用到的凹凸贴图是一张灰度图,当然你也可以使用彩色图。像素的密集程度定义的是凹凸的高度,
但是凹凸图只包含像素的相对高度,没有任何倾斜的方向信息。所以使用凹凸贴图所能表达的深度信息有限。*/
material.bumpMap = tbumpMap;
material.bumpScale = 10;
/*我们可以通过设置高光贴图来实现部分区域反光。通过设置高光贴图,我们会发现,只有海洋部分会有发光,而陆地部分没有高光的效果。
与 specular 配合使用*/
material.specularMap = tlarmap;
//添加高光颜色
// #8cc2ff
material.specular = new THREE.Color(0x8cc2ff);
//specular高亮的程度,越高的值越闪亮。默认值为 30
material.shininess = 3;
//云层
geometry = new THREE.SphereGeometry(92, 32, 32);
//transparent png透明
material = new THREE.MeshPhongMaterial({ map: tcloud, transparent: true });
mesh_cloud = new THREE.Mesh(geometry, material);
scene.add(mesh_cloud);
}
function init() {
initRender();
initScene();
initCamera();
initLight();
initObject();
animation();
}
function out() {
try {
cancelAnimationFrame(requestAnimationFrameNum);
if (curContainerRef.current) {
curContainerRef.current.innerHTML = "";
}
renderer = null;
} catch (error) {
console.log(error);
}
}
function animation() {
requestAnimationFrameNum = requestAnimationFrame(animation);
renderer.render(scene, camera);
sphere.rotation.y += 0.003;
mesh_cloud.rotation.y += 0.003
controls.update();
}
useEffect(() => {
init()
return () => {
out();
}
}, []);
return (
)
}
样式文件 index.module.scss
.container {
position: relative;
}
使用组件
import EarthComponent from "../EarthComponent";
图片资源
压缩包