Как я могу использовать матрицу из array3d CSS в шейдере WebGL2?CSS

Разбираемся в CSS
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу использовать матрицу из array3d CSS в шейдере WebGL2?

Сообщение Anonymous »

Сейчас у меня есть преобразование CSS Matrix3d, которое мне нравится, скажем, например, следующее:

Код: Выделить всё

transform: matrix3d(1.3453,0.1357,0.0,0.0003,0.2096,1.3453,0.0,0.0003,0.0,0.0,1.0,0.0,-100.0,-100.0,0.0,1.0);
transform-origin: 0 0;
Я использую холст WebGL2, и мне хотелось бы, чтобы изображение, которое я на нем нарисовал, имело такое же преобразование.
Для достижения этой цели , я считаю, что мне нужен вершинный шейдер, чтобы взять матрицу и умножить ее:

Код: Выделить всё

#version 300 es

in vec2 a_position;
in vec2 a_texCoord;
uniform vec2 u_resolution;
out vec2 v_texCoord;

uniform mat4 u_matrix;

void main() {
vec2 zeroToOne = a_position / u_resolution;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 clipSpace = zeroToTwo - 1.0;

gl_Position = u_matrix*vec4(clipSpace * vec2(1, -1), 0, 1);
v_texCoord = a_texCoord;
}
Затем я могу передать матрицу шейдеру в моем коде JavaScript:

Код: Выделить всё

const matrixLocation = gl.getUniformLocation(program, "u_matrix");
gl.uniformMatrix4fv(matrixLocation, false, new Float32Array(matrix));
Сейчас я застрял в выяснении того, каким должно быть значение матрицы в моем коде. Я пытался прочитать, как устроено преобразование Matrix3d, и перестроить матрицу на основе этого, но безуспешно.
Как я могу использовать matrix3d< /code> преобразование в шейдере WebGL2 здесь?
Изменить: полный рабочий пример добавлен по запросу в комментариях.

Код: Выделить всё

#image {
transform: matrix3d(1.3453,0.1357,0.0,0.0003,0.2096,1.3453,0.0,0.0003,0.0,0.0,1.0,0.0,-100.0,-100.0,0.0,1.0);
transform-origin: 0 0;
}
img, canvas {
border: 1px solid #000;
}






// Set up matrices

// Based on: matrix3d(1.3453,0.1357,0.0,0.0003,0.2096,1.3453,0.0,0.0003,0.0,0.0,1.0,0.0,-100.0,-100.0,0.0,1.0)
const cssMatrix = new Float32Array([1.3453,0.1357,0.0,0.0003,0.2096,1.3453,0.0,0.0003,0.0,0.0,1.0,0.0,-100.0,-100.0,0.0,1.0]);
const identityMatrix = new Float32Array([1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]);

// identityMatrix works correctly while the cssMatrix does not
const matrixArray = cssMatrix;
// const matrixArray = identityMatrix;

// Set up shaders

const vertexShaderSource =  `#version 300 es

in vec2 a_position;
in vec2 a_texCoord;

uniform vec2 u_resolution;
uniform mat4 u_matrix;
out vec2 v_texCoord;

void main() {
vec2 zeroToOne = a_position / u_resolution;
vec2 zeroToTwo = zeroToOne * 2.0;
vec2 clipSpace = zeroToTwo - 1.0;

gl_Position = u_matrix*vec4(clipSpace * vec2(1, -1), 0,1);

v_texCoord = a_texCoord;
}`;

const fragmentShaderSource = `#version 300 es

precision highp float;
uniform sampler2D u_image;
in vec2 v_texCoord;
out vec4 outColor;

void main() {
outColor = texture(u_image, v_texCoord);
}`;

// Load the test image

const img = document.getElementById("image");
img.src = "https://i.imgur.com/NIt86ft.png";
img.onload = () => renderImg(img);

// Rest of this code is boilerplate based off of
// https://webgl2fundamentals.org/webgl/lessons/webgl-image-processing.html

function createProgram(
gl, shaders, opt_attribs, opt_locations, opt_errorCallback) {
const errFn = opt_errorCallback || console.error;
const program = gl.createProgram();
shaders.forEach(function(shader) {
gl.attachShader(program, shader);
});
if (opt_attribs) {
opt_attribs.forEach(function(attrib, ndx) {
gl.bindAttribLocation(
program,
opt_locations ? opt_locations[ndx] : ndx,
attrib);
});
}
gl.linkProgram(program);

// Check the link status
const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
// something went wrong with the link
const lastError = gl.getProgramInfoLog(program);
errFn('Error in program linking:' + lastError);

gl.deleteProgram(program);
return null;
}
return program;
}

function loadShader(gl, shaderSource, shaderType, opt_errorCallback) {
const errFn = opt_errorCallback || console.error;
// Create the shader object
const shader = gl.createShader(shaderType);
// Load the shader source
gl.shaderSource(shader, shaderSource);
// Compile the shader
gl.compileShader(shader);
// Check the compile status
const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
// Something went wrong during compilation; get the error
const lastError = gl.getShaderInfoLog(shader);
console.error('*** Error compiling shader \'' + shader + '\':' + lastError + `\n` + shaderSource.split('\n').map((l,i) => `${i + 1}: ${l}`).join('\n'));
gl.deleteShader(shader);
return null;
}
return shader;
}

