ThreeJS-3D教学一基础场景创建

Three.js 是一个开源的 JS 3D 图形库,用于创建和展示高性能、交互式的 3D 图形场景。它建立在 WebGL 技术之上,并提供了丰富的功能和工具,使开发者可以轻松地构建令人惊叹的 3D 可视化效果。

Three.js 提供了一套完整的工具和 API,用于创建和管理 3D 场景、几何体、纹理、光照、材质和相机等方面。它具有强大的渲染引擎,可以处理复杂的渲染任务,如阴影、透明度、反射和折射等效果。该库还支持动画、骨骼动画、粒子系统和物理模拟,可以实现流畅的动态效果和交互行为。它提供了丰富的控制器和用户交互工具,如旋转、缩放、平移和点击等操作。

Three.js 还支持加载和导入各种文件格式,如 OBJ、STL、FBX 和 glTF 等,以便使用外部工具创建和编辑 3D 模型。它还可以与音频、视频和其他 Web 技术进行集成,实现更丰富的应用场景。

接下来我们依次介绍three的三大件,渲染器(Renderer),场景(Scene),照相机(Camera),这三个展开说每一个都能单开一篇,这里简单介绍下概念,我们主要从案例中学习具体知识,感兴趣的朋友可以看这个链接Three.js学习,介绍的比较详细

渲染器(Renderer)

当我们在官方文档搜索WebGL时会显示七个类渲染器
WebGLMultipleRenderTargets
WebGLRenderer
WebGL1Renderer
WebGLRenderTarget
WebGL3DRenderTarget
WebGLArrayRenderTarget
WebGLCubeRenderTarget
暂时我们只聚焦于WebGLRenderer,其实真正经常用到的也是它。

WebGL1Renderer
three在 r118(包含此版本)后,自动使用WebGL 2 渲染上下文,如果您没有时间升级代码,但仍想使用最新版本,可以使用WebGL1Render。此版本的渲染器将强制执行WebGL 1渲染上下文。

WebGLRenderer
下面是一个基础的WebGLRenderer应用

 var renderer;var width,height;function initThree() {width = document.getElementById("box").clientWidth;height = document.getElementById("box").clientHeight;// 生成渲染器对象(属性antialias:抗锯齿效果为设置有效)renderer = new THREE.WebGLRenderer({antialias: true});renderer.setSize(width,height);document.getElementById("box").appendChild(renderer.domElement);// 设置canvas背景色(clearColor)和背景色透明度(clearAlpha)renderer.setClearColor(0xFFFFFF, 1.0);}

场景(Scene)

three.js添加的模型都添加到了场景中,其初始化很简单

 var scene;function initScene(){scene = new THREE.Scene();// 场景的背景色scene.background = new THREE.Color( 0xf0f0f0 );}// 添加一个物体 mesh是什么后面会说明scene.add(mesh);

照相机(Camera)

你可以把相机想象为我们的眼睛,它决定了场景中哪个角度的景色会显示出来 ,就是我们所看到的,人站在不同位置,抬头或者低头都能够看到不同的景色 ,默认的照相机与加载进来的模型都处于坐标原点,为了能够看到模型,需要将照相机位置偏移。
经常用到相机分为:
CubeCamera

此相机适配 WebGLCubeRenderTarget

正交相机-OrthographicCamera

在此投影模式下,无论对象与摄影机的距离如何,其在渲染图像中的大小都保持不变。这对于渲染2D场景和UI元素等非常有用。

透视相机-PerspectiveCamera

这种投影模式是为了模仿人眼的视觉方式而设计的。它是用于渲染三维场景的最常见的投影模式。

我所有案例three版本是 three-155
先看效果图
在这里插入图片描述

上代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>body {width: 100%;height: 100%;}* {margin: 0;padding: 0;}.label {font-size: 20px;color: #fff;font-weight: 700;}</style>
</head>
<body>
<div id="container"></div>
<script type="importmap">{"imports": {"three": "../three-155/build/three.module.js","three/addons/": "../three-155/examples/jsm/"}}
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer;
let camera, scene, renderer, mesh, target, controls;
const group = new THREE.Group();init();
initHelp();
initLight();
axesHelperWord();
animate();function init() {camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 2000 );camera.position.set(0, 500, 500);camera.up.set(0, 1, 0);camera.lookAt(0, 0, 0);scene = new THREE.Scene();scene.background = new THREE.Color( '#ccc' );renderer = new THREE.WebGLRenderer( { antialias: true } );renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );labelRenderer = new CSS2DRenderer();labelRenderer.setSize( window.innerWidth, window.innerHeight );labelRenderer.domElement.style.position = 'absolute';labelRenderer.domElement.style.top = '0px';labelRenderer.domElement.style.pointerEvents = 'none';document.getElementById( 'container' ).appendChild( labelRenderer.domElement );window.addEventListener( 'resize', onWindowResize );controls = new OrbitControls( camera, renderer.domElement );controls.minDistance = 10;controls.maxDistance = 1000;// 设置为true可启用阻尼(惯性),可用于为控件提供重量感。默认值为false。// 请注意,如果启用了此选项,则必须在动画循环中调用.update()。controls.enableDamping = false;controls.screenSpacePanning = false; // 定义平移时如何平移相机的位置 控制不上下移动stats = new Stats();stats.setMode(1); // 0: fps, 1: msdocument.body.appendChild( stats.dom );scene.add( group );
}function initLight() {const light = new THREE.DirectionalLight(new THREE.Color('rgb(253,253,253)'));light.position.set(100, 100, -10);light.intensity = 3; // 光线强度const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255,255,255)'));scene.add( light );scene.add( AmbientLight );
}function initHelp() {const size = 1000;const divisions = 20;const gridHelper = new THREE.GridHelper( size, divisions );scene.add( gridHelper );// The X axis is red. The Y axis is green. The Z axis is blue.const axesHelper = new THREE.AxesHelper( 500 );scene.add( axesHelper );
}function axesHelperWord() {let xP = addWord('X轴');let yP = addWord('Y轴');let zP = addWord('Z轴');xP.position.set(200, 0, 0);yP.position.set(0, 200, 0);zP.position.set(0, 0, 200);
}function addWord(word) {let name = `<span>${word}</span>`;let moonDiv = document.createElement( 'div' );moonDiv.className = 'label';// moonDiv.textContent = 'Moon';// moonDiv.style.marginTop = '-1em';moonDiv.innerHTML = name;const label = new CSS2DObject( moonDiv );group.add( label );return label;
}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );
}function animate() {requestAnimationFrame( animate );stats.update();controls.update();labelRenderer.render( scene, camera );renderer.render( scene, camera );
}
</script>
</body>
</html>

这是一个简单的3D场景,除了之前介绍的三大件,renderer,camera、scene,
stats.js
左上角是一个 Three.js 开发的辅助库,主要用于检测动画运行时的帧数。
stats.setMode(1); // 0: fps, 1: ms
设置为 0:检测的是画面每秒传输帧数(fps)
设置为 1:检测的是画面渲染的时间

OrbitControls.js
动态观察控件允许摄影机围绕目标动态观察。

GridHelper
是一个用于定义网格的对象。网格是二维的线阵列。这也是个辅助工具,帮我们看清3D场景

AxesHelper
一个轴对象,以一种简单的方式显示3个轴。X轴为红色,Y轴为绿色。Z轴为蓝色。这也是个辅助工具,可以清晰的让我们在3D场景中看清方向也就是 X、Y、Z轴在哪

CSS2DRenderer
图中的文案用到了CSS2DRenderer,当然对应的还有CSS3DRenderer,这两者的主要区别就是CSS2DRenderer会永远面向相机,且大小不会随意相机移动而变化。非常适合辅助AxesHelper指明X、Y、Z轴

light
当然还有一个非常重要的光源,这里用到了DirectionalLight 和 AmbientLight,其实还有一些比如:PointLight、SpotLight、RectAreaLight后面我们会介绍到

AmbientLight
该灯光在全局范围内平等地照亮场景中的所有对象。
该灯光不能用于投射阴影,因为它没有方向。

