前言(大部分解释都在代码注释上边)

上一个主要说自己选择的web引擎和前置安装步骤,接着直接开荤,进入正文。
本人的代码大部分都很简单,方便自己看,也方便各位同学们学习,所以不要吐槽。

个人认为:threejs相对webgl来说最方便的是什么?它把webgl那些复杂的点、线、面等等封装成一个个组件,如果不做非常非常精细化的场景,对于展示物体,一些web端三维可视化项目之类的完全够用了。

那么这篇就简单搭建一个场景,效果如下图:

一、场景scene:

首先,场景scene是什么?想要容纳物体,就要先开辟一方空间,而场景scene就相当于这一方空间,有了这一方空间,才能在这方空间里创造物体。

//页面上创建一个div用来盛放threejs的空间,执行渲染renderer之后会有一个canvas填充到这个div里
<div id="threecanvas"></div>
//首先引入threejs的基础库
import * as THREE from 'three'

1.创建场景

var scene
// 初始化场景
function initScene() {// 实例化一个场景scene = new THREE.Scene()// 整个场景的颜色scene.background = new THREE.Color( 0x000000 )
}

2.天空盒子

// 天空盒是以正方体6面结构贴图[贴图顺序:右、左、上、下、前、后]
var urls = ['./static/skyBox/day/px.jpg','./static/skyBox/day/nx.jpg','./static/skyBox/day/py.jpg','./static/skyBox/day/ny.jpg','./static/skyBox/day/pz.jpg','./static/skyBox/day/nz.jpg'
]
//初始化一个场景
function initScene() {// 实例化一个场景scene = new THREE.Scene()// 整个场景的颜色scene.background = new THREE.Color( 0x000000 )// 6图天空盒子[贴图顺序:右、左、上、下、前、后]scene.background = new THREE.CubeTextureLoader().load(urls)
}

二、相机camera:

相机相当于人的眼睛,用于看到展示在视野内的物体。

var camera
// 初始化相机
function initCamera() {//实例化一个相机,内部参数(角度,div的宽/div的高,距离视野中心最近距离,同前最远距离)//角度:类似于手机狭角、广角的效果//画面比例:div的宽高自己定义,全屏展示的话就按照官网给的window.innerWidth/window.innerHeight即可//视野最大(小)远近距离根据自身项目来定camera = new THREE.PerspectiveCamera(60,document.getElementById('threecanvas').offsetWidth / document.getElementById('threecanvas').offsetHeight, 2, 5000)camera.position.set(0, 100, -100)//相机位置camera.lookAt(new THREE.Vector3(0, 0, 0))// 相机视野中心//相机所展示画面的比例camera.aspect = document.getElementById('threecanvas').offsetWidth / document.getElementById('threecanvas').offsetHeight//更新相机投影变换矩阵camera.updateProjectionMatrix()//将相机加入到场景中scene.add(camera)
}

三、渲染器renderer:

渲染器,顾名思义,就是把这个三维空间渲染到web页面上,前边我在页面上加了id为threecanvas的div便签,那我可以把场景渲染到threejscanvas里。

