跳到主要内容

如何利用WebGL创建液体效果

Liquid effect Creative Bloq logo

+$Many web designers look for ways to add a big impact to their site designs, so that they'll grab the attention of their users. Methods have evolved over the years, from using a header graphic, to placing a slideshow under the landing page menu, to becoming full browser width – and now the vast majority of sites follow this same format.

+$Today, the designs that win 'site of the day' on different web awards sites generally try and do something that's a little more unique, and WebGL is great for this. Adding an interactive element can really grab users' attention and show that this isn't the same as the other sites they've just visited. It makes a site much more interesting than just having a giant slideshow and some视差滚动

+$To make a splash effect in this tutorial, a liquid, reflective surface will be added, and this will be animated towards the camera with rolling waves moving forward. There will also be particles that move forward to complete the look and feel. In the centre will be the site's logo, and the whole scene will react to the user's mouse movement so that the content shifts and makes the 3D really stand out.

标志设计被渲染为透明的PNG,因此可以根据您自己的设计轻松定制。灯光也会生成动画,以便颜色围绕轨道运行并突出场景中的不同波浪。

下载文件本教程。

+$01. Add Initial Variables

+$Open the start folder from the project files and drag this into your code editor. Open '的index.html+$' and you will see that the JavaScript libraries have already been linked up for you. Inside the empty script tags is where the code will go. Here WebGL is detected to make sure the project can be run, then a whole range of variables are added that will be used in the scene.

if(!Detector.webgl)Detector.addGetWebGLMessage(); var SCREEN_WIDTH = window.innerWidth; var SCREEN_HEIGHT = window.innerHeight; var renderer,camera,scene,moverGroup,floorGeometry,floorMaterial,pointLight,pointLight2,pGeometry; var FLOOR_RES = 60; var FLOOR_HT = 650; var stepCount = 0; var noiseScale = 9.5; var noiseSeed = Math.random()* 100;

+$02. Create More Variables

下一个变量块处理水底应该有多大以及它与初始鼠标位置一起移动的速度。屏幕的中心已经完成,改进的噪声库正在用于创建水面。

var FLOOR_WIDTH = 3600; var FLOOR_DEPTH = 4800; var MOVE_SPD = 1.9; var mouseX = 0; var mouseY = 0; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; var snoise = new ImprovedNoise(); var textureLoader = new THREE.TextureLoader();

+$03. Calculate The Mouse

为场景的后期处理效果添加了一些最终变量。添加了一个检查鼠标移动的事件监听器。场景将在显示端口移动以对鼠标移动作出反应。此处添加的功能可计算出允许的移动量。

+$04. Change post processing settings

+$The 'PARAMS+$' function is where all the settings for the post processing effects will be stored. If you need to change anything, this is the place to do it. The tilt shift blur is covered in the first four lines, then the film pass in the remaining lines. This is mainly for the screen intensity and noise intensity.

+$05. Set Final Parameters

+$The last of the parameters is for the dark vignette around the edge of the screen. The '在里面'和'+$animate+$' functions are called to run. The '+$animate+$' function will be created much later in the tutorial, but the '在里面+$' function is created here. The camera and scene are set up to allow viewing of the 3D content.

