使用three.js创建交互式3D视觉效果

null

这个WebGL教程演示了如何创建一个3D环境模拟,显示二氧化碳水平变化时世界会发生什么。 (你可以看到更多WebGL实验这里。)

用户使用HTML输入范围滑块控制级别。随着用户增加更多的二氧化碳,场景中会出现更多的烟雾,随着温度的升高融化更多的极地冰盖,水位会上升,然后当树木浸入水中时树木就会消失。

使用补间库对元素进行动画处理和输出,并沿相反方向拖动滑块将反转效果。如果只是在现实生活中那么容易!

01.显示元素

The basic layout of the page is shown here before the  3D scene has been added. The image is a transparent  PNG at the top of the screen and there is a range slider at the bottom

在添加3D场景之前,此处显示页面的基本布局。图像是屏幕顶部的透明PNG,底部有一个范围滑块

要启动项目,请在代码IDE中打开“start”文件夹。打开的index.html你会看到有一个基本的页面脚手架已经有了一些代码。在body部分中,在此处添加将用作3D内容界面的显示元素。

拖动滑块改变二氧化碳的水平

02.链接图书馆

3D内容通过three.js显示,包含在此处。 Collada模型将在稍后添加到场景中。包括要加载它的额外库,以及基本的补间库。下一行所有链接到后处理效果,将添加精加工抛光。

      

03.后处理着色器

在场景渲染完每个帧之后,将添加许多后期处理效果。这些是赋予胶片颗粒效果的图书馆,屏幕顶部和底部的倾斜移位模糊,最后是一个小插图,淡出到屏幕的边缘。

04.添加变量

部分代码已经为您完成。您将看到一条注释,其中添加了教程代码的其余部分。在这个3D场景中使用了许多变量,它们负责屏幕分辨率,各种3D模型和后期处理。两个重要的变量是WaterHt对于水的高度和LastVal,它会记住滑块的最后位置。

var SCREEN_WIDTH = window.innerWidth,SCREEN_HEIGHT = window.innerHeight,mouseX = 0,mouseY = 0,windowHalfX = window.innerWidth / 2,windowHalfY = window.innerHeight / 2,camera,scene,renderer,water,waterHt = 1; var textureLoader = new THREE.TextureLoader(); var composer,shaderTime = 0,filmPass,renderPass,copyPass,effectVignette,group,lastVal = 0;

05.初始化场景

Init函数是代码的很大一部分,确保在开头设置正确的场景。一个容器被添加到页面,这是3D场景的显示位置。添加了一个摄像头和一些背景雾来淡出距离。

