今天给大家分享一些WebGL实验。在这个实验中,我们将创建一个非常逼真的雨滴效果并将其放在不同的场景中。在本文中,我们将概述用于创建此效果的一些通用技术和技巧。请注意:本文产生的效果还处于实验阶段,可能无法在所有浏览器中看到预期的效果。***使用铬。开始如果我们想要制作一个基于现实世界的效果,那么首先我们需要解剖它的外观,这样我们制作的效果才能显得逼真。如果你看一些水滴落在窗户上的照片(当然,你在生活中肯定观察过),你会发现,由于折射,雨滴似乎把它背后的影像颠倒过来了。图片来源:Wikipedia,GGBreflectioninraindrop你还可以看到,彼此距离很近的雨滴会合并为一个——如果超过一定大小,它就会滑落下来,留下一个小的痕迹。为了模拟这种行为,我们必须绘制大量雨滴,每帧更新它们的折射效果,并以合理的帧速率执行此操作,为此我们需要极高的性能-所以,为了能够使用硬件加速对于显卡,我们将使用WebGL。WebGLWebGL是一个用于绘制2D和3D图形的JavaScript接口,并允许使用GPU以获得更好的性能。它基于OpenGLES,着色器是用一种称为GLSL而不是JS的语言编写的。总而言之,如果您只做过Web开发,它可能看起来让人不知所措——它不仅仅是一门新语言,它是一个全新的概念——但是一旦您掌握了核心概念,它就很容易上手。它会变得容易得多。在本文中我们只会给出一些基本的使用示例,更深入的分析请参考WebGlFundamentals。首先我们需要一个画布标签。WebGL是在画布上绘制的,这是一种类似于我们通过getContext('2d')获得的绘图环境。varcanvas=document.getElementById("container");vargl=canvas.getContext("webgl");接下来我们需要一个程序,它由一个vertexshader和一个fragmentshader(译注:“片段着色器”又名“像素着色器”)组成。着色器只是函数:顶点着色器每个顶点调用一次,片段着色器每个像素调用一次。他们的任务是分别返回坐标和颜色。这是我们WebGL应用程序的核心。首先让我们创建我们的着色器。这是一个顶点着色器,我们不对顶点做任何修改,所以只是让数据通过它:voidmain(){//returnsthepositiongl_Position=a_position;}这是片段着色器。此着色器将根据坐标设置每个像素的颜色。现在我们将着色器连接到WebGL环境:functioncreateShader(gl,source,type){varshader=gl.createShader(type);source=document.getElementById(source).text;gl.shaderSource(shader,source);gl.compileShader(shader);returnshader;}varvertexShader=createShader(gl,'vert-shader',gl.VERTEX_SHADER);varfragShader=createShader(gl,'frag-shader',gl.FRAGMENT_SHADER);varprogram=gl.createProgram();gl.attachShader(program,vertexShader);gl.attachShader(program,fragShader);gl.linkProgram(program);gl.useProgram(program);接下来我们创建一个对象然后在它上面绘制我们的着色器。这里我们画了一个矩形——准确地说是两个矩形。//createrectanglevarbuffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array([-1.0,-1.0,1.0,-1.0,-1.0,1.0,-1.0,1.0,1.0,-1.0,1.0,1.0]),gl.STATIC_DRAW);//vertexdatavarpositionLocation=gl.getAttribLocation(program,"a_position");gl.enableVertexAttribArray(positionLocation);gl.vertexAttribPointer(positionLocation,2,gl.FLOAT,false,0,0);***,绘制整个图像:gl.drawArrays(gl.TRIANGLES,0,6);结果如下:稍后您可以玩这些着色器以了解其工作原理。您可以在ShaderToy上找到许多出色的着色器示例。雨滴现在让我们看看如何制作雨滴。首先让我们看看单个雨滴的样子:现在这里发生了很多事情。alpha通道变成这样是因为我们使用了一种类似于文章CreativeGooeyEffects中提到的技术来使雨滴粘在一起。颜色看起来像这样是有原因的:我们使用类似法线贴图的东西来实现折射效果。我们将使用雨滴的颜色来获取我们透过雨滴看到的纹理的坐标。这是没有蒙版的样子:在这个图像中,我们将从绿色通道数据中获取X坐标,从红色通道数据中获取Y坐标。现在我们可以编写着色器并使用纹理数据和雨滴的位置来翻转和扭曲雨滴后面的纹理。下雨过程创建雨滴后,我们就可以开始模拟下雨了。让雨滴彼此相互作用很难快速计算——随着新雨滴的到来,计算量将呈指数增长——所以我们必须做一些优化。在此示例中,我将大雨滴与小雨滴分开。小雨滴被绘制在一个单独的画布上,并且没有被追踪。这样我就可以毫不费力地画出成千上万的小雨滴。缺点是它们都是静态的,并且由于我们每一帧都在创建新的雨滴,所以它们会累加起来。为了解决这个问题,我们将使用更大的雨滴。由于大雨滴会移动,我们可以用它们清除下方的小雨滴。擦除操作在画布中很棘手:我们实际上仍然需要绘制一些东西,但是使用globalCompositeOperation='destination-out。所以每当大雨滴移动时,我们在较小雨滴的画布上画一个圆圈,并使用复合操作清除那些雨滴,使效果更逼真。***,我们在一个大画布上绘制所有这些,并将其用作我们的WebGL着色器中的纹理。为了让它更亮一点,我们想利用背景会失焦的事实,所以我们使用一个小纹理并将其放大。在WebGL中,纹理的大小直接影响性能。我们需要使用另一个没有失焦的纹理来制作雨滴。模糊是一项代价高昂的操作,应尽可能避免实时模糊——但由于雨滴很小,我们也可以将纹理做得很小。总结为了做出像雨滴这样逼真的效果,我们需要考虑很多复杂的细节。首先将效果与现实世界分开是重现任何效果的关键,一旦我们知道它在现实世界中的工作原理,我们就可以将其行为映射到虚拟世界。使用WebGL我们可以获得非常高的性能(我们可以使用显卡的硬件加速)所以对于这种效果它是一个很好的选择。希望您喜欢这个实验并受到启发!示例(http://tympanus.net/Development/RainEffect/)源代码(http://tympanus.net/Development/RainEffect/RainEffect.zip)