手写各种矩阵:

//矩阵
var vShader = `
attribute vec4 a_Position;
uniform mat4 u_xformMatrix;
void main(){
gl_Position = u_xformMatrix * a_Position;
}
`;
var fShader = `
void main(){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`; function main(){
//获取canvas元素
var canvas = document.getElementById('webgl');
//获取webgl上下文
var gl = getWebGLContext(canvas);
if(!gl){
console.log('Failed to get the rendering context for WebGL!');
return;
}
//初始化着色器
if(!initShaders(gl,vShader,fShader)){
console.log('Failed to initialize shaders.');
return;
}
var n = initVertexBuffers(gl);
if(n < ){
console.log('Failed to set the positions of the vertices!');
return;
}
//用指定颜色填充webgl容器,就是设置背景
gl.clearColor(0.4, 0.5, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT); /*手动写各种矩阵*/
var ANGLE = 180.0;
var radian = Math.PI * ANGLE / 180.0;
var cosB = Math.cos(radian),sinB = Math.sin(radian);
//旋转矩阵
var transform = [
cosB,-sinB,0.0,0.0,
sinB,cosB,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
];
//平移矩阵
var transform = [
1.0,0.0,0.0,0.5,
0.0,1.0,0.0,0.5,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
];
//旋转+平移矩阵
var transform = [
cosB,-sinB,0.0,0.5,
sinB,cosB,0.0,0.5,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0
];
//缩放矩阵
var Sx = 0.5,Sy = 0.5,Sz = 0.5;
var transform = [
Sx,0.0,0.0,0.0,
0.0,Sy,0.0,0.0,
0.0,0.0,Sz,0.0,
0.0,0.0,0.0,1.0
];
//将行主序矩阵转化为列主序矩阵(webgl只支持列主序矩阵)
var xformMatrix = new Float32Array(rTc(transform));
//至此,适用于顶点着色器的变化矩阵已经写好 /*行主序转为列主序(webgl是列主序的)*/
function rTc(arr){
var size = arr.length/;
var newarr = [];
for (var i = ; i < size; i++) {
newarr.push(arr[i]);
newarr.push(arr[+i]);
newarr.push(arr[+i]);
newarr.push(arr[+i]);
}
return newarr;
} var u_xformMatrix = gl.getUniformLocation(gl.program,'u_xformMatrix');
gl.uniformMatrix4fv(u_xformMatrix,false,xformMatrix);
gl.drawArrays(gl.TRIANGLES,,n); function initVertexBuffers(gl){
var vertices = new Float32Array([
0.0,0.5,-0.5,-0.5,0.5,-0.5
]);
var n = ;//点的个数 //创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if(!vertexBuffer){
console.log('Failed to create the buffer object!');
return -;
} //将缓冲区对象绑定到目标ARRAY_BUFFER
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
//往ARRAY_BUFFER
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW); //获取shaderProgram中attribute变量‘a_Position’的地址
var a_Position = gl.getAttribLocation(gl.program,'a_Position');
if (a_Position < ) {
console.log('Failed to get the storage location of a_Position');
return -;
}
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position,,gl.FLOAT,false,,);
//开启着色器对缓冲区数据的访问
gl.enableVertexAttribArray(a_Position);
return n;
}
} main();

利用webgl编程指南作者提供的矩阵库:

//矩阵
var vShader = `
attribute vec4 a_Position;
uniform mat4 u_xformMatrix;
void main(){
gl_Position = u_xformMatrix * a_Position;
}
`;
var fShader = `
void main(){
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`; function main(){
//获取canvas元素
var canvas = document.getElementById('webgl');
//获取webgl上下文
var gl = getWebGLContext(canvas);
if(!gl){
console.log('Failed to get the rendering context for WebGL!');
return;
}
//初始化着色器
if(!initShaders(gl,vShader,fShader)){
console.log('Failed to initialize shaders.');
return;
}
var n = initVertexBuffers(gl);
if(n < ){
console.log('Failed to set the positions of the vertices!');
return;
}
//用指定颜色填充webgl容器,就是设置背景
gl.clearColor(0.4, 0.5, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT); var ANGLE = 180.0;
 
var xformMatrix = new Matrix4();
//设置旋转矩阵,旋转轴为(0,0,1),即Z轴
xformMatrix.setRotate(ANGLE,,,);
xformMatrix.translate(0.5,,);
//先设置旋转矩阵,在此基础上乘以平移矩阵
//最后结果是 旋转矩阵x平移矩阵,就是先平移再旋转 // xformMatrix.setTranslate(0.5,0,0);
// xformMatrix.rotate(ANGLE,0,0,1);
//先设置平移矩阵,在此基础上乘以旋转矩阵
//最后结果是 平移矩阵x旋转矩阵,就是先旋转再平移
gl.uniformMatrix4fv(u_xformMatrix,false,xformMatrix.elements);
gl.drawArrays(gl.TRIANGLES,,n); function initVertexBuffers(gl){
var vertices = new Float32Array([
0.0,0.5,-0.5,-0.5,0.5,-0.5
]);
var n = ;//点的个数 //创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if(!vertexBuffer){
console.log('Failed to create the buffer object!');
return -;
} //将缓冲区对象绑定到目标ARRAY_BUFFER
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
//往ARRAY_BUFFER
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW); //获取shaderProgram中attribute变量‘a_Position’的地址
var a_Position = gl.getAttribLocation(gl.program,'a_Position');
if (a_Position < ) {
console.log('Failed to get the storage location of a_Position');
return -;
}
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position,,gl.FLOAT,false,,);
//开启着色器对缓冲区数据的访问
gl.enableVertexAttribArray(a_Position);
return n;
}
} main();

在顶点着色器中,我们添加了一个矩阵参数,通过变化矩阵来改变顶点的坐标,替代了之前的复杂的运算,关于矩阵:

矩阵运算:

平移矩阵:

旋转矩阵:

注意:

①webGL中矩阵是列主序的,但是我们通常接触的高数中的矩阵都是行主序的,行主序的矩阵看上去也比较符合人的习惯,所以我们在这里,手写矩阵的时候,写成行主序,但是传给webGL的时候,要将其转化为列主序的,文中已经列出了我自己编写的转化函数:

/*行主序转为列主序(webgl是列主序的)*/
function rTc(arr){
var size = arr.length/;
var newarr = [];
for (var i = ; i < size; i++) {
newarr.push(arr[i]);
newarr.push(arr[+i]);
newarr.push(arr[+i]);
newarr.push(arr[+i]);
}
return newarr;
}

②在矩阵库的帮助下,我们写起矩阵尤为方便,但要注意,关于set***和不加set前缀的方法的区别

set***为一个矩阵对象初始化一个矩阵M1,多次set***的话,结果只包含最后一次set的矩阵;

不加set的方法,在原先初始化了矩阵的矩阵基础上M1 x M2,多个的结果是M1 x M2 x M3 x......注意顺序;

矩阵乘法不适用交换律,所以先后顺序不同的话,最终效果也会不一样,文中注释已说明。

WebGL编程指南案例解析之平移和旋转的矩阵实现的更多相关文章

  1. WebGL编程指南案例解析之平移和旋转的math库实现

    这里说的math库实现,指的是,通过一般的加减乘除(角度计算)来更新坐标值. 因为涉及到坐标的变化,所以这里都是基于对顶点着色器的修改 平移: var vShader = ` attribute ve ...

  2. WebGL编程指南案例解析之绘制一个点

    <!DOCTYPE html> <html> <head> <title>webgl</title> <style type=&quo ...

  3. WebGL编程指南案例解析之3D视图视区问题

    var VSHADER_SOURCE = 'attribute vec4 a_Position;\n' + 'attribute vec4 a_Color;\n' + 'uniform mat4 u_ ...

  4. WebGL编程指南案例解析之绘制三个点

    //案例2.绘制3个点,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //着色器将对这些顶点进行逐个解析, //第一个顶点给到顶点着色器,赋值给 ...

  5. WebGL编程指南案例解析之绘制四边形

    //案例4,绘制矩形,和三角形类似,但是注意因为一个矩形有4个顶点,按照两个三角形绘制矩形的话,顶点顺序要注意 var vShader = ` attribute vec4 a_Position; v ...

  6. WebGL编程指南案例解析之绘制三角形

    //案例3.绘制三角形,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //顶点着色器中去掉gl_PointSize = 10.0,绘制三角不能设 ...

  7. WebGL编程指南案例解析之纹理叠加

    var vShader = ` attribute vec4 a_Position; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; void ...

  8. WebGL编程指南案例解析之加载纹理(贴图)

    var vShader = ` attribute vec4 a_Position; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; void ...

  9. WebGL编程指南案例解析之多数据存储于一个缓冲区以及着色器通信

    //顶点着色器往片元着色器传值 //多个参数值存于一个缓冲对象中 var vShader = ` attribute vec4 a_Position; attribute float a_PointS ...

随机推荐

  1. UVa 1605 联合国大楼

    https://vjudge.net/problem/UVA-1605 题意:有n个国家,要求设计一栋楼并为这n个国家划分房间,要求国家的房间必须连通,且每两个国家之间必须有一间房间是相邻的. 思路: ...

  2. python 等比数列

    def is_geometric(li): : return True # Calculate ratio ratio = li[]/]) # Check the ratio of the remai ...

  3. testNG 学习笔记 Day 1 使用功能详解

    TestSuite处理测试用例有6个规约(否则会被拒绝执行测试) A 测试用例必须是公有类(Public) B 测试用例必须继承与TestCase类 C 测试用例的测试方法必须是公有的( Public ...

  4. 视图层view layer

    视图层是Django处理请求的核心代码层,我们大多数Python代码都集中在这一层面. 它对外接收用户请求,对内调度模型层和模版层,统合数据库和前端,最后根据业务逻辑,将处理好的数据,与前端结合,返回 ...

  5. Thunder团队Alpha周贡献分规则及贡献分分配结果

    小组名称:Thunder 项目名称:爱阅app 组长:王航 成员:李传康.代秋彤.邹双黛.苗威.宋雨.胡佑蓉.杨梓瑞 Alpha周贡献分分配结果

  6. JavaScript权威指南--多媒体和图形编程

    知识要点 21.1节介绍如何用传统的JavaScript技术实现诸如图片翻转(鼠标指针移动到一张静态图片上切换成另外一张图片)这样的视觉效果. 21.2节介绍HTML5的<audio>和& ...

  7. iconv编码转换

    环境:cocos2dx 3.10 1.vs环境下编译windows版本,需要增加头文件和链接库①cocos2d-x-3.10\external\win32-specific\icon\include② ...

  8. Python -- xlrd,xlwt,xlutils 读写同一个Excel

    最近开始学习python,想做做简单的自动化测试,需要读写excel,然后就找到了xlrd来读取Excel文件,使用xlwt来生成Excel文件(可以控制Excel中单元格的格式),需要注意的是,用x ...

  9. angular5 ng-bootstrap和ngx-bootstrap区别

    https://angular.cn/resources ngx-bootstrap 安装: npm install ngx-bootstrap --save 再引入css <link href ...

  10. html css 伪样式

    伪类的分类及作用: 引自W3School教程伪元素的分类及作用: 这里就不进行多的描述,原文地址:http://www.it165.net/design/html/201406/2643.html