function init(){var container = document.createElement('div'); document.body.appendChild(容器); camera = new THREE.PerspectiveCamera(75,SCREEN_WIDTH / SCREEN_HEIGHT,1,10000); camera.position.set(2000,100,0); scene = new THREE.Scene(); scene.fog = new THREE.FogExp2(0xb6d9e6,0.0025); renderer = new THREE.WebGLRenderer({antialias:true});

06.设置渲染器

渲染器被赋予背景颜色,并且分辨率被设置为与屏幕的像素比相同的大小。场景中启用了阴影,并将其放置在容器元素的页面上。添加半球灯,具有天空和地面颜色。

renderer.setClearColor(0xadc9d4); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(SCREEN_WIDTH,SCREEN_HEIGHT); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; container.appendChild(renderer.domElement); var light = new THREE.HemisphereLight(0xa1e2f5,0x6f4d25,0.5); scene.add(光);

07.着色器变量

将控制着色器后期处理效果的变量在此处给出它们的值。稍后将使用这些变量来添加将控制外观的值。如果你查看params函数,你会发现这已经完成了。

renderPass = new THREE.RenderPass(场景,相机); hblur = new THREE.ShaderPass(THREE.HorizontalTiltShiftShader); vblur = new THREE.ShaderPass(THREE.VerticalTiltShiftShader); filmPass = new THREE.ShaderPass(THREE.FilmShader); effectVignette = new THREE.ShaderPass(THREE.VignetteShader); copyPass = new THREE.ShaderPass(THREE.CopyShader);

08.组合效果

效果必须叠加在一个叫做效果作曲家的东西上。这会产生每种效果并将样式应用于它。然后它全部显示为屏幕上的最终场景,稍后添加渲染功能时您将看到它。

09.加载云图像

The params() function is called in step 9, which sets  the parameters for the post processing vignette and film grain effect

在步骤9中调用params()函数,该函数设置后处理晕影和胶片颗粒效果的参数

PARAMS调用函数,这将设置后期效果的各个参数。创建一个新组,它将保存其中的所有场景内容,以便轻松旋转对象组。将透明PNG图像作为云材料加载,以用作场景内的精灵。

PARAMS(); group = new THREE.Group(); scene.add(基); var cloud = textureLoader.load(“img / cloud.png”); material = new THREE.SpriteMaterial({map:cloud,opacity:0.6,color:0x888888,fog:true});

10.双循环

在第一组内创建了八组对于环。这八个组在第二个for循环中都添加了35个云。每个云都放置在场景上方的随机位置。用户可以使用滑块打开和关闭组,以显示可视化中添加和删除的烟雾。

for(j = 0; j <8; j ++){var g = new THREE.Group(); for(i = 0; i <35; i ++){var x = 400 * Math.random() -  200; var y = 60 * Math.random()+ 60; var z = 400 * Math.random() -  200; sprite = new THREE.Sprite(material); sprite.position.set(x,y,z);

11.扩展云

The first group of clouds can be seen in the scene. The others are hidden and will be visible when controlled from the slider by the user

可以在场景中看到第一组云。其他是隐藏的,并且在用户从滑块控制时将可见

云被放大到允许它在场景中可见的大小。第一组之后的每组云都按比例缩小,以使它们对渲染器几乎不可见。这是通过将它们缩小到完整尺寸后可以看到它们的方式,因为这将产生良好的补间效果。

12.加载模型

现在Collada Loader设置为加载Scene.dae模型。当它完成加载时,扫描模型并使任何恰好是网格的对象投射阴影并接收阴影以给场景提供一些额外的深度。

var loader = new THREE.ColladaLoader(); loader.options.convertUpAxis = true; loader.load('scene.dae',function(collada){var dae = collada.scene; dae.traverse(function(child){if(child instanceof THREE.Mesh){child.castShadow = true; child.receiveShadow = true;}});

13.在场景中找到具体细节

当模型现在可以显示时,它被设置为适合场景的正确尺寸。代码需要专门控制水的高度,以便在场景中找到水模型并将其传递到全局变量中。类似地,需要找到主光源,以便可以将其设置为投影阴影。

dae.scale.x = dae.scale.y = dae.scale.z = 0.5; dae.updateMatrix(); group.add(DAE); water = scene.getObjectByName(“Water”,true); water = water.children [0]; light = scene.getObjectByName(“SpLight”,true); light = light.children [0];

14.灯光设置

The model has been added with the main light set to emit shadows onto the scene. There is something substantial to look at in the scene so the tilt shift blur effect can be seen at the front and back of the scene

该模型已添加主光源设置,以在场景上发出阴影。在场景中有一些重要的东西可以看到,因此可以在场景的正面和背面看到倾斜移位模糊效果

现在,随着聚光灯的发现,设置了将阴影投射到场景中的细节。此处还设置了光点边缘的光线褪色。最后,由于模型是加载的最大元素,因此在运行此代码之前将设置场景的其余部分,因此可以在每个帧中调用渲染函数。

light.target.position.set(0,0,0); light.castShadow = true; light.shadow = new THREE.LightShadow(new THREE.PerspectiveCamera(90,1,90,5000)); light.shadow.bias = 0.0008; light.shadow.mapSize.width = 1024; light.shadow.mapSize.height = 1024; light.penumbra = 1; light.decay = 5;渲染(); });

15.上次初始化代码

With the mouse and touch events set up, the scene becomes reactive to the mouse movement, zooming in and out while being able to tilt the scene up and down

设置鼠标和触摸事件后,场景会对鼠标移动产生反应,放大和缩小,同时可以上下调整场景

Init函数的最后一部分设置了各种鼠标和触摸输入,这些输入将根据摄像机的位置移动摄像机。还会注册一个事件来监听屏幕是否已调整大小,这将更新渲染的显示。

document.addEventListener('mousemove',onDocumentMouseMove,false); document.addEventListener('touchstart',onDocumentTouchStart,false); document.addEventListener('touchmove',onDocumentTouchMove,false); window.addEventListener('resize',onWindowResize,false); }

16.渲染每个帧

渲染功能被设置为在浏览器可以管理的情况下被调用为接近每秒60帧。包含所有模型的组被设置为每帧旋转少量。相机的位置从鼠标或触摸输入更新,并继续查看场景的中心。

17.更新显示

着色器时间是一个变量,每帧上升0.1,这将被传递到FilmPass这样可以更新噪音薄膜颗粒。效果作曲家会更新并渲染到屏幕上。最后,补间引擎也会更新。

shaderTime + = 0.1; filmPass.uniforms ['time']。value = shaderTime; composer.render(0.1); TWEEN.update(); }

18.获得用户输入

在步骤1中添加的输入范围滑块调用ShowVal功能,在此定义。当用户点击它时,它只检查滑块是否已被移动。如果它向上移动,那么下一个云组将使用补间超过0.8秒进行扩展。水的高度会更新,并且这也会被调整到新的高度。

function showVal(val){if(val!= lastVal){if(val> lastVal){new TWEEN.Tween(group.children [val] .scale).to({x:1,y:1,z:1 },800).easing(TWEEN.Easing.Quadratic.InOut).start(); waterHt + = 0.07; new TWEEN.Tween(water.scale).to({y:waterHt},800).easing(TWEEN.Easing.Quadratic.InOut).start();

19.抓树

Temp变量查找它应该从场景中消除的当前树组,并在此处仅使用y轴上的补间向下缩放它们。使用弹性缓和,使其在屏幕上看不见,以获得令人愉悦的效果。随着场景中更多的水和云,树木消失了。

20.相反的意见

如果滑块向上滑动或向右滑动,则检查第一个内容。现在代码检测到用户向左滑动。云层按照补间缩小,水位也显示出对地球的冷却效果。

new TWEEN.Tween(group.children [lastVal] .scale).to({x:0.001,y:0.001,z:0.001},800).easing(TWEEN.Easing.Quadratic.InOut).start(); waterHt  -  = 0.07; new TWEEN.Tween(water.scale).to({y:waterHt},800).easing(TWEEN.Easing.Quadratic.InOut).start();

21.完成

With everything working, you can see the background fog clearly as you move the mouse so that the camera gets a higher vantage point on the scene

一切正常,您可以在移动鼠标时清楚地看到背景雾,以便相机在场景中获得更高的有利位置

最后一步是将树木带回来,这样它们就可以通过弹性补间缩小到原来的大小。保存场景并从本地托管在您自己的计算机或Web服务器上的服务器查看网页。您将能够与鼠标移动和滑块进行交互以更改场景显示。

这篇文章最初出现在网页设计者问题265.买这里

相关文章:



翻译字数超限