HT for Web基於HTML5的影象操作(三)

圖撲軟體發表於2014-11-23

上篇採用了HTML5的Canvas的globalCompositeOperation屬性達到了染色效果,其實CSS也提供了一些常規影象變化的設定引數,關於CSS的過濾器Filter設定可參考 http://www.html5rocks.com/en/tutorials/filters/understanding-css/,CSS的設定的確很方便,不需要我們瞭解底層實現邏輯,僅需要提供簡單的設定引數值即可,但這樣的方式畢竟無法達到隨心所欲變化的效果,這有點想OpenGL早期只能通過Fixed Function Pipeline進行開發,和如今採用Shading Language可實現豐富多彩變化的質變,因此這篇我們將採用WebGL的SL程式碼方式折騰點更好玩的效果。

Screen Shot 2014-11-23 at 6.00.06 PM

第一篇我們已經提到影象操作的本質是對輸入輸出的資料變化,因此染色僅是最簡單直觀的基本變化,通過WebGL的SL程式碼我們甚至可以實現影象扭曲等變化效果,先上張最終變化效果的截圖,原圖就是Hightopo官網的banner,染色+扭曲的效果如上:

Vertex程式碼如下:

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程式碼如下:

	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 WebFromPane外掛很容易實現控制引數皮膚可進行編輯實時呈現變化效果,以下為操作控制皮膚動態變化的視訊效果:http://v.youku.com/v_show/id_XODMzMTU0OTA0.html

<iframe src="http://player.youku.com/embed/XODMzMTU0OTA0" frameborder="0" width="510" height="498"></iframe>

Screen Shot 2014-11-23 at 6.02.26 PM

最後如果你耐心細緻地閱讀到此,對前端遊戲開發感興趣,感覺自己悟性不錯,願意在廈門發展的同學可與聯絡我,我的郵箱為eric@… 省略部分你應該知道的,不限制性別、學歷和年齡,只要你想用心做自己喜歡的事,我期待著與你交流和加盟!

相關文章