effectVignette.uniforms [“offset”]。value = 1.0; effectVignette.uniforms [“darkness”]。value = 1.3; } 在里面();动画(); function init(){camera = new THREE.PerspectiveCamera(70,window.innerWidth / window.innerHeight,1,4000); camera.position.z = 2750; scene = new THREE.Scene(); scene.fog = new THREE.FogExp2(0x1c3c4a,0.00045);

+$06. Let the light in

为了看到场景的内容,将放置四个灯。第一个是半球灯,用于获得场景的基本氛围。接下来是在场景中间添加浅蓝色光的中心灯。这是为了给整个场景提供一些亮光。

var hemisphereLight = new THREE.HemisphereLight(0xe3feff,0xe6ddc8,0.7); scene.add(hemisphereLight); hemisphereLight.position.y = 300; var centerLight = new THREE.SpotLight(0xb7f9ff,1); scene.add(centerLight); centerLight.position.set(2500,300,2000); centerLight.penumbra = 1; centerLight.decay = 5;

+$07. Animate Lights

+$The next two lights to be added. '+$PointLight'和'+$PointLight2+$' are coloured lights that will circle in opposite directions around the scene so that the light changes constantly in the view. The first is a pink light and the second is an orange light. The path and format for the reflection images are set in the last two lines.

pointLight = new THREE.PointLight(0xe07bff,1.5); pointLight.position.z = 200; scene.add(POINTLIGHT); pointLight2 = new THREE.PointLight(0xff4e00,1.2); pointLight2.position.z = 200; scene.add(pointLight2); var path =“img /”; var format ='.jpg';

08.有光泽的表面

+$The liquid surface will have a reflective, shiny surface and this is done by creating a reflection cube. This is a cube with a 360-degree skybox placed inside it, which will be reflected onto the surface of the liquid. The '+$urls+$' array contains the images to be loaded, then the material is set up.

+$09. Set up some groups

+$The mover group will contain some particles that will be added later, while the floor group will contain the surface of the liquid. A new 3D object is created that will hold that surface. There will be two liquid surfaces; one will have the reflective material and the second will have the wireframe '+$floorMaterial+$', as defined here.

moverGroup = new THREE.Object3D(); scene.add(moverGroup); var floorGroup = new THREE.Object3D(); var floorMaterial = new THREE.MeshPhongMaterial({color:0xeeeeee,side:THREE.DoubleSide,blend:THREE.AdditiveBlending,wireframe:true}); floorGeometry = new THREE.PlaneGeometry(FLOOR_WIDTH + 1200,FLOOR_DEPTH,FLOOR_RES,FLOOR_RES);

+$10. Make The Surfaces

Create liquid effects: make the surface

当添加第一个液体表面时,反射贴图非常明显,雾有助于将背景和表面混合在一起

+$The two liquid surfaces are created here as '+$floorMesh'和'+$floorMesh2+$'. They are positioned and placed inside the '+$floorGroup+$' then rotated to a good viewing angle in front of the camera. This isn't directly flat, but slightly angled as it looks better like that.

var floorMesh = new THREE.Mesh(floorGeometry,cubeMaterial); var floorMesh2 = new THREE.Mesh(floorGeometry,floorMaterial); floorMesh2.position.y = 20; floorMesh2.position.z = 5; floorGroup.add(floorMesh); floorGroup.add(floorMesh2); scene.add(floorGroup); floorMesh.rotation.x = Math.PI / 1.65; floorMesh2.rotation.x = Math.PI / 1.65; floorGroup.position.y = 180;

+$11. Add Floating Particles

Create liquid effects: add floating particles

浮动粒子填充场景,当所有这些都在渲染功能中进行动画处理时,它会带来对相机的移动感

这里的代码部分创建一个空的几何对象,然后将2,000个顶点放入其中作为粒子。它们分布在X,Y和Z轴上的随机位置。它们会漂浮在液体地板表面的正上方。

pGeometry = new THREE.Geometry(); sprite = textureLoader.load(“img / sprite.png”); for(i = 0; i <2000; i ++){var vertex = new THREE.Vector3(); vertex.x = 4000 * Math.random() -  2000; vertex.y = -200 + Math.random()* 700; vertex.z = 5000 * Math.random() -  2000; pGeometry.vertices.push(顶点); }

+$12. Create The Look

此处定义的材料将设置粒子的外观。在上一步中加载了图像,并在创建材质后将其用作每个粒子上的图像。然后将其应用于所有粒子的几何的每个点。然后将它们添加到场景中。

Create liquid effects: add the logo

添加徽标(透明的PNG图像)将其放置在场景的中心,以后可以轻松替换为您自己的徽标

徽标将放置在屏幕中央,这将添加到面向相机的平面上。徽标略微透明,并添加添加剂混合物,以便在较轻的物体从后面通过时更加明显。这被定位并放置在场景中。

sprite = textureLoader.load(“img / logo.png”); geometry = new THREE.PlaneBufferGeometry(500,640,1); material = new THREE.MeshLambertMaterial({transparent:true,opacity:0.8,blend:THREE.AdditiveBlending,map:sprite,side:THREE.DoubleSide}); var plane = new THREE.Mesh(geometry,material); plane.position.set(0,70,1800); scene.add(平面);

+$14. Add the render settings

渲染器设置为具有平滑的抗锯齿边缘,现在设置背景颜色。这将添加到文档正文中,以便场景位于HTML页面上。通过初始化各种渲染和着色器通道来设置后处理效果。

+$15. Make The Pass

一旦添加了胶片和毛刺传递,就会创建一个效果组合器,将所有传递组合在一起。这些将逐一添加到作曲家,最终将呈现给屏幕以供观众展示。

+$16. Close the 'init' function

最后几个设置被添加用于场景的初始化。设置后处理的参数,调用wave的设置,并在每次调整浏览器大小时添加事件监听器。这样可以更新显示以适应新尺寸。

+$17. Set up the waves

+$The waves are created now for the surface of the liquid. This is done by moving through each vertex of the floor geometry on the x and z axis and moving it upward on the y axis. At this stage the '对于+$' loops are created for the x and z axis.

function setWaves(){stepCount ++; moverGroup.position.z = -MOVE_SPD; var i,ipos; var offset = stepCount * MOVE_SPD / FLOOR_DEPTH * FLOOR_RES; for(i = 0; i <FLOOR_RES + 1; i ++){for(var j = 0; j <FLOOR_RES + 1; j ++){ipos = i + offset;

18.制造波浪

并非所有顶点都以相同的方式向上缩放。距离相机最远的那些将是较大的,然后两侧将略微减少,并且最靠近相机的那些将缩放最少。这使得背部和侧面看起来更有趣。

if((i> 30)||(j <12)||(j> 48)){floorGeometry.vertices [i *(FLOOR_RES + 1)+ j] .z = snoise.noise(ipos / FLOOR_RES * noiseScale, j / FLOOR_RES * noiseScale,noiseSeed)* FLOOR_HT; } else if(i> 25 && i <30){floorGeometry.vertices [i *(FLOOR_RES + 1)+ j] .z = snoise.noise(ipos / FLOOR_RES * noiseScale,j / FLOOR_RES * noiseScale,noiseSeed)*( FLOOR_HT / 1.2); } else {floorGeometry.vertices [i *(FLOOR_RES + 1)+ j] .z = snoise.noise(ipos / FLOOR_RES * noiseScale,j / FLOOR_RES * noiseScale,noiseSeed)*(FLOOR_HT / 2); floorGeometry.verticesNeedUpdate = true; }

+$19. Resize And Animate

调整窗口大小时,此处的函数将从步骤16中设置的侦听器调用。摄像机,渲染器和编辑器都在此处重置,以匹配浏览器窗口的新维度。 Animate函数只将其自身设置为60fps,调用render函数来更新显示。

function onWindowResize(){camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth,window.innerHeight); composer.setSize(window.innerWidth,window.innerHeight); function animate(){requestAnimationFrame(animate);渲染(); }

+$20. Set every frame of action

每帧调用渲染函数。点光源设置为在场景中绕轨道运行,摄像机根据鼠标移动定位,稍微缓和,使其逐渐移动到位。相机设置为始终查看场景的中心。

function render(){var timer = -0.0002 * Date.now(); pointLight.position.x = 2400 * Math.cos(计时器); pointLight.position.z = 2400 * Math.sin(计时器); pointLight2.position.x = 1800 * Math.cos(-timer * 1.5); pointLight2.position.z = 1800 * Math.sin(-timer * 1.5); camera.position.x + =(mouseX  -  camera.position.x)* .05; camera.position.y + =(-mouseY  -  camera.position.y)* .05; camera.lookAt(scene.position);

+$21. Render The Scene

Create liquid effect: render the scene

经常会有一个后处理效果在屏幕上产生毛刺效应,只是为了使屏幕变得活跃并扭曲屏幕,然后再恢复正常

Generate, the award winning conference for web designers, returns to NYC on April 24-25! To book tickets visit www.generateconf.com&nbsp;

+$In the final step the particles are moved forward on their individual vertex, and if they get to the camera, they are placed back into the distance. This is updated and the '+$setWaves'+$function is called to make the waves roll forward. The scene is rendered by the effects composer.

本文最初发表于创意网页设计杂志网页设计者在此订阅Web Designer

相关文章:



翻译字数超限