【WebGL与Graphics的学习之路03】旋转的彩色三角形

目标:

        1.了解 varying变量 的用法,以及顶点着色器与片元着色器的交流(即顶点着色器的数据进入片元着色器)

        2.了解矩阵变换和动画的基础知识,让三角形绕z轴旋转起来

 当顶点着色器与片元着色器varying的命名且类型相同时,顶点着色器的数据就会自动的传递给片元着色器,这样就可以达到数据传递。 而varying(变化的)可以把顶点设置成不同的颜色,解决uniform(统一)顶点颜色相同的问题。

矩阵变换:

            

webgl里按列主序的意思就是他的矩阵形式就是行和列进行交换,按上面的数据来写的话即为以z轴旋转。 但是这样太麻烦,会使用矩阵库来代替它进行旋转、平移、缩放。接下来我就直接用改良后的方法来说了。

uniform mat4 u_ModelMatrix;
gl_Position =u_ModelMatrix * a_Position;

先定义一个4*4的矩阵,然后用顶点坐标左乘它,就完成了矩阵变换。

var modelMatrix = new Matrix4();
modelMatrix.setRotate(currentAngle,0,0,1);
modelMatrix.translate(0,0.5,0);
var u_ModelMatrix = gl.getUniformLocation(gl.program,'u_ModelMatrix');
gl.uniformMatrix4fv(u_ModelMatrix,false,modelMatrix.elements);

        这几行代码简单来说就是创建了一个矩阵对象,然后设置了平移和旋转。在得到attribute的u_ModelMatrix的存储地址后,把这个矩阵传递给它,进而顶点着色器就接收到了这个矩阵。最后一行中的modelMatrix.elements的原因是顶点着色器不能接收对象,需要得到的是个矩阵数据。

而变换的先后顺序可以简单记成带set的后进行,本例子就是先进行平移,再旋转。如何想反过来就换一下代码顺序:

        

modelMatrix.setTranslate(0,0.5,0);
modelMatrix.rotate(currentAngle,0,0,1);
	

 

 缩放的话就是对矩阵的对角元素进行修改就好了(即x、y、z)

动画:

        关于三角形的旋转其实就是不断地清除三角形和绘制三角形的过程。requesAnimationFrame(Rotates)和Rotates()这两个函数实现反复调用,我接下来直接把所有代码发出来吧。

var vsSource = `
attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_ModelMatrix;
varying lowp vec4 v_Color;
			void main(void){

				gl_Position =u_ModelMatrix * a_Position;
				gl_PointSize =20.0;
				v_Color = a_Color;
			}
		`;
var fsSource = `
			
			varying lowp vec4 v_Color;
			void main(void){
				gl_FragColor = v_Color;
			}
		`;
var gl;


function main() {

	var canvas = document.getElementById('glcanvas');
	gl = canvas.getContext('webgl');
	initShaders();
	var n =initBuffers(gl);
	var u_ModelMatrix = gl.getUniformLocation(gl.program,'u_ModelMatrix');
	var modelMatrix = new Matrix4();
	var currentAngle =0.0;
	
	function Rotates(){
		currentAngle =animate(currentAngle)
		draw(gl,n,currentAngle,modelMatrix,u_ModelMatrix)
		requestAnimationFrame(Rotates)
	}
	
	Rotates()
	
}

function initShaders() {


	let vsshader = gl.createShader(gl.VERTEX_SHADER);
	let fsshader = gl.createShader(gl.FRAGMENT_SHADER);

	gl.shaderSource(vsshader, vsSource);
	gl.shaderSource(fsshader, fsSource);

	gl.compileShader(vsshader);
	gl.compileShader(fsshader);

	let program = gl.createProgram();
	gl.attachShader(program, vsshader);
	gl.attachShader(program, fsshader);

	gl.linkProgram(program);
	gl.useProgram(program);

	gl.program = program

}


function initBuffers(gl) {
	var a_Position = gl.getAttribLocation(gl.program,'a_Position');
	var verticesColors = new Float32Array ([
		0.0,0.5,1.0,0.0,0.0,
		-0.5,-0.5,0.0,1.0,0.0,
		0.5,-0.5,0.0,0.0,1.0,
	]);
	var n=3

	var vertexColorsBuffer = gl.createBuffer();
	gl.bindBuffer(gl.ARRAY_BUFFER,vertexColorsBuffer);
	gl.bufferData(gl.ARRAY_BUFFER,verticesColors,gl.STATIC_DRAW);
	
	var FSIZE = verticesColors.BYTES_PER_ELEMENT;
	
	gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,FSIZE*5,0);
	gl.enableVertexAttribArray(a_Position);
	
	var a_Color = gl.getAttribLocation(gl.program,'a_Color');
	gl.vertexAttribPointer(a_Color,3,gl.FLOAT,false,FSIZE*5,FSIZE*2);
	gl.enableVertexAttribArray(a_Color);
	

return n;
}

function draw(gl,n,currentAngle,modelMatrix,u_ModelMatrix){
	modelMatrix.setRotate(currentAngle,0,0,1);
	modelMatrix.translate(0,0.5,0);
	gl.uniformMatrix4fv(u_ModelMatrix,false,modelMatrix.elements);
	gl.clearColor(0.0,0.0,0.0,1.0);
	gl.clear(gl.COLOR_BUFFER_BIT);
	gl.drawArrays(gl.TRIANGLES,0,n)
	
	
}
var angle_step = 45.0;
var g_last = Date.now()
function animate(angle){
	var now = Date.now();
	var elapsed = now -g_last;
	g_last = now;
	
	var newAngle =angle + (angle_step * elapsed)/1000.0;
	return newAngle  %=360;
}

然后这个三角形会绕原点逆时针旋转并出现一个渐变色,渐变色的原因是顶点着色器中varying变量v_Color在传入片元着色器之前进行了内插过程。前者与后者的变量实际就不是一回事。

内插过程:

 

 总结:

        本篇内容其实写的不太细,尤其是动画方面,建议具体的还是大家结合书来学习吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值