上篇採用了HTML5的Canvas的globalCompositeOperation屬性達到了染色效果,其實CSS也提供了一些常規圖像變化的設置參數,關於CSS的過濾器Filter設置可參考 http://www.html5rocks.com/en/tutorials/filters/understanding-css/,CSS的設置的確很方便,不須要咱們瞭解底層實現邏輯,僅須要提供簡單的設置參數值便可,但這樣的方式畢竟沒法達到爲所欲爲變化的效果,這有點想OpenGL早期只能經過Fixed Function Pipeline進行開發,和現在採用Shading Language可實現豐富多彩變化的質變,所以這篇咱們將採用WebGL的SL代碼方式折騰點更好玩的效果。php
在第一篇咱們已經提到圖像操做的本質是對輸入輸出的數據變化,所以染色僅是最簡單直觀的基本變化,經過WebGL的SL代碼咱們甚至能夠實現圖像扭曲等變化效果,先上張最終變化效果的截圖,原圖就是Hightopo官網的banner,染色+扭曲的效果如上:css
Vertex代碼以下html
attribute vec2 aVertexPosition; attribute vec2 aTexturePosition; varying vec2 vTexturePosition; void main() { vTexturePosition = aTexturePosition; gl_Position = vec4(aVertexPosition, 0.0, 1.0); }
Fragment代碼以下:前端
precision mediump float; varying vec2 vTexturePosition; uniform sampler2D uSampler; uniform vec4 uColor; uniform float uRadius; uniform float uAngle; uniform vec2 uCenter; void main() { vec2 vec = vTexturePosition - uCenter; float distance = length(vec); if (distance < uRadius) { float ratio = (uRadius - distance) / uRadius; float angle = ratio * ratio * uAngle; float s = sin(angle); float c = cos(angle); vec = vec2(vec.x * c - vec.y * s, vec.x * s + vec.y * c); } gl_FragColor = texture2D(uSampler, uCenter+vec) * uColor; }
相應JavaScript代碼以下:html5
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); vertexShader = loadShaderFromDOM("shader-vs"); fragmentShader = loadShaderFromDOM("shader-fs"); var program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); gl.useProgram(program); var vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -0.7, 0.7, -0.7, -0.7, 0.7, 0.7, -0.7, -0.7, 0.7, -0.7, 0.7, 0.7 ]), gl.STATIC_DRAW); var vertexLocation = gl.getAttribLocation(program, "aVertexPosition"); gl.vertexAttribPointer(vertexLocation, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vertexLocation); var textureBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1 ]), gl.STATIC_DRAW); var textureLocation = gl.getAttribLocation(program, "aTexturePosition"); gl.vertexAttribPointer(textureLocation, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(textureLocation); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); gl.uniform1i(gl.getUniformLocation(program, 'uSampler'), 0); gl.uniform4fv(gl.getUniformLocation(program, 'uColor'), toRGBA(formPane.v('color'))); gl.uniform1f(gl.getUniformLocation(program, 'uRadius'), formPane.v('radius')); gl.uniform1f(gl.getUniformLocation(program, 'uAngle'), formPane.v('angle')); gl.uniform2fv(gl.getUniformLocation(program, 'uCenter'), [formPane.v('centerX'), 1-formPane.v('centerY')]); gl.drawArrays(gl.TRIANGLES, 0, 6); }
以上Vertext和Fragment的代碼不少很容易理解,採用HT for Web的FromPane插件很容易實現控制參數面板可進行編輯實時呈現變化效果,如下爲操做控制面板動態變化的視頻效果:http://v.youku.com/v_show/id_XODMzMTU0OTA0.htmlapp
最後若是你耐心細緻地閱讀到此,對前端遊戲開發感興趣,感受本身悟性不錯,願意在廈門發展的同窗可與聯繫我,個人郵箱爲eric@… 省略部分你應該知道的,不限制性別、學歷和年齡,只要你想用心作本身喜歡的事,我期待着與你交流和加盟!spa