react threejs 创建3D地球(入门)

本文详细介绍了如何使用Three.js在React项目中构建一个具有赛博朋克风格的3D数字地球,涉及canvas画布、WebGL渲染器、相机设置、镜头轨道控制器和纹理贴图等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.先创建一个canvas画布

 <div className="earth_digital">
        <canvas className="webgl"></canvas>
 </div>

2.在useEffect里面获取webgl元素,并创建渲染器对象

const canvas = document.querySelector('.webgl');
    // 创建渲染器对象
    const renderer = new THREE.WebGLRenderer({
      canvas: canvas as HTMLCanvasElement,
      antialias: true,
      alpha: false,
    });

renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));//设置设备像素比

3.创建相机、场景、添加镜头轨道控制器

        1.创建相机分两种,一种是正投影相机(OrthographicCamera)和透视投影相机(perspectiveCamera)。 透视投影照相机对应投影到的物体的大小是随着距离逐渐变小的,而正投影照相机投影到的物体大小是不受距离影响的,简单来说就是透视投影相机就像我们的眼睛,是近大远小的,正投影相机近远距离的物体都是一样大。

        2.perspectiveCamera会有四个参数,fov、aspect、near、far。fov表示摄像机视锥体垂直视野角度,最小值为0,最大值为180,默认值为50,实际项目中一般都定义45,因为45最接近人正常睁眼角度;aspect表示摄像机视锥体长宽比,默认长宽比为1,即表示看到的是正方形,实际项目中使用的是屏幕的宽高比;near表示摄像机视锥体近端面,这个值默认为0.1,实际项目中都会设置为1;far表示摄像机视锥体远端面,默认为2000,这个值可以是无限的,说的简单点就是我们视觉所能看到的最远距离。

        3.透视投影相机的位置和position,up,lookAt有关系。position用来指定相机在三维坐标中的位置,up用来指定相机拍摄时相机头顶的方向,lookAt表示相机拍摄时指向的中心点

    // 创建场景
    const scene = new THREE.Scene();
    // 创建相机
    const camera = new THREE.PerspectiveCamera(
      45,
      window.innerWidth / window.innerHeight,
      0.01,
      50,
    );
    camera.position.set(0, 0, 15.5);
    // 添加镜头轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.enablePan = false;
    // 页面缩放监听并重新更新场景和相机
    window.addEventListener(
      'resize',
      () => {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        // renderer.setSize(window.innerWidth, window.innerHeight);
      },
      false,
    );
    // 页面重绘动画
    renderer.setAnimationLoop((_) => {
      const earth = new THREE.Mesh();
      // TWEEN.update();
      earth.rotation.y += 0.001;
      renderer.render(scene, camera);
    });
    let params = {
      colors: { base: '#f9f002', gradInner: '#8ae66e', gradOuter: '#03c03c' },
      reset: () => {
        controls.reset();
      },
    };
    let uniforms = {
      impacts: { value: 1 },
      // 陆地色块大小
      maxSize: { value: 14 },
      // 海洋色块大小
      minSize: { value: 0.025 },
      // 冲击波高度
      waveHeight: { value: 0.1 },
      // 冲击波范围
      scaling: { value: 1 },
      // 冲击波径向渐变内侧颜色
      gradInner: { value: new THREE.Color(params.colors.gradInner) },
      // 冲击波径向渐变外侧颜色
      gradOuter: { value: new THREE.Color(params.colors.gradOuter) },
    };

3.创建一个球体,把世界地图的平面图贴上就可以了

     //贴图
    const textureLoader = new THREE.TextureLoader();
    const doorColorTexture = textureLoader.load(kxzsqa);
    let m = new THREE.MeshBasicMaterial({
      map: doorColorTexture,
    });
    m.onBeforeCompile = (shader) => {
      shader.uniforms.impacts = uniforms.impacts;
      shader.uniforms.maxSize = uniforms.maxSize;
      shader.uniforms.minSize = uniforms.minSize;
      shader.uniforms.waveHeight = uniforms.waveHeight;
      shader.uniforms.scaling = uniforms.scaling;
      shader.uniforms.gradInner = uniforms.gradInner;
      shader.uniforms.gradOuter = uniforms.gradOuter;
      // shader.uniforms.tex = { value: new THREE.TextureLoader().load(kxzsqa) };
      shader.vertexShader = 'uniform float time;\n' + shader.vertexShader;
    };

    // 创建球体
    var globeGgeometry = new THREE.SphereGeometry(4.9995, 100, 100); //创建几何球体
    var globeMesh = new THREE.Mesh(globeGgeometry, m); //创建网格模型
    var point = new THREE.PointLight(0xffffff); //设置光源
    point.rotation.set(0, -0.4, 0);
    scene.add(globeMesh);

第一次尝试写threejs,仅供参考,自己只是记录一下按照别人的模版改了改。

参考链接:

使用Three.js实现炫酷的赛博朋克风格3D数字地球大屏 🌐 - 掘金本文使用 Three.js 和 CSS实现赛博朋克2077风格视觉效果 实现炫酷 3D 数字地球大屏页面。技术栈包括React + Three.js + Echarts,知识点包括THREE.Spheicon-default.png?t=N7T8https://juejin.cn/post/7124116814937718797

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值