【jsthreeJS】入门three,并实现地月绕行,附带全码

news2024/11/24 4:25:07

效果图:

序幕准备:

需要自己准备地球跟月球的纹理贴图,如下:

图片格式转换网址,如下:

Zamzar - File Conversion progress

开始编码:

实现步骤如下:

  • 在JavaScript部分,首先初始化场景、相机、渲染器、光源以及控制器。

  • 通过调用sphereGeometry函数创建地球和月球的几何体,并应用纹理贴图。

  • 调用createLabel函数创建标签,将标签绑定到地球和月球模型上。

  • 初始化相机位置和渲染器设置。

  • 使用OrbitControls控制器来实现鼠标和触摸事件的交互控制。

  • 实现动画效果的ani函数,其中通过计时器对象clock获取经过的时间,根据时间计算月球绕行轨道的位置,以及地球的自转角度。

  • 使用渲染器对象rendererlabelRenderer进行场景渲染。

  • 使用浏览器提供的requestAnimationFrame函数递归调用ani函数,实现动画效果。

完整代码展示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background: url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F1%2F590c2682cc04c.jpg%3Fdown&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641349822&t=06301990af74d7bde9f5675864375620) no-repeat;
            background-size: cover;
            padding: 0;
            margin: 0;
        }

        .label {
            color: #ffffff;
            font-size: 16px;
        }
    </style>
</head>

<body>

</body>

</html>
<script type="importmap">
    {
        "imports": {
            "three": "./three.module.js"
        }
    }
</script>
<script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from './jsm/controls/OrbitControls.js'
    import { CSS2DRenderer, CSS2DObject } from './jsm/renderers/CSS2DRenderer.js'


    var scene, camera, renderer, labelRenderer, controls;
    var earth, moon;
    let oldtime = 0;

    // 用于测量时间
    var clock = new THREE.Clock();

    // 用于加载纹理贴图
    const textureLoader = new THREE.TextureLoader();

    // 分别表示 地球和月球的半径
    const EARCH_RADIUS = 2.6;
    const MOON_RADIUS = 0.3;


    init();
    ani();
    //初始化
    function init() {
        //场景初始化
        scene = new THREE.Scene();
        //光源初始化  聚光灯光源对象
        const light = new THREE.SpotLight(0xffffff);
        //沿着z轴打光
        light.position.set(0, 0, 50);

        scene.add(light);
        //物体初始化
        let earthUrl = './earthUrl.jpg';
        let moonUrl = './seleno.jpg';

        // 应用纹理贴图 
        // sphereGeomery 函数负责创建球体几何体,参数包括纹理贴图的路径、半径、水平和垂直分段数
        earth = sphereGeomery(earthUrl, EARCH_RADIUS, 16, 16);
        moon = sphereGeomery(moonUrl, MOON_RADIUS, 16, 16);

        // 创建标签
        createLabel(earth, '地球', EARCH_RADIUS);
        createLabel(moon, '月亮', MOON_RADIUS);

        // 将地球和月球添加到场景中,使它们可以在渲染中显示
        scene.add(earth);
        scene.add(moon);


        //创建了一个 Three.js 透视相机对象
        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 500);
        //设置相机的位置
        camera.position.set(0, 0, 20);

        //创建了一个 Three.js WebGL 渲染器对象
        renderer = new THREE.WebGLRenderer({
            antialias: true,//消除锯齿
            alpha: true //透明
        });
        // 设置渲染器的尺寸
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);
        // 像素比例
        document.body.appendChild(renderer.domElement);

        // 创建了一个用于渲染 CSS2DObject 的渲染器对象,并设置其尺寸与窗口大小一致
        labelRenderer = new CSS2DRenderer();
        labelRenderer.setSize(window.innerWidth, window.innerHeight);

        // 将 CSS2D 渲染器的 DOM 元素添加到 HTML 文档的 <body> 元素中,并将其设置为绝对定位并置于页面顶部
        labelRenderer.domElement.style.position = 'absolute';
        labelRenderer.domElement.style.top = '0px';
        document.body.appendChild(labelRenderer.domElement);

        // camera 是要进行控制的相机对象,document.body 是用于监听鼠标和触摸事件的 DOM 元素。
        controls = new OrbitControls(camera, document.body);
        controls.maxPolarAngle = 0.9 * Math.PI / 2
        controls.enableZoom = true
        controls.enableDamping = true

    }

    //创建物体
    function sphereGeomery(textureUrl, radius, widthSegments, heightSegments) {
        // 创建一个 Three.js 的球体几何体对象
        // 参数包括球体的半径、水平分段数和垂直分段数
        let geometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments);

        // 创建了一个基于 Phong 光照模型的网格材质对象 MeshPhongMaterial,并为其指定了一个纹理贴图
        let material = new THREE.MeshPhongMaterial({
            // 加载指定 URL 的纹理贴图,并将其赋值给材质对象的 map 属性
            map: textureLoader.load(textureUrl)
        });

        // 创建的几何体和材质创建一个网格对象 Mesh,并将几何体与材质进行组合
        let mesh = new THREE.Mesh(geometry, material);
        return mesh;

    }

    //创建标签
    function createLabel(mesh, text, radius) {
        const div = document.createElement('div');
        div.className = 'label';
        div.textContent = text;
        // 创建的 <div> 元素包装在 CSS2DObject 对象中
        const label = new CSS2DObject(div);
        // 设置标签元素的位置。它将标签元素放置在与球体物体相对应的位置上方,radius + 0.5 表示在球体半径的基础上向上偏移 0.5 的距离
        label.position.set(0, radius + 0.5, 0);
        // 将标签元素添加到传递进来的 mesh 对象中,使标签元素与物体绑定
        mesh.add(label);
    }

    //动画
    function ani() {
        // clock 是 Three.js 提供的一个计时器对象,getElapsedTime 方法可以返回自上次重置以来经过的时间
        const elapsed = clock.getElapsedTime();

        // 设置 moon 对象的位置实现月球的绕行效果。利用正弦函数和余弦函数计算出月球在 x、y 和 z 轴上的坐标,从而使其沿着一个圆形轨道绕着中心点运动
        moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5);

        // 向量 (0, 1, 0) 表示在三维空间中的 Y 轴方向。该向量可以用于进行旋转操作,指定物体绕着 Y 轴旋转
        var axis = new THREE.Vector3(0, 1, 0);
        // rotateOnAxis 方法实现地球的自转效果
        // 接受一个向量和一个旋转角度作为参数,使物体围绕指定轴进行旋转
        // 这里根据经过的时间差计算出旋转角度,并乘以一个系数,控制旋转的速度
        earth.rotateOnAxis(axis, (elapsed - oldtime) * Math.PI / 10);

        // 渲染
        renderer.render(scene, camera);
        labelRenderer.render(scene, camera);

        // 将当前的时间值存储到变量 oldtime 中,以便在下一帧计算地球自转的角度变化
        oldtime = elapsed;

        // 使用浏览器提供的 requestAnimationFrame 函数,将 ani 函数递归调用,以便在下一帧执行动画效果
        requestAnimationFrame(ani);

    }

</script>

注解:

new THREE.SphereGeometry(radius, widthSegments, heightSegments) 水平分段数和垂直分段数

  • 水平分段数(widthSegments)指的是在球体的水平方向上将经度划分成多少段。较高的数值会在水平方向上增加更多的面片,使球体表面更加平滑。这决定了球体经线(经度线)的数量。

  • 垂直分段数(heightSegments)指的是在球体的垂直方向上将纬度划分成多少段。同样地,较高的数值会在垂直方向上增加更多的面片,使球体表面更加平滑。这决定了球体纬线(纬度线)的数量。

new THREE.MeshPhongMaterial()是什么

Phong是一种经典的着色模型,可以模拟光照效果

着色模型在Three.js中的作用是定义物体表面的外观,决定了物体在渲染时呈现出的效果