DirectionalLight
向特定方向发射的光。这种光的行为就像它是无限遥远的,并且从它产生的光线都是平行的。这方面的常见用例是模拟日光;太阳离得足够远,它的位置可以被认为是无限的,所有来自它的光线都是平行的。
此灯光可以投射阴影
具体用法参数大家可以官网查看下three官网

大家会发现现在3D场景中,除了一些辅助方法,就没别的了,其实这就是我经常用到的标准模版,有了它当我们需要测试或者学习某些效果时,这个就可以直接拿来用,然后我们往里添加需要的效果即可,后面案例中我会一一介绍。

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

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

相关文章

JUC中创建的组件 多线程使用“哈希表”

JUC中创建的组件 JUC中创建的组件这些内容都不太常用&#xff0c;偶尔用到面试的时候&#xff0c;偶尔用到&#xff01;到时候自行查找即可&#xff0c;本文主要来快速的过一下&#xff0c;留个印象即可~ JUC&#xff08;java.util.concurrent&#xff09;和多线程相关的工具…

python从入门到精通(一)

自己也有三四年的码龄了&#xff0c;目前&#xff0c;重拾起自己的博客&#xff0c;记录自己的学习笔记&#xff0c;为大家提供优质内容&#xff0c;也来巩固自己的学习内容。 很开心也成功成为了一名研究生&#xff0c;张张的研究方向是图像处理和计算机视觉这一块&#xff0c…

C++QT 作业8

#include "mywind.h" #include "ui_mywind.h" #include <iostream> #include <QIcon> #include <QLabel> #include <QLineEdit> #include <QDebug>//信息调试类 用于输出数据 Mywind::Mywind(QWidget *parent): QWidget(pa…

python3.11版本pip install ddddocr调用时报错got an unexpected keyword argument ‘det‘ 解决

一、如图出现如下问题 ddddocr.__init__() got an unexpected keyword argument det出现问题原因&#xff1a;python3.11默认安装版本就旧版的ddddocr1.0的&#xff0c;所以导致如下报错 二、解决方案一&#xff08;推荐&#xff09; python3.11的环境直接安装这个即可&…

物 理 层

二、物理层 1、物理层的基本概念 物理层的作用:尽可能的屏蔽掉传输媒体和通信手段的差异&#xff0c;使物理层上面的数据链路层感觉不到这些差异&#xff0c;使其只需要考虑如何完成本层的协议和服务 1.1、物理层的主要任务 机械特性&#xff1a;指明接口所用的接线器的形状…

关闭禁用chrome浏览器的阅读清单/强力书签

文章目录 前言操作 前言 阅读清单对我没啥用&#xff0c;还占用我位置&#xff0c;不小心点击到啥的&#xff0c;必须弃用 操作 chrome地址栏输入 chrome://flags/ 搜索book &#xff0c;关掉下面几个功能

Java 华为真题-猴子爬山

需求&#xff1a; 一天一只顽猴想去从山脚爬到山顶&#xff0c;途中经过一个有个N个台阶的阶梯&#xff0c;但是这猴子有一个习惯&#xff1a;每一次只能跳1步或跳3步&#xff0c;试问猴子通过这个阶梯有多少种不同的跳跃方式&#xff1f; 输入描述 输入只有一个整数N&#xff…

MySQL版数据库原理与应用期末复习重点(3)---画E-R图

文章目录 一、题目一1.1 题目描述1.2 解答 二、题目二2.1 题目描述2.2 解答 一、题目一 1.1 题目描述 设开发一个校园公共自行车管理系统&#xff0c;系统需要达到如下要求&#xff1a; &#xff08;1&#xff09;用户能够注册登录&#xff0c;能够根据借车点的名称查询借车…

若依注册的时候给个默认部门出现获取用户信息异常

想在注册的时候在数据库中查询一个部门给它一个默认部门&#xff0c;结果出现异常——【[handleServiceException,59] - 获取用户信息异常】 经分析代码&#xff0c;此方法有如下注解 以上注解会在mapper.xml中做如下操作 在做此操作之前会进入一个拦截器&#xff0c;根据token…

