glsl es 2.0 inverse matrix
Asked Answered
L

3

8

There is no inverse command in glsl es 2.0
But I saw that I can 1.0/mat2 . But I fear it'll just divide component wisely. Or not?
But if so, is there some trick for this (get 1/det fast)?

Lippi answered 25/3, 2014 at 18:45 Comment(0)
H
7

No, there's no matrix inverse function in GLSL ES 1.00 (used in OpenGL ES 2.0). You'll need to do it manually, take a look e.g. here. But you should think hard whether you really need to do it in the shader on a per-vertex or per-fragment basis every frame, or is it possible to be precomputed and passed in as uniform.

Hysteria answered 26/3, 2014 at 7:41 Comment(1)
Belive me, I think really hard on this. By the way it is faster to calculate determinant as a dot product.Lippi
Z
1

To add to the response from Arttu Peltonen, for mat3, you can use the following inverse function:

float det(mat2 matrix) {
    return matrix[0].x * matrix[1].y - matrix[0].y * matrix[1].x;
}

mat3 inverse(mat3 matrix) {
    vec3 row0 = matrix[0];
    vec3 row1 = matrix[1];
    vec3 row2 = matrix[2];

    vec3 minors0 = vec3(
        det(mat2(row1.y, row1.z, row2.y, row2.z)),
        det(mat2(row1.z, row1.x, row2.z, row2.x)),
        det(mat2(row1.x, row1.y, row2.x, row2.y))
    );
    vec3 minors1 = vec3(
        det(mat2(row2.y, row2.z, row0.y, row0.z)),
        det(mat2(row2.z, row2.x, row0.z, row0.x)),
        det(mat2(row2.x, row2.y, row0.x, row0.y))
    );
    vec3 minors2 = vec3(
        det(mat2(row0.y, row0.z, row1.y, row1.z)),
        det(mat2(row0.z, row0.x, row1.z, row1.x)),
        det(mat2(row0.x, row0.y, row1.x, row1.y))
    );

    mat3 adj = transpose(mat3(minors0, minors1, minors2));

    return (1.0 / dot(row0, minors0)) * adj;
}
Zanze answered 27/10, 2020 at 23:32 Comment(0)
G
0

I think there is an error. Is better to use the cofactor matrix:

float det(mat2 matrix) {
    return matrix[0].x * matrix[1].y - matrix[0].y * matrix[1].x;
}

mat3 inverse(mat3 matrix) {
    vec3 row0 = matrix[0];
    vec3 row1 = matrix[1];
    vec3 row2 = matrix[2];

    vec3 cof0 = vec3(
        det(mat2(row1.y, row1.z, row2.y, row2.z)),
        -det(mat2(row1.z, row1.x, row2.z, row2.x)),
        det(mat2(row1.x, row1.y, row2.x, row2.y))
    );
    vec3 cof1 = vec3(
        -det(mat2(row2.y, row2.z, row0.y, row0.z)),
        det(mat2(row2.z, row2.x, row0.z, row0.x)),
        -det(mat2(row2.x, row2.y, row0.x, row0.y))
    );
    vec3 cof2 = vec3(
        det(mat2(row0.y, row0.z, row1.y, row1.z)),
        -det(mat2(row0.z, row0.x, row1.z, row1.x)),
        det(mat2(row0.x, row0.y, row1.x, row1.y))
    );

    mat3 adj = transpose(mat3(cof0, cof1, cof2));

    return (1.0 / dot(row0, cof0)) * adj;
}

Please check.

Greensickness answered 11/12, 2022 at 18:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.