在Three.js中,有多种着色模型可用于渲染网格模型的表面,一些常见的着色模型:

  • 基础着色模型(Basic Material):最简单的着色模型,不考虑光照和阴影效果,只显示材质的基本颜色。

  • 基础光照着色模型(Lambert Material):使用Lambert光照模型,考虑漫反射光照,适用于呈现无光泽的物体。

  • Phong着色模型(Phong Material):使用Phong光照模型,考虑漫反射、镜面反射和环境光照。可以实现光滑的表面效果。

  • Blinn-Phong着色模型(MeshStandardMaterial):是Phong模型的一种变体,使用Blinn-Phong光照模型,相对于Phong模型计算更加高效。

  • 物理着色模型(Physical Material):基于真实物理原理的光照模型,考虑漫反射、镜面反射、金属度、粗糙度等参数。可以实现高度逼真的外观效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/911885.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue】使用Hbuilder x开发vue前端项目

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 一、Hbuilder x 代码风格调整1.在工具中找到设置&#xff0c;点击插件设置2.代开jsbeautify.js配置2.uni-app项目icon的使用 一、Hbuilder x …

解读逻辑输出光隔离器TLP2355(TPL,E(T 在工业自动化应用技巧

逻辑输出光隔离器是一种用于隔离电路中的逻辑信号和光信号的器件。它通常由光电耦合器和逻辑输出接口组成。 光电耦合器是一种能够将光信号转换为电信号的器件&#xff0c;它由一个发光二极管和一个光敏二极管组成。当发光二极管接收到电路中的逻辑信号时&#xff0c;它会发出…

智能在线客服系统,客户问题接待更及时

优质的客户服务可以提高客户的满意度和忠诚度&#xff0c;从而为企业带来更多的商业机会。智能在线客服系统&#xff0c;是指通过人工智能技术和自然语言处理技术&#xff0c;将客户的问题自动化地分配给相应的客服人员&#xff0c;从而实现客户问题的快速解答。相比传统的客服…

七夕节海外网红营销:助力品牌赢得全球消费者

随着全球化的进程不断加速&#xff0c;七夕节作为一个传统的华人节日&#xff0c;正逐渐走向国际舞台&#xff0c;成为了海外品牌开拓市场的营销新热点。近年来&#xff0c;海外网红已成为品牌宣传的重要工具&#xff0c;他们的影响力和粉丝基础成为了出海品牌开拓海外市场的利…

WindowsServer安装IIS以及搭建Asp网页

简介 Internet Information Services (IIS) 是一个由微软公司创建和维护的&#xff0c;用于在Windows系统上托管网站和Web应用程序的服务器。IIS是Windows Server的一个组成部分&#xff0c;并且也可以在某些版本的Windows上运行。 IIS支持多种Web开发技术&#xff0c;包括AS…

第六章,创作文章

6.1添加创作页面 <template><div class="blog-container"><div class="blog-pages"><div class="col-md-12 panel"><div class="panel-body"><h2 class="text-center">创作文章&l…

220V转5V芯片三脚芯片-AH8652

220V转5V芯片三脚芯片是一种非常常见的电源管理芯片&#xff0c;它通常被用于将高压交流输入转为稳定的直流5V输出。芯片型号AH8652是一款支持交流40V-265V输入范围的芯片&#xff0c;采用了SOT23-3三脚封装。该芯片内部集成了650V高压MOS管&#xff0c;能够稳定地将输入电压转…

中小型企业人事考勤管理系统的设计(论文+源码)_kaic

摘要 中小企业是我国经济的重要组成部分&#xff0c;人事管理对于中小企业的发展和运营至关重要。传统的人事考勤管理方式往往存在着效率低、准确度不高以及易于被操控等问题&#xff0c;给企业的管理带来了一定的困扰。为了解决中小企业在人事考勤管理方面面临的问题&#xff…

Databend 开源周报第 107 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 理解连接参数 …

html动态爱心代码【一】(附源码)

前言 七夕马上就要到了&#xff0c;为了帮助大家高效表白&#xff0c;下面再给大家带来了实用的HTML浪漫表白代码(附源码)背景音乐&#xff0c;可用于520&#xff0c;情人节&#xff0c;生日&#xff0c;表白等场景&#xff0c;可直接使用。 效果演示 文案修改 var loverNam…

LeetCode669. 修剪二叉搜索树

669. 修剪二叉搜索树 文章目录 [669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/)一、题目二、题解方法一&#xff1a;递归法方法二&#xff1a;迭代法 一、题目 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 hig…

【并发编程的艺术读书笔记】synchronized锁升级机制详解

锁升级机制 简介锁升级流程三种锁的优缺点 简介 synchronized在早期被称为重量级锁&#xff0c;而到现在已经得到不少优化。偏向锁、轻量级锁、重量级锁指的是synchronized三种形态。 锁升级流程 无锁&#xff08;Unlocked&#xff09;&#xff1a; 初始状态&#xff0c;表示…

​ 模拟嵌入式边缘计算卡设计方案:367-XC7Z100 板卡 基于zynq XC7Z100 FMC接口通用计算平台

基于zynq XC7Z100 FMC接口通用计算平台 一、板卡概述 北京太速科技板卡由SoC XC7Z100-2FFG900I芯片来完成卡主控及数字信号处理&#xff0c;XC7Z100内部集成了两个ARM Cortex-A9核和一个kintex 7的FPGA&#xff0c;通过PL端FPGA扩展FMC、光纤、IO等接口&#xff0c;PS端ARM扩展…

智慧高速公路整体解决方案[76页PPT]

导读&#xff1a;原文《76页智慧高速公路整体解决方案PPPT》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以关注评论转发本文&#xff0c…

java excel导出 本地运行数据正常 docker或者服务器导出数据为空 已解决

加上这个 response.addHeader("Content-Type","application/octet-stream;charsetutf-8"); 如图

【python爬虫案例】爬了上千条m端微博签到数据

一、爬取目标 大家好&#xff0c;我是马哥python说&#xff0c;一枚10年程序猿。 今天分享一期python爬虫案例&#xff0c;爬取目标是新浪微博的微博签到数据&#xff0c;字段包含&#xff1a; 页码,微博id,微博bid,微博作者,发布时间,微博内容,签到地点,转发数,评论数,点赞数…

Sphinx——Python生成API文档

1、简介 Sphinx是Python文档生成器&#xff0c;它基于reStructuredText标记语言&#xff0c;可自动根据项目生成HTML&#xff0c;PDF等格式的文档&#xff0c;无数著名项目的文档均用Sphinx生成&#xff0c;如机器学习库scikit-learn、交互式神器Jupyter Notebook sphinx是一…

k8s ingress (二)

k8s ingress (二) Ingress介绍 在前面课程中已经提到&#xff0c;Service对集群之外暴露服务的主要方式有两种&#xff1a;NodePort和LoadBalancer&#xff0c;但是这两种方式&#xff0c;都有一定的缺点&#xff1a; NodePort方式的缺点是会占用很多集群机器的端口&#xff0…

常见的时序数据库

1.概念 时序数据库全称为时间序列数据库。时间序列数据库指主要用于处理带时间标签&#xff08;按照时间的顺序变化&#xff0c;即时间序列化&#xff09;的数据&#xff0c;带时间标签的数据也称为时间序列数据。 时间序列数据主要由电力行业、化工行业、气象行业、地理信息…

【高危】Apache Airflow Spark Provider 任意文件读取漏洞 (CVE-2023-40272)

漏洞描述 Apache Airflow Spark Provider是Apache Airflow项目的一个插件&#xff0c;用于在Airflow中管理和调度Apache Spark作业。 受影响版本中&#xff0c;在JDBC连接时&#xff0c;由于没有对conn_prefix参数做验证&#xff0c;允许输入"?"来指定参数。攻击者…