Search code examples
three.jswebglwebgl2

Jittering vertices


I'm trying to get rid of spatial jitter. To be more precise, I'm trying to replicate Three.js behavior concerning matrix manipulation.

My current rendering pipeline (WebGL with m4.js)

There is a scene object, a camera and a mesh. The mesh has its position (mesh.position) set to position and the camera is floating somewhere near it.

Vertices have positions relative to mesh.position:

new Float32Array([
    -5, 0, -5,
    5, 0, -5,
    0, 0, 5
])

Important part of render loop:

const position = {x: 6428439.8443510765, y: 0, z: 4039717.5286310893}; // mesh is located there

camera.updateMatrixWorld();
camera.updateMatrixWorldInverse();

let modelViewMatrix = m4.multiply(camera.matrixWorldInverse, mesh.matrixWorld);

material.uniforms.projectionMatrix = {type: 'Matrix4fv', value: camera.projectionMatrix};
material.uniforms.modelViewMatrix = {type: 'Matrix4fv', value: modelViewMatrix};
material.use();
mesh.draw(material);

Vertex shader:

#version 300 es
precision highp float;
in vec3 position;
in vec3 color;
out vec3 vColor;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

void main() {
    vColor = color;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

Fragment shader:

#version 300 es
precision highp float;
out vec4 FragColor;
in vec3 vColor;
uniform float uSample;

void main() {
  FragColor = vec4(vColor * uSample, 1);
}

Result:

enter image description here

When moving or rotating the camera around the mesh spatial jitter effect is observed, which is not the expected behavior.

I've implemented the same scene using Three.js, and as expected you can see no jitter while moving vertices or camera: Codepen link. Three.js must work exactly the same as my implemetation, but obviously I'm missing something.


Solution

  • It turns out that m4.js which is a part of webgl-3d-math library used on webgl2fundamentals.org utilizes Float32Array objects for storing matrices. Maybe this approach positively affects performance, but it also causes some confusion as JavaScript's Number uses 64-bit floats.