首頁  >  文章  >  web前端  >  使用three.js如何實現3D影院

使用three.js如何實現3D影院

亚连
亚连原創
2018-06-20 10:50:232412瀏覽

本篇文章主要跟大家講解如何透過three.js實現3D戲院的功能以及原理分析,需要的朋友參考一下吧。

本篇文章我們透過介紹3D影院的視覺原理,並介紹了three.js事件處理過程,全面分析了實現3D影院的基礎知識。

1.創造一個3d的空間

可以想像我們在房間內,房間是一個立方體,如果你有生活品味,可能會在房間內貼上壁紙,three.js可以很方便的創建一個立方體,並且給它的周圍貼上紋理,讓照相機在立方體之中,照相機可以360旋轉,就模擬了一個真實的場景。

轉換成代碼:

const path = 'assets/image/'
 const format = '.jpg'
 const urls = [
 `${path}px${format}`, `${path}nx${format}`,
 `${path}py${format}`, `${path}ny${format}`,
 `${path}pz${format}`, `${path}nz${format}`
 ]
 const materials = []
 urls.forEach(url => {
 const textureLoader = new TextureLoader()
 textureLoader.setCrossOrigin(this.crossOrigin)
 const texture = textureLoader.load(url)
 materials.push(new MeshBasicMaterial({
 map: texture,
 overdraw: true,
 side: BackSide
 }))
 })
 const cube = new Mesh(new CubeGeometry(9000, 9000, 9000), new MeshFaceMaterial(materials))
 this.scene.add(cube)

CubeGeometry創建一個超大的立方體MeshFaceMaterial給立方體貼上文理,由於視角是在立方體內部,所以side:BackSide 2.粒子效果

一個3d模型是由點,線,面組成的,可以遍歷模型的每一個點,把每一個點轉換為幾何模型,並且給它貼上文理,拷貝每一個點的位置,用這些幾何模型重新構成一個只有點的模型,這就是粒子效果的基本原理。

this.points = new Group()
 const vertices = []
 let point
 const texture = new TextureLoader().load('assets/image/dot.png')
 geometry.vertices.forEach((o, i) => {
 // 记录每个点的位置
 vertices.push(o.clone())
 const _geometry = new Geometry()
 // 拿到当前点的位置
 const pos = vertices[i]
 _geometry.vertices.push(new Vector3())
 const color = new Color()
 color.r = Math.abs(Math.random() * 10)
 color.g = Math.abs(Math.random() * 10)
 color.b = Math.abs(Math.random() * 10)
 const material = new PointsMaterial({
 color,
 size: Math.random() * 4 + 2,
 map: texture,
 blending: AddEquation,
 depthTest: false,
 transparent: true
 })
 point = new Points(_geometry, material)
 point.position.copy(pos)
 this.points.add(point)
 })
 return this.points

new Group建立一個群,可以說是粒子的集合透過point.position.copy(pos)設定粒子和位置,座標和模型中對應點的位置相同3.點擊事件的處理

three.js的點擊事件需要藉助光線投射器(Raycaster),為了方便理解,請先看一張圖:

Raycaster發射一個射線, intersectObject監測射線命中的物體

this.raycaster = new Raycaster()
// 把你要监听点击事件的物体用数组储存起来
this.seats.push(seat)

onTouchStart(event) {
 event.preventDefault()
 event.clientX = event.touches[0].clientX;
 event.clientY = event.touches[0].clientY;
 this.onClick(event)
 }

 onClick(event) {
 const mouse = new Vector2()
 mouse.x = ( event.clientX / this.renderer.domElement.clientWidth ) * 2 - 1
 mouse.y = - ( event.clientY / this.renderer.domElement.clientHeight ) * 2 + 1;
 this.raycaster.setFromCamera(mouse, this.camera)
 // 检测命中的座位
 const intersects = this.raycaster.intersectObjects(this.seats)
 if (intersects.length > 0) {
 intersects[0].object.material = new MeshLambertMaterial({
  color: 0xff0000
 })
 }
 }

intersects.length > 0 表示射線命中了某個幾何體偷懶只實現了移動端的點擊實現,如果想看pc怎麼實現,請看thee.js官網

4.著色器的初步使用

著色器分為頂點著色器和片元著色器,用GLSL語言編寫,是一種和GPU溝通的的語言,這裡只講如何使用

const vertext = `
 void main()
 {
 gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
 }
 `

const fragment = `
 uniform vec2 resolution;
 uniform float time;

 vec2 rand(vec2 pos)
 {
 return fract( 0.00005 * (pow(pos+2.0, pos.yx + 1.0) * 22222.0));
 }
 vec2 rand2(vec2 pos)
 {
 return rand(rand(pos));
 }

 float softnoise(vec2 pos, float scale)
 {
 vec2 smplpos = pos * scale;
 float c0 = rand2((floor(smplpos) + vec2(0.0, 0.0)) / scale).x;
 float c1 = rand2((floor(smplpos) + vec2(1.0, 0.0)) / scale).x;
 float c2 = rand2((floor(smplpos) + vec2(0.0, 1.0)) / scale).x;
 float c3 = rand2((floor(smplpos) + vec2(1.0, 1.0)) / scale).x;

 vec2 a = fract(smplpos);
 return mix(
 mix(c0, c1, smoothstep(0.0, 1.0, a.x)),
 mix(c2, c3, smoothstep(0.0, 1.0, a.x)),
 smoothstep(0.0, 1.0, a.y));
 }

 void main(void)
 {
 vec2 pos = gl_FragCoord.xy / resolution.y;
 pos.x += time * 0.1;
 float color = 0.0;
 float s = 1.0;
 for(int i = 0; i < 8; i++)
 {
 color += softnoise(pos+vec2(i)*0.02, s * 4.0) / s / 2.0;
 s *= 2.0;
 }
 gl_FragColor = vec4(color);
 }
 `
// 设置物体的质材为着色器质材
 let material = new ShaderMaterial({
 uniforms: uniforms,
 vertexShader: vertext,
 fragmentShader: fragment,
 transparent: true,
 })

5.光暈效果

由於是模擬電影院,我想做一個投影儀,模擬投影機射出的光線。

// 光晕效果必须设置alpha = true
 const renderer = this.renderer = new WebGLRenderer({alpha: true, antialias: true})

 let textureFlare = new TextureLoader().load(&#39;assets/image/lensflare0.png&#39;)
 let textureFlare3 = new TextureLoader().load(&#39;assets/image/lensflare3.png&#39;)
 let flareColor = new Color(0xffffff)
 let lensFlare = new LensFlare(textureFlare, 150, 0.0 , AdditiveBlending, flareColor)
 lensFlare.add(textureFlare3, 60, 0.6, AdditiveBlending);
 lensFlare.add(textureFlare3, 70, 0.7, AdditiveBlending);
 lensFlare.add(textureFlare3, 120, 0.9, AdditiveBlending);
 lensFlare.add(textureFlare3, 70, 1.0, AdditiveBlending);
 lensFlare.position.set(0, 150, -85)

上面是我整理給大家的,希望未來會對大家有幫助。

相關文章:

在mongoose中有關於更新物件的詳細介紹

在JS函數中有關setTimeout詳細介紹

使用jquery如何實作側邊欄左右伸縮效果

#在Vue中如何實作數位輸入框元件

在jquery中如何實作自訂顯示訊息數量

在Angular2中如何實作元件互動

在js中如何解決軟鍵盤遮擋輸入框

以上是使用three.js如何實現3D影院的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn