I can't understand this error

Just like I said sometime it appears sometimes it doesn’t. I hope you can help me thanks.

Error:

three.webgpu.js:5465 Uncaught (in promise) TypeError: Cannot read properties of null (reading 'build')
    at Proxy.generate (three.webgpu.js:5465:8)
    at Proxy.build (three.webgpu.js:1719:19)
    at Proxy.build (three.webgpu.js:2165:16)
    at Proxy.generate (three.webgpu.js:4855:50)
    at Proxy.build (three.webgpu.js:1719:19)
    at Proxy.build (three.webgpu.js:2165:16)
    at Proxy.generate (three.webgpu.js:5476:20)
    at Proxy.build (three.webgpu.js:1719:19)
    at Proxy.build (three.webgpu.js:2149:27)
    at Proxy.generate (three.webgpu.js:5476:20)

Code:

export class Grass extends THREE.InstancedMesh {
    constructor(model) {
        var geo, mat;

        model.traverse((e) => {
            if (e.geometry) {
                geo = e.geometry
            }
        })

        var positions = []

        const offset = 0.03
        const xCount = 5
        const yCount = 5
        var count = 0;
        var currentPos;

        for (var x = 0; x < xCount; x += offset) {
            for (var y = 0; y < yCount; y += offset) {
                currentPos = [x, y]
                currentPos[0] += THREE.MathUtils.randFloat(-offset / 2, offset / 2)
                currentPos[1] += THREE.MathUtils.randFloat(-offset / 2, offset / 2)
                positions.push(new THREE.Vector3(currentPos[0], 0, currentPos[1]))
                count++
            }
        }
        console.log(count)
        mat = new THREE.MeshStandardNodeMaterial({ side: THREE.DoubleSide, metalness: 0.2, roughness: 1 })
        var dummyModel = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshStandardMaterial({}))
        super(geo, mat, count)
        this.mat = mat
        this.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
        var instanceOffsets = new Float32Array(count * 3);

        for (var i = 0; i < count; i++) {
            dummyModel.position.copy(positions[i])
            //dummyModel.quaternion.copy(new THREE.Quaternion().setFromEuler(new THREE.Euler(0, THREE.MathUtils.randFloat(-Math.PI / 8, Math.PI / 8), 0)))
            dummyModel.scale.copy(new THREE.Vector3(0.5, 0.75, 0.5))
            dummyModel.updateMatrix()
            this.setMatrixAt(i, dummyModel.matrix)
            instanceOffsets.set(positions[i].toArray(), i * 3);
        }
        this.instanceOffsetAttribute = new THREE.InstancedBufferAttribute(instanceOffsets, 3);
        this.geometry.setAttribute('instanceOffset', this.instanceOffsetAttribute);
        this.needsUpdate = true

        var instanceOffsetNode = TSL.attribute('instanceOffset', 'vec3');

        this.params = {
        }

        var getPaneVar = (name, init, min, max, step) => {
            this.params[name] = init
            var temp = TSL.uniform('float')
            temp.value = init
            var temp2 = pane.addBinding(this.params, name, { min: min, max: max, step: step })
            temp2.on('change', (e) => { temp.value = e.value })
            return temp
        }

        this.time = TSL.uniform('float');

        this.lightWindSpeed = getPaneVar("lightWindSpeed", 0.5, 0, 5, 0.1)
        this.lightWindAmplitude = getPaneVar("lightWindAmplitude", 4, 0, 20, 0.1)
        this.curveInitAngle = getPaneVar("curveInitAngle", 32, 0, 60, 0.1)
        this.curveInitAngleRandom = getPaneVar("curveInitAngleRandom", 7, 0, 20, 0.1)
        this.windDirSpeed = getPaneVar("windDirSpeed", 1, 0, 5, 0.1)
        this.windStrengthSpeed = getPaneVar("windStrengthSpeed", 1, 0, 5, 0.1)
        this.windStrengthIntensity = getPaneVar("windStrengthIntensity", 3, 0, 90, 0.1)

        var transform;

        /* var randomYAngle = TSL.fract(TSL.sin(TSL.)) */

        var randomBendingAngle = TSL.uv().y.mul(TSL.mix(this.curveInitAngle.add(this.curveInitAngleRandom), this.curveInitAngle.add(this.curveInitAngleRandom.mul(-1)), randomYangle))
        var randomBendingAngleMatrix = rotateX(TSL.radians(randomBendingAngle))

        var randomYangle = TSL.fract(TSL.sin(snoise(TSL.instanceIndex)).mul(1234.5678))
        var randomYmatrix = rotateY(randomYangle.mul(TSL.PI2))

        transform = randomBendingAngleMatrix
        transform = transform.mul(randomYmatrix)

        mat.positionNode = TSL.positionLocal.mul(transform)

        mat.normalNode = TSL.transformNormalToView(TSL.normalLocal.mul(transform))

        //mat.colorNode = TSL.vec3(0, randomYangle, 0)
        mat.colorNode = TSL.mix(TSL.vec3(0.05, 0.2, 0.01), TSL.vec3(0.5, 0.5, 0.1), TSL.smoothstep(0, 1, TSL.pow(TSL.uv().y, 2)))

    }

    update(elapsed) {
        this.time.value = elapsed
    }

}

The error message:

“Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘build’)”

indicates that the code is trying to access the build method on a value that is null. In your provided code, one likely culprit is the use of the variable randomYangle before it’s actually defined. Specifically, you call:

var randomBendingAngle = TSL.uv().y.mul(
  TSL.mix(
    this.curveInitAngle.add(this.curveInitAngleRandom),
    this.curveInitAngle.add(this.curveInitAngleRandom.mul(-1)),
    randomYangle   // used here before it’s initialized
  )
)

Later, you initialize randomYangle:

var randomYangle = TSL.fract(TSL.sin(snoise(TSL.instanceIndex)).mul(1234.5678))

Because JavaScript hoists variable declarations with var but does not hoist their assignments, randomYangle is undefined when used in the TSL.mix call. This can lead to the node graph (or any object using TSL functions) building with a null or invalid parameter, which eventually causes the error when it tries to call the build method on that missing object.

Suggested Fix:

Reorder your code so that randomYangle is defined and initialized before it is used. For example:

var randomYangle = TSL.fract(TSL.sin(snoise(TSL.instanceIndex)).mul(1234.5678))
var randomBendingAngle = TSL.uv().y.mul(
  TSL.mix(
    this.curveInitAngle.add(this.curveInitAngleRandom),
    this.curveInitAngle.add(this.curveInitAngleRandom.mul(-1)),
    randomYangle
  )
)
var randomBendingAngleMatrix = rotateX(TSL.radians(randomBendingAngle))
var randomYmatrix = rotateY(randomYangle.mul(TSL.PI2))

This change ensures that all required values are properly initialized before they are used in subsequent calculations, which should prevent the error from occurring.

Additionally, double-check that all dependencies (like TSL, pane, and helper functions such as rotateX and rotateY) are correctly loaded and available when this code runs.

1 Like