变换有三种状态:平移 旋转 缩放
在四维矩阵中,是是可以包含所有变换状态的。即我们介意进行一次平移,旋转,缩放。这种变换叫做复合变换
矩阵相乘
矩阵相乘可以实现复合变换。使用tree.js中的Matrix4对象建立矩阵
const a=new Matrix4().set(
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10,11,
12,13,14,15
)
const b=new Matrix4().set(
0, 10, 20, 30,
40, 50, 60, 70,
80, 90, 100,110,
120,130,140,150
)
注:set()方法里输入的矩阵是行主序的,但elements 输出的矩阵是列主序的。
const ca=a.elements
console.log(ca);
[
0, 4, 8, 12,
1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15
]
2.让矩阵相乘
[
560, 1520, 2480, 3440,
620, 1740, 2860, 3980,
680, 1960, 3240, 4520,
740, 2180, 3620, 5060
]
矩阵连续位移
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<!-- 定点着色器 -->
<!-- z旋转其实就是以圆心为中心,进行旋转 -->
<script id="vertexShader" type="x-shader/x-vertext">
attribute vec4 a_Position;
uniform mat4 u_Matrix;
void main () {
//列主序
gl_Position = u_Matrix*a_Position;
gl_PointSize = 50.0;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main () {
gl_FragColor = vec4(1, 1, 0, 1);
}
</script>
<script type="module">
import { initShaders } from "./jsm/Utils.js";
import { Matrix4 } from 'https://unpkg.com/three/build/three.module.js';
const canves = document.querySelector('#canvas');
canves.width = window.innerWidth
canves.height = window.innerHeight
// 获取着色器文本
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
const gl = canves.getContext('webgl')
initShaders(gl, vsSource, fsSource)
const a_Position = gl.getAttribLocation(gl.program, 'a_Position')
// 创建缓冲区
const vertextBuffer = gl.createBuffer();
// 绑定缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER,vertextBuffer)
const floatArray = new Float32Array([
0.0,0.0,
0.0,0.2,
0.2,0.0
])
gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW)
const u_Matrix = gl.getUniformLocation(gl.program,'u_Matrix')
const mr = new Matrix4()
mr.makeRotationZ(Math.PI)
const mt = new Matrix4()
mt.makeTranslation(0.2,0.0,0)
const dm = mt.multiply(mr)
gl.uniformMatrix4fv(u_Matrix,false,dm.elements)
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT,false,0,0)
gl.enableVertexAttribArray(a_Position)
gl.clearColor(0,0,0,1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.TRIANGLES,0,3)
</script>
</html>
矩阵先位移后旋转
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<!-- 定点着色器 -->
<!-- z旋转其实就是以圆心为中心,进行旋转 -->
<script id="vertexShader" type="x-shader/x-vertext">
attribute vec4 a_Position;
uniform mat4 u_Matrix;
void main () {
//列主序
gl_Position = u_Matrix*a_Position;
gl_PointSize = 50.0;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main () {
gl_FragColor = vec4(1, 1, 0, 1);
}
</script>
<script type="module">
import { initShaders } from "./jsm/Utils.js";
import { Matrix4 } from 'https://unpkg.com/three/build/three.module.js';
const canves = document.querySelector('#canvas');
canves.width = window.innerWidth
canves.height = window.innerHeight
// 获取着色器文本
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
const gl = canves.getContext('webgl')
initShaders(gl, vsSource, fsSource)
const a_Position = gl.getAttribLocation(gl.program, 'a_Position')
// 创建缓冲区
const vertextBuffer = gl.createBuffer();
// 绑定缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER,vertextBuffer)
const floatArray = new Float32Array([
0.0,0.0,
0.0,0.2,
0.2,0.0
])
gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW)
const u_Matrix = gl.getUniformLocation(gl.program,'u_Matrix')
const mr = new Matrix4()
mr.makeRotationZ(Math.PI)
const mt = new Matrix4()
mt.makeTranslation(0.2,0.0,0)
const dm = mr.multiply(mt)
gl.uniformMatrix4fv(u_Matrix,false,dm.elements)
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT,false,0,0)
gl.enableVertexAttribArray(a_Position)
gl.clearColor(0,0,0,1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.TRIANGLES,0,3)
/**
*
* */
</script>
</html>
矩阵先旋转后位移
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<!-- 定点着色器 -->
<!-- z旋转其实就是以圆心为中心,进行旋转 -->
<script id="vertexShader" type="x-shader/x-vertext">
attribute vec4 a_Position;
uniform mat4 u_Matrix;
void main () {
//列主序
gl_Position = u_Matrix*a_Position;
gl_PointSize = 50.0;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main () {
gl_FragColor = vec4(1, 1, 0, 1);
}
</script>
<script type="module">
import { initShaders } from "./jsm/Utils.js";
import { Matrix4 } from 'https://unpkg.com/three/build/three.module.js';
const canves = document.querySelector('#canvas');
canves.width = window.innerWidth
canves.height = window.innerHeight
// 获取着色器文本
const vsSource = document.querySelector("#vertexShader").innerText;
const fsSource = document.querySelector("#fragmentShader").innerText;
const gl = canves.getContext('webgl')
initShaders(gl, vsSource, fsSource)
const a_Position = gl.getAttribLocation(gl.program, 'a_Position')
// 创建缓冲区
const vertextBuffer = gl.createBuffer();
// 绑定缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER,vertextBuffer)
const floatArray = new Float32Array([
0.0,0.0,
0.0,0.2,
0.2,0.0
])
gl.bufferData(gl.ARRAY_BUFFER, floatArray, gl.STATIC_DRAW)
const u_Matrix = gl.getUniformLocation(gl.program,'u_Matrix')
const mr = new Matrix4()
mr.makeRotationZ(Math.PI)
const mt = new Matrix4()
mt.makeTranslation(0.2,0.0,0)
const dm = mt.multiply(mr)
gl.uniformMatrix4fv(u_Matrix,false,dm.elements)
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT,false,0,0)
gl.enableVertexAttribArray(a_Position)
gl.clearColor(0,0,0,1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.TRIANGLES,0,3)
</script>
</html>
上面两种会产生差异。产生差异的原因如下图所示·
image.png