Webgl-超级基础随笔2-矩阵与绘制Cude

下面的代码编写紧接着上一篇来进行扩展。

目录

视图矩阵

投影矩阵

绘制Cude


视图矩阵

  1. maxtrix.js

//视图矩阵计算

Matrix4.prototype.setLookAt = function (eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ) {

var e, fx, fy,fz, rlf, sx, sy, sz, rls, ux, uy, uz;

fx = centerY - eyeX;

fy = centerY - eyeY;

fz = centerZ - eyeZ;

 

rlf = 1 / Math.sqrt(fx * fx + fy * fy + fz * fz);//归一化

fx *= rlf;

fy *= rlf;

fz *= rlf;

//叉乘计算

sx = fy * upZ - fz * upY;

sy = fz * upX - fx * upZ;

sz = fx * upY - fy * upX;

rls = 1 / Math.sqrt(sx*sx + sy*sy + sz*sz);//归一化

sx *= rls;

sy *= rls;

sz *= rls;

//叉乘

ux = sy * fz - sz * fy;

uy = sz * fy - sx * fz;

uz = sx * fy - sy * fx;

e = this.elements;

e[0] = sx; e[4] = sy; e[8] = sz; e[12] = 0;

e[1] = ux; e[5] = uy; e[9] = uz; e[13] = 0;

e[2] = -fx; e[6] = -fy; e[10] = -fz; e[14] = 0;

e[3] = 0; e[7] = 0; e[11] = 0; e[15] = 1;

return this.translate(-eyeX, -eyeY, -eyeZ);//乘以平移矩阵的转置矩阵

}

  1. demo.js:添加视图矩阵

顶点着色器

VSHADER_SOURCE =

'attribute vec4 a_Position;\n'+

'uniform mat4 u_ModelMatrix;\n' +//旋转

'uniform mat4 u_ViewMatrix;\n' +//视图矩阵

'void main (){\n'+

'gl_Position = u_ViewMatrix*u_ModelMatrix*a_Position;\n'+//视图矩阵*旋转角度*位置

'}\n'

定义矩阵:(看向位置,自己位置,头部朝向)

//视图矩阵

var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix')

var viewMatrix = new Matrix4()

viewMatrix.lookAt(0,0,0,0,0,-1,0,1,0)

draw方法中

//设置传递视图矩阵

gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements)

投影矩阵

透视矩阵

  1. matrix.js

//透视投影矩阵计算

Matrix4.prototype.perspective = function (fovy, aspect, near, far) {

return this.concat(new Matrix4().setPerspective(fovy, aspect, near, far));

}

 

Matrix4.prototype.setPerspective = function (fovy, aspect, near, far) {

var e, s, ct;

if (near === far || aspect == 0) {

throw 'null frustum';

}

if (near <= 0) {

throw 'near <= 0';

}

if (far <= 0) {

throw 'far <= 0';

}

fovy = Math.PI * fovy / 180 / 2;

s = Math.sin(fovy);

if (s === 0) {

throw 'null frustum';

}

rd = 1 / (far - near);

ct = Math.cos(fovy) / s;

e = this.elements;

e[0] = ct / aspect; e[4] = 0; e[8] = 0; e[12] = 0;

e[1] = 0; e[5] = ct; e[9] = 0; e[13] = 0;

e[2] = 0; e[6] = 0; e[10] = -(far + near) / (far - near); e[14] = -2 * near * far / (far - near);

e[3] = 0; e[7] = 0; e[11] = -1; e[15] = 0;

return this;

}

  1. demo.js

顶点着色器

VSHADER_SOURCE =

'attribute vec4 a_Position;\n'+

'uniform mat4 u_ModelMatrix;\n' +//旋转

'uniform mat4 u_ViewMatrix;\n' +//视图矩阵

'uniform mat4 u_ProjectionMatrix;\n' +//投影矩阵

'void main (){\n'+

'gl_Position = u_ProjectionMatrix*u_ViewMatrix*u_ModelMatrix*a_Position;\n'+//投影矩阵*视图矩阵*旋转角度*位置

'}\n'

定义投影矩阵

//投影矩阵

var u_ProjectionMatrix = gl.getUniformLocation(gl.program, 'u_ProjectionMatrix')

var projectionMatrix = new Matrix4()

projectionMatrix.perspective(120,1,0.1,1000)

draw方法中

//设置传递投影矩阵

gl.uniformMatrix4fv(u_ProjectionMatrix, false, projectionMatrix.elements)

正交矩阵

  1. maxtrix.js

//正交投影

Matrix4.prototype.ortho = function(left, right, bottom, top, near, far) {

return this.concat(new Matrix4().setOrtho(left, right, bottom, top, near, far));

}

 

Matrix4.prototype.setOrtho = function(left, right, bottom, top, near, far) {

if (left === right || bottom === top || near === far) {

throw 'null frustum';

}

e = this.elements;

 

e[0] = 2 / (right - left); e[4] = 0; e[8] = 0; e[12] = - (right + left) / (right - left);

e[1] = 0; e[5] = 2 / (top - bottom); e[9] = 0; e[13] = - (top + bottom ) / (top - bottom);

e[2] = 0; e[6] = 0; e[10] = -2 / (far - near); e[14] = - (far + near) / (far - near);

e[3] = 0; e[7] = 0; e[11] = 0; e[15] = 1;

console.log(e)

return this;

}

  1. demo.js(其他与透视一致)

//投影矩阵

