Uncaught TypeError: Cannot read properties of undefined (reading 'world')

hello, I don’t know if it’s a bug and it’s super weird cause it only happens on chrome and not firefox.

webGLPipelineContext.js:296 Uncaught TypeError: Cannot read properties of undefined (reading ‘world’)
at WebGLPipelineContext.setMatrix (webGLPipelineContext.js:296)
at Effect.setMatrix (effect.js:964)
at ShaderMaterial.bindOnlyWorldMatrix (shaderMaterial.js:664)
at ShaderMaterial.bind (shaderMaterial.js:693)
at Mesh.render (mesh.js:1928)
at SubMesh.render (subMesh.js:358)
at RenderingGroup.renderUnsorted (renderingGroup.js:205)
at RenderingGroup.render (renderingGroup.js:105)
at RenderingManager.render (renderingManager.js:87)
at MultiRenderTarget.RenderTargetTexture.renderToTarget (renderTargetTexture.js:834)

in the debugger:

    /**
     * Sets matrix on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGLPipelineContext.prototype.setMatrix = function (uniformName, matrix) {
        if (this._cacheMatrix(uniformName, matrix)) {
            if (!this.engine.setMatrices(this._uniforms[uniformName], matrix.toArray())) {
                this._valueCache[uniformName] = null;
            }
        }
    };

In my code if I remove world:

const material = new ShaderMaterial(
    name,
    scene,
    {
      vertex: "main",
      fragment: "main",
    },
    {
      attributes: ["position", "normal", "modelViewMatrix"],
      uniforms: [
//        "world",
        "viewProjection",
        "lightMatrix0",
        "ambiant",
        "diffuse",
        "ambiantDark",
        "diffuseDark",
        "mapSize",
      ],
      uniformBuffers: ["Light0"],
      samplers: ["shadowSampler0"],
      defines: [
        "#define SHADOWS",
        "#define SHADOW0",
        "#define LIGHT0",
        "#define SHADOWFLOAT",
      ],
    }
  );

it complains for viewProjection.
Obviously this._uniforms seem to be undefined in WebGLPipelineContext.
Any lead of investigation?
I might try to reproduce it in the playground if you have no clue.

1 Like

This is really strange and a playground would definitely help here.

1 Like

https://playground.babylonjs.com/#8RU8Q3#87
It doesn’t, it’s the same usage I have and no issue.

1 Like

This is even harder to tell then :frowning:

Are you using the same version ? is there any repro you could share ?

1 Like

I’m using the exact same version, the repo is not public (yet ?)
I fiddled a bit inside the node_modules to try debugging it.

WebGLPipelineContext.prototype.setMatrix = function (uniformName, matrix) {
    if (!this._uniforms)
      console.log("uniforms", uniformName, this._uniforms, this);
    if (this._cacheMatrix(uniformName, matrix)) {
      if (
        !this.engine.setMatrices(this._uniforms[uniformName], matrix.toArray())
      ) {
        this._valueCache[uniformName] = null;
      }
    }
  };

result:


I’m puzzled, is there some trickery I don’t know in js that could explain that?
Am I facing a V8 bug (since spidermonkey does the job correctly) ?

1 Like

It looks like in your case setMatrix is called to early like rendering before the effect is actually ready. so when you debug it shows it on expand cause the compilation is over.

You d need to look when it is called

2 Likes

Indeed console.log(“uniforms”, uniformName, this._uniforms, { …this }); clarifies it.
putting debugger; in the function, it’s actually called by scene.render() in my render loop function.
stack

It really looks like your material is not ready when rendering which is weird :frowning: A repro would definitely help.

I really don’t know how to reproduce the bug in the playground and my whole code doesn’t stand in a playground.
If you have gitlab I can grant an access to my repo (in PM)

You can share with @vandenberghe.sebastien on gitlab

@Mikael thanks for sharing your code. It highlighted a nice issue in our ShaderMaterial.

Fix is here Fix Shader Material Effect Cache by sebavan · Pull Request #11233 · BabylonJS/Babylon.js · GitHub and will be available in the next release.

At the moment you can when you create a ShaderMaterial set material.checkReadyOnEveryCall = true; to simulate the same code path than the fix.

2 Likes

nice thanks!
I thought I should have putted it in bugs but I wasn’t sure if the problem was on my side.
Glad to been able to help fixing it.

2 Likes