Я пытался использовать свои собственные матрицы в WebGL (на данный момент 2d). Моя основная ссылка - webglfundamentals.com . Я умножаю поворот на 360 градусов на масштаб (1, -1), (-142, 6) перенос и матрицу проекции. Мой прямоугольник отображается нормально, но без перевода. Вот мой код:
var vertexShaderSource= `
attribute vec3 a_position;
uniform mat3 u_matrix;
void main() {
gl_Position = vec4(vec2(u_matrix * a_position), 0, 1);
}`
var fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1, 0, 0.5, 1);
}`
var canvas = document.querySelector("#c");
var gl = canvas.getContext("webgl");
var m3 = {
multiply: function(a, b) {
return [
b[0] * a[0] + b[1] * a[3] + b[2] * a[6],
b[0] * a[1] + b[1] * a[4] + b[2] * a[7],
b[0] * a[2] + b[1] * a[5] + b[2] * a[8],
b[3] * a[0] + b[4] * a[3] + b[5] * a[6],
b[3] * a[1] + b[4] * a[4] + b[5] * a[7],
b[3] * a[2] + b[4] * a[5] + b[5] * a[8],
b[6] * a[0] + b[7] * a[3] + b[8] * a[6],
b[6] * a[1] + b[7] * a[4] + b[8] * a[7],
b[6] * a[2] + b[7] * a[5] + b[8] * a[8],
];
},
translation: function(tx, ty) {
return [
1, 0, 0,
0, 1, 0,
tx, ty, 1,
];
},
rotation: function(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c, -s, 0,
s, c, 0,
0, 0, 1,
];
},
scaling: function(sx, sy) {
return [
sx, 0, 0,
0, sy, 0,
0, 0, 1,
];
},
projection: [
2 / gl.canvas.clientWidth, 0, 0,
0, -2 / gl.canvas.clientHeight, 0,
-1, 1, 1
]
}
function createShader(gl, type, source) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS))
return shader;
console.log(gl.getShaderInfoLog(shader));
return null;
}
var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
function createProgram(gl, vertexShader, fragmentShader) {
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (gl.getProgramParameter(program, gl.LINK_STATUS))
return program;
console.log(gl.getProgramInfoLog(program));
return null;
}
var program = createProgram(gl, vertexShader, fragmentShader);
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
var positions = [
10, 20,
80, 20,
10, 30,
10, 30,
80, 20,
80, 30
];
var translationMatrix = m3.translation(-142, 6);
var rotationMatrix = m3.rotation(Math.PI * 2);
var scaleMatrix = m3.scaling(1, -1);
var matrix = m3.multiply(m3.projection, translationMatrix);
matrix = m3.multiply(matrix, rotationMatrix);
matrix = m3.multiply(matrix, scaleMatrix);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
var resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
var matrixLocation = gl.getUniformLocation(program, "u_matrix");
gl.viewport(0, 0, 800, 600);
gl.clearColor(0.4, 0.4, 0.4, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.uniform2f(resolutionUniformLocation, 800, 600);
gl.uniformMatrix3fv(matrixLocation, false, matrix);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.drawArrays(gl.TRIANGLES, 0, positions.length / 2);
<html>
<head>
<title>webgl</title>
<meta charset="UTF-8">
<script src="gl-matrix.js"></script>
</head>
<body style="background-color: #222223;">
<canvas id="c" tabindex="1" width="800" height="600">get good browser</canvas>
</body>
</html>
Если я добавлю такой перевод: gl_Position = vec4(a_position + translation, 1);
, очки будут переведены. Однако это лишает смысла использование матриц.