var renderer
// 初始化渲染器
function initRenderer() {renderer = new THREE.WebGLRenderer({alpha: false,// 是否可以设置背景色透明antialias: true, // 抗锯齿logarithmicDepthBuffer: true, // 图层叠加闪烁问题precision: 'lowp', // 着色器精度preserveDrawingBuffer: true, // 开启图层缓冲区autoClear: true})renderer.setPixelRatio(window.devicePixelRatio)// 设置分辨率与电脑的分辨率相同renderer.setSize(document.getElementById('threecanvas').offsetWidth, document.getElementById('threecanvas').offsetHeight)renderer.shadowMap.enabled = true// 渲染器渲染阴影效果renderer.shadowMap.type = THREE.PCFSoftShadowMap// 阴影类型renderer.outputEncoding = THREE.sRGBEncoding// 色域,鲜明渲染,常规rgb颜色渲染// 把这个canvas渲染到指定div里,不指定div则把setSize指定宽高document.getElementById('threecanvas').appendChild(renderer.domElement)
}

四、控制器controls:

控制器,就是可以使用鼠标or键盘控制三维场景旋转等交互操作,变换视角,以达到三维效果,否则的话,web页面上渲染出来的只能算作平面三维物体2.5D,只有立体感,俗话说只能看,不能交互,意义不大。

//控制器需要引入控制器插件
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
var controls
// 初始化控制器
function initControls() {controls = new OrbitControls(camera, renderer.domElement)controls.listenToKeyEvents(window)//监听操作,具体有哪些可以去底层扒一扒controls.enableDamping = true// 开启控制阻尼,是否有惯性controls.dampingFactor = 0.05 // 阻尼强度,鼠标拖拽旋转灵敏度controls.enableZoom = true// 是否可以缩放controls.minDistance = 2// 相机距离原点最近距离controls.maxDistance = 1000// 相机距离原点最远距离controls.enablePan = true // 是否开启右键拖拽controls.maxPolarAngle = Math.PI / 2.05 // 最大角度,实际项目中一些模型限制视角到地下controls.screenSpacePanning = false //false时只能前后左右平移,不能上下平移,true时哪个方向都可以controls.target = new THREE.Vector3(0, 0, 0)// 设置控制器的旋转原点
}
// 更新,实时渲染的时候加进去,有控制交互,就渲染
function update() {controls.update()
}

五、光源light:

前边我创建好了场景、相机、渲染器、控制器,还有一个天空盒,这个时候场景中没有光源,什么都看不到,所以需要光源来照亮物体。

//这里我主要使用,环境光和平行光
//环境光是自然环境中全局的光线
//平行光是方向光类似于太阳光,主要用来模拟阴影
var ambient, directional
// 光源
function initLight() {// 环境光AmbientLight,影响整个场景的光源ambient = new THREE.AmbientLight(0xffffff, 1)ambient.name = '环境光'scene.add(ambient)// 平行光DirectionalLight,模拟太阳光,用于渲染阴影directional = new THREE.DirectionalLight(0xffffff, 1.2, 100) // 模拟远处类似太阳的光源directional.name = '平行光'directional.position.set(directionalx1, directionaly1, directionalz1)directional.castShadow = true// 告诉平行光需要开启阴影投射directional.shadowDarkness = 1directional.shadow.mapSize.width = 512 * 4// 阴影分辨率,默认512directional.shadow.mapSize.height = 512 * 4// 平行光范围directional.shadow.camera.left = -directionalvaluedirectional.shadow.camera.right = directionalvaluedirectional.shadow.camera.top = directionalvaluedirectional.shadow.camera.bottom = -directionalvaluedirectional.shadow.camera.near = 0.5directional.shadow.camera.far = 1500directional.shadow.bias = 0.0001// 阴影偏移,否则会有阴影锯齿出现,阴影条纹,嗯写过的人应该都遇到过,很恶心的东西,可以用这个bias稍作偏移,具体参数调整起来比较烦scene.add(directional)// 平行光辅助线,添加辅助线后可以看到平行光笼罩的范围,用于细节调整const directionalhelper = new THREE.CameraHelper(directional.shadow.camera)directionalhelper1.visible = true// 平时不用,注掉这个addscene.add(directionalhelper)
}

六、初始化所有组件:

创建一个函数,把所有组件放进去一起加载,这么写呢,主要是方便后期增补或者修改一些内容,这么做比较方便,毕竟商务和产品每次都说这个东西三天或者五天必须给出来,写的太乱了后期不好改。

// 初始化
function init() {initScene()// 基础场景initCamera()// 相机initRenderer()// 渲染器initControls()// 控制器initLight()// 光源
}
init()//直接执行,或者HTML直接加onload

七、渲染:

// 循环渲染页面场景
function render() {update()requestAnimationFrame(render)// 执行一个动画.并在动画执行后重新渲染// 传统渲染器,如果使用shader着色器,则注掉这个,增加效果合成器,增加通道渲染renderer.render(scene, camera)
}

八、测试网格:

var grid
function initGrid(){grid = new THREE.GridHelper( 300, 8, 0xffffff, 0xffffff );grid.position.set(0,-5,0)scene.add( grid );
}

九、完整代码:

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'var scene, camera, controls, renderer, ambient, directional,grid// 天空盒是以正方体6面结构贴图[贴图顺序:右、左、上、下、前、后]
var urls = ['./static/skyBox/day/px.jpg','./static/skyBox/day/nx.jpg','./static/skyBox/day/py.jpg','./static/skyBox/day/ny.jpg','./static/skyBox/day/pz.jpg','./static/skyBox/day/nz.jpg'
]
//初始化一个场景
function initScene() {// 实例化一个场景scene = new THREE.Scene()// 整个场景的颜色scene.background = new THREE.Color( 0x000000 )// 6图天空盒子[贴图顺序:右、左、上、下、前、后]scene.background = new THREE.CubeTextureLoader().load(urls)
}
// 初始化相机
function initCamera() {//实例化一个相机,内部参数(角度,div的宽/div的高,距离视野中心最近距离,同前最远距离)//角度:类似于手机狭角、广角的效果//画面比例:div的宽高自己定义,全屏展示的话就按照官网给的window.innerWidth/window.innerHeight即可//视野最大(小)远近距离根据自身项目来定camera = new THREE.PerspectiveCamera(60,document.getElementById('threecanvas').offsetWidth / document.getElementById('threecanvas').offsetHeight, 2, 5000)camera.position.set(0, 100, -100)//相机位置camera.lookAt(new THREE.Vector3(0, 0, 0))// 相机视野中心//相机所展示画面的比例camera.aspect = document.getElementById('threecanvas').offsetWidth / document.getElementById('threecanvas').offsetHeight//更新相机投影变换矩阵camera.updateProjectionMatrix()//将相机加入到场景中scene.add(camera)
}
// 初始化渲染器
function initRenderer() {renderer = new THREE.WebGLRenderer({alpha: false,// 是否可以设置背景色透明antialias: true, // 抗锯齿logarithmicDepthBuffer: true, // 图层叠加闪烁问题precision: 'lowp', // 着色器精度preserveDrawingBuffer: true, // 开启图层缓冲区autoClear: true})renderer.setPixelRatio(window.devicePixelRatio)// 设置分辨率与电脑的分辨率相同renderer.setSize(document.getElementById('threecanvas').offsetWidth, document.getElementById('threecanvas').offsetHeight)renderer.shadowMap.enabled = true// 渲染器渲染阴影效果renderer.shadowMap.type = THREE.PCFSoftShadowMap// 阴影类型renderer.outputEncoding = THREE.sRGBEncoding// 色域,鲜明渲染,常规rgb颜色渲染// 把这个canvas渲染到指定div里,不指定div则把setSize指定宽高document.getElementById('threecanvas').appendChild(renderer.domElement)
}
// 初始化控制器
function initControls() {controls = new OrbitControls(camera, renderer.domElement)controls.listenToKeyEvents(window)//监听操作,具体有哪些可以去底层扒一扒controls.enableDamping = true// 开启控制阻尼,是否有惯性controls.dampingFactor = 0.05 // 阻尼强度,鼠标拖拽旋转灵敏度controls.enableZoom = true// 是否可以缩放controls.minDistance = 2// 相机距离原点最近距离controls.maxDistance = 1000// 相机距离原点最远距离controls.enablePan = true // 是否开启右键拖拽controls.maxPolarAngle = Math.PI / 2.05 // 最大角度,实际项目中一些模型限制视角到地下controls.screenSpacePanning = false //false时只能前后左右平移,不能上下平移,true时哪个方向都可以controls.target = new THREE.Vector3(0, 0, 0)// 设置控制器的旋转原点
}
// 更新,实时渲染的时候加进去,有控制交互,就渲染
function update() {controls.update()
}
// 光源
function initLight() {// 环境光AmbientLight,影响整个场景的光源ambient = new THREE.AmbientLight(0xffffff, 1)ambient.name = '环境光'scene.add(ambient)// 平行光DirectionalLight,模拟太阳光,用于渲染阴影directional = new THREE.DirectionalLight(0xffffff, 1.2, 100) // 模拟远处类似太阳的光源directional.name = '平行光'directional.position.set(directionalx1, directionaly1, directionalz1)directional.castShadow = true// 告诉平行光需要开启阴影投射directional.shadowDarkness = 1directional.shadow.mapSize.width = 512 * 4// 阴影分辨率,默认512directional.shadow.mapSize.height = 512 * 4// 平行光范围directional.shadow.camera.left = -directionalvaluedirectional.shadow.camera.right = directionalvaluedirectional.shadow.camera.top = directionalvaluedirectional.shadow.camera.bottom = -directionalvaluedirectional.shadow.camera.near = 0.5directional.shadow.camera.far = 1500directional.shadow.bias = 0.0001// 阴影偏移,否则会有阴影锯齿出现,阴影条纹,嗯写过的人应该都遇到过,很恶心的东西,可以用这个bias稍作偏移,具体参数调整起来比较烦scene.add(directional)// 平行光辅助线,添加辅助线后可以看到平行光笼罩的范围,用于细节调整const directionalhelper = new THREE.CameraHelper(directional.shadow.camera)directionalhelper1.visible = true// 平时不用,注掉这个addscene.add(directionalhelper)
}
//网格
function initGrid(){grid = new THREE.GridHelper( 300, 8, 0xffffff, 0xffffff );grid.position.set(0,-5,0)scene.add( grid );
}
// 初始化
function init() {initScene()// 基础场景initCamera()// 相机initRenderer()// 渲染器initControls()// 控制器initLight()// 光源initGrid()//网格
}
// 循环渲染页面场景
function render() {update()requestAnimationFrame(render)// 执行一个动画.并在动画执行后重新渲染// 传统渲染器,如果使用shader着色器,则注掉这个,增加效果合成器,增加通道渲染renderer.render(scene, camera)
}
init()
render()

个人写的vue,分开function函数,原生HTML和vue都能用,包括小程序,可以单独把代码提取成js,使用export{…}导出属性或方法函数,直接在页面import引入即可。
正好今天又修改模型改动代码,重构的时候把代码扣出来,一边整合代码,一边写博客,可能时间有限,写的比较拉。

WEB端三维可视化(threejs)02相关推荐

  1. WEB端三维可视化(threejs)01

    WEB端三维可视化(初识)threejs01 前言 一.初识 二.nodejs 三.引入threejs库 前言 记录一下学习笔记 一.初识 一年前从网上爬了个web端的三维demo,从此接触到了一个新 ...

  2. WEB端三维可视化(threejs)03

    前言 上一篇主要写了如何创建一个场景,本篇写一下模型加载方面的细节. 目前threejs支持的模型格式有很多,gltf/glb.obj+mtl.fbx.dea等等- 主要推荐的模型格式:obj+mtl ...

  3. Web端3D可视化引擎HOOPS Communicator读取10G超大模型测试 | 数字孪生技术

    前言: HOOPS Communicator是专为在云端和Web上构建工程应用程序的3D开发工具包.它针对Web工作流.浏览器和工程图形进行了优化.研发小组花了20多年的时间来研发HOOPS Visu ...

  4. 阿里云物联网平台web端,可视化开发,简单实例

    Web可视化 阿里云物联网平台提供了一种可快速开发的web服务,只需要拖入一些控件,做一些配置就可以完成一个简单的物联网web应用,对单一场景,需求简单的项目非常实用. 首先进入物联网平台,打开开发者 ...

  5. web端的shader Threejs飞线

    目标 之前想用粒子来实现一下飞线的效果,看到很多大佬的代码发现使用粒子会是一个不错的选择,因为粒子的渲染比较省性能,之前看到有人使用圆形的粒子 后来发现其实普通的正方形的粒子就行,因为在线的粗度比较小 ...

  6. Web 端的下一代三维图形

    原文地址:Next-generation 3D Graphics on the Web 原文作者:Dean Jackson 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gol ...

  7. WEB端显示三维地形模型

    注:正常在WEB上显示三维地形首选Cesium,本文内容仅作为研究,展示文章用DEM制作通用三维地形模型中制作的局部三维地形模型 Cesium是可以很容易的实现在WEB端三维地形的,下面的图是分别是使 ...

  8. Vue常用的组件库大全【前端工程师必备】【实时更新】【移动端、PC端(web端)、数据可视化组件库(数据大屏) 、动画组件库、3D组件库】

    Vue常用的组件库大全[前端工程师必备] (一)移动端 常用组件库 1)Vant ui 2)Cube UI 3)VUX 4) NuTUI 5)Mint ui 6)Varlet UI 7)OnsenUI ...

  9. Axure高保真智慧消防远程监管系统数据可视化大屏看板+web端高保真大数据分析平台看板+大数据交换配置管理平台大屏动态可视化看板

    作品介绍:Axure高保真智慧消防远程监管系统数据可视化大屏看板+web端高保真大数据分析平台看板+大数据交换配置管理平台大屏动态可视化看板 原型交互及下载链接:https://www.pmdaniu ...

