WebGL——水波纹特效

  大家好,今天我ccentry要做一个水波纹特效,我们来看看水波纹特效的做法。首先我们来看一下水波纹特效的效果是怎么样的,请看下图。

  我们要做的就是类似这种纹理特效,那么我们来看看是如何制作的吧。首先鲫鱼我新建一个空项目,来编写这个demo,项目结构如下图所示。

img文件夹中存放的是uv贴图和底图,js文件夹下存放的是jquery和我的水波纹效果的js文件,还有就是展示页面index.html。很简单,没什么东西了,接下来就来看鲫鱼我是怎么实现上面这个水波纹特效的吧。我们先开始编辑ripples.js,这就是这个特效的核心功能。再来看一遍工程结构。

且看鲫鱼我怎么写这个ripple.js。首先我们检查浏览器是否支持webgl的api,这是一个浏览器校验功能函数,代码块如下。

复制代码
var gl;  function hasWebGLSupport() {         var canvas = document.createElement('canvas');         var context = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');         var result = context && context.getExtension('OES_texture_float') && context.getExtension('OES_texture_float_linear');         return result;     }
复制代码

这里先是创建了一个canvas标签,然后由这个canvas中拿到context('webgl')对象,我们所有做webgl的api都由此而来。这里只是校验并获取gl对象的动作,然后我们来看函数的返回值,这里有个js的&&运算符的妙用,result = context && context.getExtension('OES_texture_float') && context.getExtension('OES_texture_float_linear');这句话是指context存在,就取context.getExtension('OES_texture_float'),而且context.getExtension('OES_texture_float')存在,就取context.getExtension('OES_texture_float_linear'),这是递进式的取值方式,我们最终通过了前两个的校验获取到了'OES_texture_float_linear'对象,鲫鱼相信大家也都看得懂,我们就不在这里浪费时间了,继续往下看。

var supportsWebGL = hasWebGLSupport();

这句就一目了然了,我们调用了hasWebGLSupport函数,从而获取到了'OES_texture_float_linear'线性浮点数的材质处理对象。这个对象我们后面要使用到,现在这里拿到手再说。我们接下去看。

复制代码
function createProgram(vertexSource, fragmentSource, uniformValues)      {         function compileSource(type, source) {             var shader = gl.createShader(type);             gl.shaderSource(shader, source);             gl.compileShader(shader);             if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {                 throw new Error('compile error: ' + gl.getShaderInfoLog(shader));             }             return shader;         }                  var program = {};                  program.id = gl.createProgram();         gl.attachShader(program.id, compileSource(gl.VERTEX_SHADER, vertexSource));         gl.attachShader(program.id, compileSource(gl.FRAGMENT_SHADER, fragmentSource));         gl.linkProgram(program.id);         if (!gl.getProgramParameter(program.id, gl.LINK_STATUS)) {             throw new Error('link error: ' + gl.getProgramInfoLog(program.id));         }          // Fetch the uniform and attribute locations        program.uniforms = {};         program.locations = {};         gl.useProgram(program.id);         gl.enableVertexAttribArray(0);         var name, type, regex = /uniform (\w+) (\w+)/g, shaderCode = vertexSource + fragmentSource;         while ((match = regex.exec(shaderCode)) != null) {             name = match[2];             program.locations[name] = gl.getUniformLocation(program.id, name);         }                  return program;     }
复制代码

这一个功能自然不必再解释了,这是gl对象绑定shader的工具,参数为vertexSource顶点着色器字符串,fragmentSource片段着色器字符串,uniformValues向着色器传递的参数,如果读者对这个函数存在疑问,鲫鱼建议读者先学习《webgl编程指南》和阅读鲫鱼之前的博客https://www.cnblogs.com/ccentry/p/9864847.html,这里不再赘述。我们再往下看。

复制代码
function bindTexture(texture, unit) {         gl.activeTexture(gl.TEXTURE0 + (unit || 0));         gl.bindTexture(gl.TEXTURE_2D, texture);     }
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信