使用Three.js制作一个旋转多面体

news2024/11/29 12:32:26

之前一直对three.js比较好奇,但是一直没有着手学习。今天刷到一篇博客(博主:1_bit),觉得挺有意思,就跟着敲了一下。

html:

其中canvas用于添加渲染好的元素,本篇文章通过CDN形式引入three.js,另外一个js则是我们自己编写的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
    <div id="canvas"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.151.3/three.min.js"></script>
    <script src="./js/index.js"></script>
</body>
</html>

css:

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
html{
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    background: linear-gradient(to bottom, #11e8bb 0%, #8200c9 100%);
}

进入正题:

具体操作,在代码的注释中我都有写,就不在赘述了。以下就是完整的js代码

var renderer, scene, camera, inside, outside, particle;
window.onload = function () {
    // 创建对象存储三要素(渲染器、场景、摄像头)
    /**
     * 渲染器
     * 通过调用 THREE 对象的 WebGLRenderer 对摄像头进行创建,WebGLRenderer 方法接收传入一个渲染器的配置项对象
     * antialias 表示抗锯齿打开,使几何体边缘平滑
     * alpha 表示渲染器渲染时的画面有透明通道,若不打开将不会存在透明通道
     */
    renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });

    // 设置渲染器大小
    renderer.setSize(window.innerWidth, window.innerHeight)
    // 获取canvas,并将渲染器添加到canvas窗口
    // renderer.domElement 是得到渲染器渲染出的 canvas
    document.querySelector('#canvas').appendChild(renderer.domElement)

    /**
     * 场景
     * 通过 THREE 的 Scene 方法即可创建
     */
    scene = new THREE.Scene()

    /**
     * 摄像头
     * 使用 PerspectiveCamera 创建透视摄像头
     * 参数含义:
     * 相机可视垂直视野角度,相机可视长宽比,相机近端距离,相机远端距离
     * 若可视物体小于了 相机近端距离 和 大于了 相机远端距离 都会不可见
     */
    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
    //  移动摄像头的 Z 轴,此时 z 轴就相当是人的视野
    camera.position.z = 500
    // 将摄像头加入到场景当中
    scene.add(camera)

    /**
     * 创建几何体
     */
    // 通过 IcosahedronGeometry 方法创建两个20面的几何体
    // 参数含义:
    // 1. 二十面体的半径,默认为1;
    // 2.设置面角,默认为0,值超过1则是球体,超过0小于1则会增加顶点使其转变成非二十面几何体
    var geom = new THREE.IcosahedronGeometry(7, 1)
    var geom2 = new THREE.IcosahedronGeometry(15, 1)

    // 为20面体创建显示样式(创建材质)
    var mat = new THREE.MeshPhongMaterial({
        color: 0xffffff,
        shading: THREE.FlatShading //网格的渲染方式(之后要使用的网格),在此使用
    })
    var mat2 = new THREE.MeshPhongMaterial({
        color: 0xffffff,
        wireframe: true, // 渲染的网格将会呈现线框形式
        side: THREE.DoubleSide // 双面渲染;  THREE.FrontSide:单面渲染
    })

    // 创建 Mesh,用于组装3D对象
    var planet = new THREE.Mesh(geom, mat)
    // 对 planet 进行缩放显示
    planet.scale.x = planet.scale.y = planet.scale.z = 16
    // 创建Object3D,用于存放几何体
     inside = new THREE.Object3D()
    inside.add(planet)
    scene.add(inside)

    // 创建第二个 Mesh,并创建Object3D 对象存放
    var planet2 = new THREE.Mesh(geom2, mat2);
    planet2.scale.x = planet2.scale.y = planet2.scale.z = 10
    outside = new THREE.Object3D();
    outside.add(planet2);
    scene.add(outside);

    /**
     *  创建光源
     * 通过方法 AmbientLight 创建环境光,传入环境光颜色
    //  */
     var ambientLight = new THREE.AmbientLight(0x999999);
     scene.add(ambientLight);   

    /**
     * 创建太阳光
     * 通过 DirectionalLight 进行创建,
     * 参数含义:
     * 1.光照颜色,2.光照强度,默认为1
     */
    var ligthts1 = new THREE.DirectionalLight(0xffffff,1)
    ligthts1.position.set(1,0,0)
    var ligthts2 = new THREE.DirectionalLight(0x11E8BB,1)
    ligthts2.position.set(0.75,1,0.5)
    var ligthts3 = new THREE.DirectionalLight(0x8200C9,1)
    ligthts3.position.set(-0.75,-1,0.5)
    scene.add(ligthts1)
    scene.add(ligthts2)
    scene.add(ligthts3)

    // 创建环境物体
    // 创建一个3D容器,并将其加入到场景中
    particle = new THREE.Object3D();
    scene.add(particle);
    // 创建一个四面体,参数含义:1.半径,2.面角
    var geometry = new THREE.TetrahedronGeometry(2, 0);
    var material = new THREE.MeshPhongMaterial({
        color: 0xffffff,
        shading: THREE.FlatShading
    });
    for (var i = 0; i < 1000; i++) {
        var mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
        mesh.position.multiplyScalar(90 + (Math.random() * 700));
        mesh.rotation.set(Math.random() * 2, Math.random() * 2, Math.random() * 2);//旋转
    
        particle.add(mesh);
    }   
    animate()
}
// 动画
function animate() {
	requestAnimationFrame(animate);

	particle.rotation.x += 0.0010;
	particle.rotation.y -= 0.0040;
	inside.rotation.x -= 0.0020;
	inside.rotation.y -= 0.0030;
	outside.rotation.x -= 0.0010;
	outside.rotation.y += 0.0020;
	renderer.clear();

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

效果演示:

今日寄语:种一棵树最好的时间是十年前,其次是现在! 

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

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

相关文章

2023 Gartner RPA魔力象限报告解读:国产厂商“破纪录”跃升意味着什么?

2023 Gartner RPA魔力象限报告解读&#xff1a;象限跃升彰显国产RPA厂商实力 2023 Gartner RPA魔力象限报告四大行业趋势&#xff0c;国产RPA厂商已在践行 文/王吉伟 8月3日&#xff0c;全球著名咨询调查机构Gartner发布了《2023年全球RPA魔力象限&#xff08;Gartner RPA M…

ceph相关概念和部署

Ceph 可用于向云提供 Ceph 对象存储 平台和 Ceph 可用于提供 Ceph 块设备服务 到云平台。Ceph 可用于部署 Ceph 文件 系统。所有 Ceph 存储集群部署都从设置 每个 Ceph 节点&#xff0c;然后设置网络。 Ceph 存储集群需要满足以下条件&#xff1a;至少一个 Ceph 监控器&#x…

10分钟学会阿里OSS对象存储

一. 前言 最近有很多小伙伴问&#xff0c;如果我们要进行大规模的文件存储该怎么做? 其实实现文件存储的技术有很多&#xff0c;如果我们在网上搜索一下&#xff0c;你会发现实现的技术简直是五花八门&#xff0c;比如有一种技术叫FastDFS就可以实现文件存储&#xff0c;但该…

Effective Java笔记(31)利用有限制通配符来提升 API 的灵活性

参数化类型是不变的&#xff08; invariant &#xff09; 。 换句话说&#xff0c;对于任何两个截然不同的类型 Typel 和 Type2 而言&#xff0c; List<Type1 &#xff1e;既不是 List<Type 2 &#xff1e; 的子类型&#xff0c;也不是它的超类型 。虽然 L ist<String…

问道管理:零基础学炒股?

跟着股市的不断升温&#xff0c;越来越多的人参加到了炒股大军中&#xff0c;希望经过股市赚到更多的金钱。但是关于零根底的新手来说&#xff0c;怎么开始学习炒股成为了一个难题。那么&#xff0c;零根底学炒股真的难吗&#xff1f;怎么更好的入门和学习&#xff1f; 首要&am…

线性代数(三) 线性方程组

前言 如何利用行列式&#xff0c;矩阵求解线性方程组。 线性方程组的相关概念 用矩阵方程表示 齐次线性方程组&#xff1a;Ax0&#xff1b;非齐次线性方程组&#xff1a;Axb. 可以理解 齐次线性方程组 是特殊的 非齐次线性方程组 如何判断线性方程组的解 其中R(A)表示矩阵A的…

模型、策略和算法

模型(model)、策略(strategy)和算法(algorithm)是统计学习的所有内容. 模型是统计学习的最终结果&#xff0c;即决策函数(decision function) 或条件概率函数 &#xff0c;它被⽤来预测特定问题下&#xff0c;将来未知输⼊的输出结果. 策略是统计学习过程中的产⽣最优模型的评…

如何使用vue创建一个项目

1、安装node.js 打开cmd 输入node -v 和npm -v查看电脑是否已经安装了node,js 如果出现以下截图&#xff0c;则说明已经有node.js&#xff0c;可忽略此步 如果没有&#xff0c;则打开官网&#xff0c;下载即可 下载地址&#xff1a;Node.js 下载完成后&#xff0c;打开cmd输…

漏洞挖掘日记1:企业src某系统存在登录绕过漏洞

&#xff08;一&#xff09;漏洞描述 这个漏洞属于逻辑漏洞&#xff0c;逻辑漏洞是指开发者在开发过程中&#xff0c;实现业务上出现了逻辑上的漏洞。之所以出现逻辑漏洞&#xff0c;是因为一些开发者&#xff0c;在开发过程中&#xff0c;第一考虑是怎么实现功能&#xff0c;…

OPENCV C++(十)gramm矫正+直方图均衡化

两者都是只对单通道使用&#xff0c;对多通道的话 就需要分离通道处理再合并通道 两种方法&#xff0c;第一个要运算次数太多了&#xff0c;第二个只需要查表 伽马矫正函数&#xff0c;这里用第二种方法&#xff0c;且写法有点高级 int gammaCorrection(cv::Mat srcMat, cv::…

路由器和交换机的区别

交换机和路由器的区别 交换机实现局域网内点对点通信&#xff0c;路由器实现收集发散&#xff0c;相当于一个猎头实现的中介的功能 路由器属于网络层&#xff0c;可以处理TCP/IP协议&#xff0c;通过IP地址寻址&#xff1b;交换机属于中继层&#xff0c;通过MAC地址寻址(列表)…

聚观早报 | 真我GT5系列工艺细节曝光;小米MIXFold3定妆照抢先看

【聚观365】8月10日消息 真我GT5系列工艺细节曝光小米MIX Fold 3定妆照抢先看360智脑整体能力提升15%科大讯飞智能办公本X3正式发布索尼第二季度营收增长33% 真我GT5系列工艺细节曝光 在此前举办的ChinaJoy2023上&#xff0c;作为手机行业新势力的真我realme携手旗下多款爆款…

JavaWeb 速通Session

目录 一、Session的引入 1.什么是Session&#xff1f; 2.Session的基本原理 : 3.Session长什么样子&#xff1f; 二、Session的底层机制 1. Session接口相关的方法 : 1 req.getSession() : 2 httpSession.setAttribute(String name, Object val); 3 Object obj httpSessi…

Python(七十五--总结)列表、字典、元组、集合总结

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

【Python篇】Python基础语法

【Python篇】Python基础语法 拖拖拖&#xff0c;能使工作便捷高效的为何要拒绝&#xff0c;作个记录—【蘇小沐】 文章目录 【Python篇】Python基础语法1.实验环境 1、标识符2、Python保留字&#xff08;关键字&#xff1a;不能用作任何标识符名称&#xff09;3、注释1&#x…

定制全彩LED电子屏的模组类型

定制全彩LED电子屏的成功与否很大程度上取决于选择合适的LED模组。LED模组是LED电子屏的基本组成部分&#xff0c;直接影响显示效果、可靠性和性能。什么是LED模组&#xff1f;根据LED屏表面处理的工艺不同&#xff0c;我们可以把其分为插件模组、表贴模组、亚表贴模组、三合一…

Redis 搭建哨兵集群

文章目录 0. 哨兵原理1. 哨兵集群架构2. 准备实例和配置3. 启动4. 测试5. RedisTemplate 的哨兵模式配置地址配置读写分离 在 主从架构 Redis 搭建主从集群 中&#xff0c;一个 slave 节点挂了无影响&#xff0c;但是 master 节点挂了&#xff0c;就无法进行写操作了&#xff0…

代码随想录算法训练营之JAVA|第二十五天| 491. 递增子序列

今天是第25天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天。 算法挑战链接 491. 递增子序列https://leetcode.cn/problems/non-decreasing-subsequences/ 第一想法 题目理解&#xff1a;在给定的一个数组中&#xff0c;找出全部的递增列表。要求不能有重复。 这是一…

Talk | 清华大学交叉信息研究院助理教授许华哲:具身控制中的泛化能力

本期为TechBeat人工智能社区第520期线上Talk&#xff01; 北京时间8月9日(周三)20:00&#xff0c;清华大学交叉信息研究院助理教授—许华哲的Talk已准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “具身控制中的泛化能力”&#xff0c;从具身控制中视觉外…

python采集淘宝整店商品 json格式

竞争优势&#xff1a;通过采集淘宝整店商品&#xff0c;可以获取到同一行业或同一类别的竞争对手的商品信息。这使得你可以更好地了解市场上的产品&#xff0c;了解竞争对手的定价、销售策略和产品特点&#xff0c;从而更好地制定自己的营销策略和定价策略。在竞争激烈的市场中…