var u_ProjectionMatrix = gl.getUniformLocation(gl.program, 'u_ProjectionMatrix')

var projectionMatrix = new Matrix4()

//projectionMatrix.perspective(120,1,0.1,1000)

projectionMatrix.ortho(-5,5,-5,5,0.1,1000)//正交

绘制Cude

  1. demo_cude.js

var canvas = document.getElementById('myCanvas')//获取canvas

var gl = canvas.getContext('webgl')//获取webGL上下文

 

var program = gl.createProgram()//创建程序

 

var VSHADER_SOURCE, FSHADER_SOURCE

//定义顶点着色器、片元着色器源码

VSHADER_SOURCE =

'attribute vec4 a_Position;\n' +

'attribute vec4 a_Color;\n' +

'attribute vec4 a_Normal;\n' +

'uniform mat4 u_MvpMatrix;\n' +//视图投影矩阵

'void main() {\n' +

' gl_Position = u_MvpMatrix * a_Position;\n' +//计算位置

'}\n';

FSHADER_SOURCE =

'void main() {\n' +

' gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\n' +//颜色渲染

'}\n';

var vertexShader, fragmentShader

//创建着色器(gl上下文、着色器源码,着色器类型)

function createShader (gl, sourceCode,type) {

// create shader

var shader = gl.createShader(type)

gl.shaderSource(shader, sourceCode)

gl.compileShader(shader)

return shader

}

// define vertex shader

vertexShader = createShader(gl, VSHADER_SOURCE, gl.VERTEX_SHADER)

// define frament shader

fragmentShader = createShader(gl, FSHADER_SOURCE, gl.FRAGMENT_SHADER)

// attach shader to program

gl.attachShader(program, vertexShader)

gl.attachShader(program, fragmentShader)

// link program to context

gl.linkProgram(program)

gl.useProgram(program)

gl.program = program

var tick = function () {

draw()

requestAnimationFrame(tick)//循环tick

}

function initVertexBuffers (gl) {//加载顶点数据

// Create a cube(下面的图差不多就是那意思,文章里显示,对不准)

// v6----- v5

// /| --------/|

// v1------v0|

// | | ------| |

// | |v7-----|v4

// |/------- |/

// v2------v3

var vertices = new Float32Array([ // Vertex coordinates(点坐标)

1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front

1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // v0-v3-v4-v5 right

1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up

-1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, // v1-v6-v7-v2 left

-1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, // v7-v4-v3-v2 down

1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0 // v4-v7-v6-v5 back

]);

 

// 每个顶点的法向量

var normals = new Float32Array([

0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,

0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,

-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0,

0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,

0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0

]);

var colors = new Float32Array([ // Colors

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v1-v2-v3 front(white)

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v3-v4-v5 right(white)

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v5-v6-v1 up(white)

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v1-v6-v7-v2 left(white)

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v7-v4-v3-v2 down(white)

1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 // v4-v7-v6-v5 back(white)

]);

var indices = new Uint8Array([ // Indices of the vertices,三角面绘制规则

0, 1, 2, 0, 2, 3, // front

4, 5, 6, 4, 6, 7, // right

8, 9,10, 8,10,11, // up

12,13,14, 12,14,15, // left

16,17,18, 16,18,19, // down

20,21,22, 20,22,23 // back

]);

// Create a buffer object

var indexBuffer = gl.createBuffer();

initArrayBuffer(gl, vertices, 3, gl.FLOAT, 'a_Position')

initArrayBuffer(gl, colors, 3, gl.FLOAT, 'a_Color')

initArrayBuffer(gl, normals, 3, gl.FLOAT, 'a_Normal')

// Write the indices to the buffer object

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

return indices.length;//返回点数

}

//(gl上下文,ArrayBuffer数据,以几组数据为一点,数据类型,着色器中对应变量名)

function initArrayBuffer(gl, data, num, type, attribute) {

// Create a buffer object

var buffer = gl.createBuffer();

if (!buffer) {

console.log('Failed to create the buffer object');

return false;

}

// Write date into the buffer object

gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

 // Assign the buffer object to the attribute variable

var a_attribute = gl.getAttribLocation(gl.program, attribute);

if (a_attribute < 0) {

console.log('Failed to get the storage location of ' + attribute);

return false;

}

//将当前绑定到gl.ARRAY_BUFFER的缓冲区到顶点缓存区

gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);

// Enable the assignment of the buffer object to the attribute variable

gl.enableVertexAttribArray(a_attribute);//许可缓冲区分配变量

gl.bindBuffer(gl.ARRAY_BUFFER, null);//清空bindBuffer中的gl.ARRAY_BUFFER缓存区

return true;

}

function normalizeVector (vector) {

var len = Math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)

return [vector[0] / len, vector[1] / len, vector[2] / len]

}

// write the positions of vertices to a vertex shader

var n = initVertexBuffers(gl)//加载顶点

gl.clearColor(0, 0, 0, 1)//背景色

gl.enable(gl.DEPTH_TEST);//深度检测

//摄像机视图

// Get the storage location of u_MvpMatrix

var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');

// Set the eye point and the viewing volume

var mvpMatrix = new Matrix4();

mvpMatrix.setPerspective(30, 1, 1, 100);

mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1,0);

//关联gl设置视图

gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);

function draw () {

// Clear color and depth buffer

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// Draw the cube索引方式绘制(三角面,绘制点数,前面的数据类型,偏移)

gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);

}

tick()


源代码,等写完基础随笔就上传拉。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值