PHP-composer安装扩展安装,批量操作合并pdf

清除Composer缓存&#xff1a; 运行以下命令来清除Composer的缓存&#xff0c;并再次尝试安装包。 bash composer clear-cache 使用不同的镜像源&#xff1a; Composer使用的默认包源可能会受到限制或访问问题。你可以切换到使用其他镜像源&#xff0c;如阿里云、Composer中国…

安理【2022】

关键字&#xff1a; 出栈序列s2固定、快速排序2趟、next数组、二分查找比较次数log2n向上取整、 一、选择 二、填空 三、应用

Zookeeper 启动失败【Cannot open channel to 3 at election address...】

文章目录 完整报错信息解决方法1.检查文件夹权限2.未监听所有IP3.IP映射名称与 ID 不对应 完整报错信息 Cannot open channel to 3 at election address hadoop121/192.168.10.121:3888 java.net.ConnectException 解决方法 1.检查文件夹权限 检查当前用户是否拥有 Zookeep…

《Kubernetes部署篇:Ubuntu20.04基于containerd部署kubernetes1.25.14集群(多主多从)》

一、架构图 如下图所示: 二、环境信息 1、资源下载基于containerd部署容器版kubernetes1.25.14集群资源合集 2、部署规划主机名K8S版本系统版本内核版本IP地址备注k8s-master-121.25.14Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.12master节点 + etcd节点k8s-master-131.…

adb shell命令查看当前屏幕可见最顶层Activity和Fragment及其调用栈

adb shell命令查看当前屏幕可见最顶层Activity和Fragment及其调用栈 &#xff08;1&#xff09;当前屏幕可见页面最顶层是哪个Activity: adb shell "dumpsys activity top | grep ACTIVITY | tail -n 1"&#xff08;2&#xff09;当前屏幕可见页面最顶层是哪个Fragm…

(图论) 827. 最大人工岛 ——【Leetcode每日一题】

❓ 827. 最大人工岛 难度&#xff1a;困难 给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。 返回执行此操作后&#xff0c;grid 中最大的岛屿面积是多少&#xff1f; 岛屿 由一组上、下、左、右四个方向相连的 1 形成。 示例 1: 输入: grid [[1, 0]…

解决Sublime Text用浏览器打开没反应

点击Open in Browser用浏览器打开没反应怎么解决&#xff1f; 点击Browse Packages 会跳转到这个文件夹页面 打开User文件夹 在文件中添加下面代码即可,chrome是默认打开浏览器&#xff0c;可以自定义为你想用的浏览器 { "browser": "chrome" }

Centos7 安装部署 Kubernetes(k8s) 高可用集群

1&#xff1a;基础环境准备 宿主机系统集群角色服务器IP主机名称容器centos7.6master192.168.2.150ks-m1dockercentos7.6master192.168.2.151ks-n1dockercentos7.6master192.168.2.152ks-n2docker 1.1 服务器初始化及网络配置 VMware安装Centos7并初始化网络使外部可以访问*…

华为HCIA学习(一)

文章目录 一.根据考试题总结知识点&#xff08;一题一点&#xff09;二.上午学习三.下午学习四.今天只做了70题&#xff0c;需要的可以找我 一.根据考试题总结知识点&#xff08;一题一点&#xff09; 二.上午学习 ① VRP系统是VRP是华为公司从低端到高端的全系列路由器、交换…

探讨基于IEC61499 的分布式 ISA Batch 控制系统

ISA SP88 是批次过程控制的标准&#xff0c;对应的IEC标准是IEC 61512。该标准中一个重要的部分是配方管理&#xff08;Recipe Management&#xff09;。 所谓配方&#xff0c;是根据批量产品的要求&#xff0c;材料设定加工工艺&#xff0c;加工流程和参数。类似于传统制造业的…

层次聚类分析

1、python语言 from scipy.cluster import hierarchy # 导入层次聚类算法 import matplotlib.pylab as plt import numpy as np# 生成示例数据 np.random.seed(0) data np.random.random((20,1))# 使用树状图找到最佳聚类数 Z hierarchy.linkage(data,methodweighted,metric…