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 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编程指南案例解析之平移和旋转的矩阵实现的更多相关文章
- WebGL编程指南案例解析之平移和旋转的math库实现
这里说的math库实现,指的是,通过一般的加减乘除(角度计算)来更新坐标值. 因为涉及到坐标的变化,所以这里都是基于对顶点着色器的修改 平移: var vShader = ` attribute ve ...
- WebGL编程指南案例解析之绘制一个点
<!DOCTYPE html> <html> <head> <title>webgl</title> <style type=&quo ...
- WebGL编程指南案例解析之3D视图视区问题
var VSHADER_SOURCE = 'attribute vec4 a_Position;\n' + 'attribute vec4 a_Color;\n' + 'uniform mat4 u_ ...
- WebGL编程指南案例解析之绘制三个点
//案例2.绘制3个点,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //着色器将对这些顶点进行逐个解析, //第一个顶点给到顶点着色器,赋值给 ...
- WebGL编程指南案例解析之绘制四边形
//案例4,绘制矩形,和三角形类似,但是注意因为一个矩形有4个顶点,按照两个三角形绘制矩形的话,顶点顺序要注意 var vShader = ` attribute vec4 a_Position; v ...
- WebGL编程指南案例解析之绘制三角形
//案例3.绘制三角形,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //顶点着色器中去掉gl_PointSize = 10.0,绘制三角不能设 ...
- WebGL编程指南案例解析之纹理叠加
var vShader = ` attribute vec4 a_Position; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; void ...
- WebGL编程指南案例解析之加载纹理(贴图)
var vShader = ` attribute vec4 a_Position; attribute vec2 a_TexCoord; varying vec2 v_TexCoord; void ...
- WebGL编程指南案例解析之多数据存储于一个缓冲区以及着色器通信
//顶点着色器往片元着色器传值 //多个参数值存于一个缓冲对象中 var vShader = ` attribute vec4 a_Position; attribute float a_PointS ...
随机推荐
- HDU 6121 Build a tree(完全K叉树)
http://acm.hdu.edu.cn/showproblem.php?pid=6121 题意:给你一颗完全K叉树,求出每棵子树的节点个数的异或和. 思路: 首先需要了解一些关于完全K叉树或满K叉 ...
- confluence导出pdf 文字显示不全
当使用confluence编辑页面时,当一行的文字过多,且中间没什么逗号分隔时,有时会出现导出的pdf文件中,这一行显示的文字不全的情况. 如: 很明显费用的费字没有显示完全,且后面还有其他的字. 可 ...
- .net Parallel并行使用
因项目响应过慢,代码优化空间不大,在暂时无法调整系统架构的情况下,只有使用.NET中的TPL解决一些模块耗时过多的问题.但在使用过程中也碰到了一些问题,现在把它写下来,用于备忘. 1. Paralle ...
- 小波变化库——Pywalvets学习笔记
笔记 术语(中英对照): 尺度函数:scaling function(又称父函数 father wavelet) 小波函数:wavelet function(又称母函数 mother wavelet) ...
- vector_01
尾部 ==> 添加/删除 快 头部/中间 ==> 添加/删除 慢 A.尾部 添加/移除: void vector::push_back(); void vector::pop_back( ...
- Topless eclipse导入myeclipse的web项目没法识别问题解决
1.进入项目目录,找到.project文件,打开. 2.找到<natures>...</natures>代码段. 3.在第2步的代码段中加入如下标签内容并保存: <nat ...
- 重构 MVC; 代码分享工具(重构,改进,打分)
include 模块和 extend 模块的不同: Class Extension: 通过向singleton class中加入Module来定义class method,是对象扩展的一个特例. ...
- python-day38--IO模型
一. IO模型介绍 对于一个网络通信,IO涉及到两个阶段 1.操作系统等数据来 2.进程或线程等操作系统拷贝数据 记住这两点很重要,因为这些IO模型的区别就是在两个阶段上各有不同的情况. 二.阻塞IO ...
- secureCRT启动xmanager图形化工具
secureCRT启动xmanager图形化工具 2014年9月17日 11:42 secureCRT是我们在维护UNIX或者linux的重要工具.xmanager 工具是连接UNIX或者linux的 ...
- @ConditionalOnProperty 详解
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Documented @Con ...