首页 > 编程知识 正文

基于threejs的3d框架,threejs 3d建模

时间:2023-05-04 21:59:02 阅读:114002 作者:685

Three.js的一些重要概念首先简要了解3D场景中不可缺少的三个元素,然后在后面的章节中详细介绍每个元素。

场景可以将场景视为沙盘。 你表现的物体需要把它放在场景里。

照相机,最终出现在屏幕上的影像,实际上可以站在照相机的角度看场景中的物体,将其视为我们的眼睛。

渲染器渲染器,我们有场景了。 然后,用相机捕获这个画面,如何在画面上显示这个画面是渲染器的工作。 形象说一点,比如我看到物体,把它画出来给你看,这幅画就相当于渲染的过程。

坐标系在three.js中使用右手坐标系。 右手坐标系是什么

一切与位置有关的东西,包括把东西放在场景里的位置,设置照相机的位置,都必须参考这个坐标系。

创建简单的3D场景1并引入Three.js 1。 首先在项目中安装依赖关系

NPM安装- -部署到需要创建保存树2.3 d场景的文件中

部署import * as THREE from 'three '不容易。 有些组件需要特别部署,但在使用时会介绍

初始化SimpleScene.js (以下所有代码都将写入此文件)。

导入react, { component } from ' react ' import * asthreefrom ' three ' exportdefaultclasssimplesceneextendscomponent { componentdididmount } init=()={ const scene=new THREE.Scene ) ) const camera=new three.perspective camera ) 75, window.innerwidth/windows 1000 ) const renderer=new three.webglrenderer () renderer.setsize ) window.innerwidth, window.innerHeight ) renderer camera (document.getelementbyid (stage ) ) appendchild ) this.} renderer.domelement ) rement

1 .创建场景实例scene,它是将物体放置在我们后面的空间

2 .创建透视相机的实例camera。 这取决于相机的特性。 3D场景中常用的是透视相机,四个参数分别如下:

fov (视角) :相机的视角(在相同距离处视角越大,可见的东西越多;物体在显示器上越小,aspect (纵横比) ) :渲染窗口的纵横比near (近截面距离) 333660

3 .创建渲染实例,并设置指示显示区域大小的宽度高度。 在这里,填充整个屏幕,然后设置要渲染的场景和摄影机,最后将渲染器放入页面的容器中

现在,3D场景所需的三个元素已初始化完毕,并运行了程序

我们得到了黑暗的空间,然后开始把东西放在里面

3 .放置网格模型的网格模型。 对于前述物体,网格模型也由几何体和材质组成

const geometry=new three.box geometry (1,1 ) const material=new three.meshbasicmaterial ) { color : ' red ' } color 这里的几何可以理解为只是骨架。 接下来,在这个骨架上贴上皮。 也就是说,创建材质。 现在,我们将创建红色基本材质,最后将骨架和皮组合在一起以创建立方体模型。 然后,可以将该模型放入场景中。 此时,运行程序,你会发现它还很暗。 这是因为相机的默认位置为[ 0,0,0 ],模型所在的默认中心位置也为[ 0,0,0 ]。 也就是说,现在照相机在模型内部,正在拉出照相机

在camera.position.z=3处可以看到红色的正方形

但是,这个看起来一点也不像3D。 这是因为我们现在看到的是立方体的正面,调整相机的位置,看起来像立方体

camera.position.set (3,3,3 ) )。

camera.lookAt(mesh.position)

就可以看到

有点3D的感觉了,但还是像2D的样子,差了阴影,要产生阴影,就必须有光。

4.设置灯光 const pointLight = new THREE.PointLight(0xffffff) pointLight.position.set(3,2,1) scene.add(pointLight)

为场景添加一个点光源,光的颜色是白色,刷新一下,发现还是这样,没有阴影

这是材质的问题,MeshBasicMaterial这种材质对光无感,这也是为啥刚才没有设置灯光的情况下,我们仍可以看到这个正方体,现在我们给正方体换一种皮

const material = new THREE.MeshPhongMaterial({color:'red'})


现在终于有3D的感觉了,画面偏暗,我们可以增加灯光的强度,或者增加一个环境光

const ambientLight = new THREE.AmbientLight(0xcccccc, 0.5) scene.add(ambientLight)

5.让正方体动起来

光看个图片也不够3D,下一步我们让正方体转起来

animate = () => { requestAnimationFrame(this.animate) this.mesh.rotation.y += 0.02 this.renderer.render(this.scene, this.camera) }

然后在初始化后调用,就可以看到正方体以y轴为轴心转起来了
​​​​​​

requestAnimationFrame(this.animate)

这一行代码的作用是使屏幕刷新时调用括号中的函数,这里的刷新指的是指屏幕刷新率的那个刷新,所以每次执行animate,正方体就会沿y轴旋转0.02个单位,如果电脑的刷新频率是60hz的话,一秒内这个函数执行60次,看起来正方体就转了起来,记得在旋转后调用

this.renderer.render(this.scene, this.camera)

不然只是修改了属性,没有渲染。

6.控制摄像机

光看着小正方体旋转还是不够3D,接下来我们将控制摄像机,全方位观察小正方体

首先需要引入轨道控制器,有了它我们就可以控制摄像机

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

在初始化的代码中,加上

const controls = new OrbitControls(this.camera, this.renderer.domElement) controls.addEventListener('change', this.handleControl) this.controls = controls

第一行,声明这个控制器是控制哪个摄像机,在哪个渲染器节点控制摄像机,第二行给控制器添加监听事件,每当我们使用鼠标拖拽或者滚轮时都会触发回调函数,回调函数相当简单:

handleControl = () => { this.renderer.render(this.scene, this.camera) }

这样我们就可以控制摄像机了,来看看效果,已经非常3D了,动画中移近摄像头的时候,正方体好像盖子要打开,这其实是因为正方体触碰到了近截面,前面说过,摄像机与近截面之间的不会被渲染,所以才会出现这种情况,可以把近截面距离给调小。

至此,我们的一个非常简单的3D场景就搭建完毕了。

全部代码 import React, { Component } from 'react'import * as THREE from 'three'import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'export default class SimpleScene extends Component { componentDidMount(){ this.init() this.animate() } init = () => { const scene = new THREE.Scene() this.scene = scene const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000) this.camera = camera const geometry = new THREE.BoxGeometry(1,1,1) const material = new THREE.MeshPhongMaterial({color:'red'}) const mesh = new THREE.Mesh(geometry, material) this.mesh = mesh scene.add(mesh) camera.position.set(3,3,3) camera.lookAt(mesh.position) const pointLight = new THREE.PointLight(0xffffff,1) pointLight.position.set(3,2,1) scene.add(pointLight) const ambientLight = new THREE.AmbientLight(0xcccccc, 0.5) scene.add(ambientLight) const renderer = new THREE.WebGLRenderer() renderer.setSize(window.innerWidth, window.innerHeight) renderer.render(scene, camera) this.renderer = renderer document.getElementById('stage').appendChild(renderer.domElement) const controls = new OrbitControls(this.camera, this.renderer.domElement) controls.addEventListener('change', this.handleControl) this.controls = controls } handleControl = () => { this.renderer.render(this.scene, this.camera) } animate = () => { requestAnimationFrame(this.animate) this.mesh.rotation.y += 0.02 this.renderer.render(this.scene, this.camera) } render() { return ( <div id="stage"> </div> ) }}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。