Search code examples
javascriptmatrixspreadwebgpu

Spread not works for Array(16) _wgpuMatrix.mat4.invert return NUll filled array


For matrix transformation i use wgpu-matrix library.

I already have implemented raycast (hit object trigger) in other project. I wanna implement it also in my new project matrix-engine-wgpu.

In this moment input values are correct.


let projectionMatrix = [...object.projectionMatrix]
// after this line i have also object.projectionMatrix filled with NaN  so strange ... I use debugger watch in first pass 

let modelViewProjectionMatrix = [...object.modelViewProjectionMatrix]

ray = unproject([touchCoordinate.x, touchCoordinate.y], 
       [0, 0, touchCoordinate.w, touchCoordinate.h], 
    mat4.invert(outp,object.projectionMatrix),
    mat4.invert(outv,modelViewProjectionMatrix));

Debugger screenshot

I got NaN filled array in unproject func.

export function unproject(
  screenCoord,   // [number, number]
  viewport,      // [number, number, number, number]
  invProjection, // mat4
  invView) {
  // return vec3
  const [left, top, width, height] = viewport;
  const [x, y] = screenCoord;
  console.log("test out x ", x)
  const out = vec4.fromValues((2 * x) / width - 1 - left, (2 * (height - y - 1)) / height - 1, 1, 1);
  vec4.transformMat4(out, out, invProjection);
  out[3] = 0;
  vec4.transformMat4(out, out, invView);
  return vec3.normalize(vec3.create(), out);
}

This is special branch with this problem: https://github.com/zlatnaspirala/matrix-engine-wgpu/tree/RAYCASTER

Instruction for install and running

npm i
npm run main

This line is critical :

    var TEST1 = mat4.invert(outv, modelViewProjectionMatrix)
     console.log("test1 ;; ", TEST1)
     console.log("test2 ;; ", outv)    

output for test1

[ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null ]

output for test2

{ "0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0, "8": 0, "9": 0, "10": 0, "11": 0, "12": 0, "13": 0, "14": 0, "15": 0 }

If i switch mat4.invert(modelViewProjectionMatrix, outv) output :

{ "0": null, "1": null, "2": null, "3": null, "4": 0, "5": 0.7265425324440002, "6": 0, "7": 0, "8": -4.997498035430908, "9": -6.150917053222656, "10": -13.99299430847168, "11": -0.9994995594024658, "12": 4.999997615814209, "13": 6.153993606567383, "14": 12.999993324279785, "15": 0.9999995231628418 }

https://codesandbox.io/p/github/zlatnaspirala/matrix-engine-wgpu/RAYCASTER?file=%2Fsrc%2Fengine%2Fraycast-test.js%3A56%2C31&workspaceId=cd4f340e-85cd-4d71-9715-f9a263cdc951

Any suggestion ?


Solution

  • It seems that

    ray = unproject(
        [touchCoordinate.x, touchCoordinate.y],
        [0, 0, touchCoordinate.w, touchCoordinate.h],
        mat4.inverse(object.projectionMatrix),
        mat4.inverse(object.modelViewProjectionMatrix)
    );
    

    should be sufficient. If you only provide a single (matrix) parameter to inverse, it will simply return with the inverse of that parameter. If you believe inverse is producing the wrong output, you would need to show the matrix being passed in for us to see if that is the case.