最新文章

  1. cli/c++与C#比较之我见
  2. redis和kafka读取代码
  3. ubuntu 14.04下 horizon openstack_dashboard 的开发环境搭建
  4. .NET轻量级配置中心AgileConfig
  5. spring jpa 流式_从响应式Spring Data存储库流式传输实时更新
  6. 防止System.exit调用
  7. 西门子主程序调用子程序_S7200Smart 子程序局部变量使用教程
  8. 数据概览_2015年概览:开源年鉴
  9. 一台手机苹果含泪赚4000?iPhone 12硬件成本曝光
  10. 【Kafka】Failed to send data to Kafka: Expiring 30 record(s) for xxx 732453 ms has passed since last a
  11. linux 强行安装软件,Linux下强制不检测依赖安装VNC
  12. 手机上有没有学python的软件-盘点几个在手机上可以用来学习编程的软件
  13. lua_shared_dict的incr方法
  14. 高效程序员秘籍(9):快速查找硬盘上的文件和目录
  15. 耒阳计算机学校,耒阳县系统分析师_科泰计算机学校
  16. 录屏软件推荐:bilibili哔哩哔哩直播姬录屏软件下载使用指南
  17. 视频教程-网络工程师的5天修炼-软考
  18. 推广TrustAI可信分析:通过提升数据质量来增强在ERNIE模型下性能
  19. 警告: Establishing SSL connection without server
  20. Ps 的模板文件格式 PSDT

热门文章

  1. 74HC595芯片实现原理及跑马灯数码管应用程序-----day2
  2. PAT乙级 1016 部分A+B
  3. windterm主密码关闭
  4. win10系统上装win11系统解决方案,亲测成功
  5. 安卓手机系统安装虚拟机
  6. Nexus 5 Android 6.0.1刷机、Root
  7. 迈向可验证的 AI: 形式化方法的五大挑战
  8. 啃完阿里这份高并发编程核心笔记,反手涨了 5K
  9. 看完以后就不会混淆啦,靠理解去区别substr, substring, slice,splice, split方法
  10. 前台项目20鼠标移入背景颜色改变