function createProgramFromSources(
gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {
const shaders = [];
const defaultShaderType = [
'VERTEX_SHADER',
'FRAGMENT_SHADER',
];
for (let ii = 0; ii < shaderSources.length;  ++ii) {
shaders.push(loadShader(
gl, shaderSources[ii], gl[defaultShaderType[ii]], opt_errorCallback));
}
return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback);
}

function resizeCanvasToDisplaySize(canvas, multiplier) {
multiplier = multiplier || 1;
const width  = canvas.clientWidth  * multiplier | 0;
const height = canvas.clientHeight * multiplier | 0;
if (canvas.width !== width ||  canvas.height !== height) {
canvas.width  = width;
canvas.height = height;
return true;
}
return false;
}

function renderImg(image) {
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl2");
if (!gl)
return;

var program = createProgramFromSources(gl, [vertexShaderSource, fragmentShaderSource]);

var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
var texCoordAttributeLocation = gl.getAttribLocation(program, "a_texCoord");
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
var imageLocation = gl.getUniformLocation(program, "u_image");
var matrixLocation = gl.getUniformLocation(program, "u_matrix");

// Create a vertex array object (attribute state)
var vao = gl.createVertexArray();

// and make it the one we're currently working with
gl.bindVertexArray(vao);

// Create a buffer and put a single pixel space rectangle in
// it (2 triangles)
var positionBuffer = gl.createBuffer();

// Turn on the attribute
gl.enableVertexAttribArray(positionAttributeLocation);

// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
var size = 2;          // 2 components per iteration
var type = gl.FLOAT;   // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0;        // start at the beginning of the buffer
gl.vertexAttribPointer(
positionAttributeLocation, size, type, normalize, stride, offset);

// provide texture coordinates for the rectangle.
var texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0,  0.0,
1.0,  0.0,
0.0,  1.0,
0.0,  1.0,
1.0,  0.0,
1.0,  1.0,
]), gl.STATIC_DRAW);

// Turn on the attribute
gl.enableVertexAttribArray(texCoordAttributeLocation);

// Tell the attribute how to get data out of texCoordBuffer (ARRAY_BUFFER)
var size = 2;          // 2 components per iteration
var type = gl.FLOAT;   // the data is 32bit floats
var normalize = false; // don't normalize the data
var stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
var offset = 0;        // start at the beginning of the buffer
gl.vertexAttribPointer(
texCoordAttributeLocation, size, type, normalize, stride, offset);

// Create a texture.
var texture = gl.createTexture();

// make unit 0 the active texture uint
// (ie, the unit all other texture commands will affect
gl.activeTexture(gl.TEXTURE0 + 0);

// Bind it to texture unit 0's 2D bind point
gl.bindTexture(gl.TEXTURE_2D, texture);

// Set the parameters so we don't need mips and so we're not filtering
// and we don't repeat at the edges.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

// Upload the image into the texture.
var mipLevel = 0;               // the largest mip
var internalFormat = gl.RGBA;   // format we want in the texture
var srcFormat = gl.RGBA;        // format of data we are supplying
var srcType = gl.UNSIGNED_BYTE;  // type of data we are supplying
gl.texImage2D(gl.TEXTURE_2D,
mipLevel,
internalFormat,
srcFormat,
srcType,
image);

gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
setRectangle(gl, 0, 0, image.width, image.height);

resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(program);
gl.bindVertexArray(vao);
gl.uniform2f(resolutionLocation, gl.canvas.width, gl.canvas.height);
gl.uniform1i(imageLocation, 0);

gl.uniformMatrix4fv(matrixLocation, false, matrixArray);

gl.drawArrays(gl.TRIANGLES, 0, 6);
}

function setRectangle(gl, x, y, width, height) {
var x1 = x;
var x2 = x + width;
var y1 = y;
var y2 = y + height;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2,
]), gl.STATIC_DRAW);
}



Подробнее здесь: https://stackoverflow.com/questions/786 ... gl2-shader
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как я могу использовать матрицу из array3d CSS в шейдере WebGL2?
    Anonymous » » в форуме CSS
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Как я могу использовать матрицу из array3d CSS в шейдере WebGL2?
    Anonymous » » в форуме CSS
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Как я могу использовать матрицу из CSS array3d в шейдере WebGL2?
    Anonymous » » в форуме CSS
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Как умножить матрицу 2x3x3x3 на матрицу 2x3, чтобы получить матрицу 2x3
    Anonymous » » в форуме Python
    0 Ответы
    64 Просмотры
    Последнее сообщение Anonymous
  • Как умножить матрицу 2x3x3x3 на матрицу 2x3, чтобы получить матрицу 2x3
    Anonymous » » в форуме Python
    0 Ответы
    57 Просмотры
    Последнее сообщение Anonymous

Вернуться в «CSS»