regl-project / regl

👑 Functional WebGL
https://regl-project.github.io/
MIT License
5.24k stars 322 forks source link

Uncaught TypeError: Cannot create property 'buffer' on number '0' #526

Open kevzettler opened 5 years ago

kevzettler commented 5 years ago

Stumped on this issue. Its stemming from the generated code making it hard to debug. The error message is not transparent. This is on ─ regl@1.3.1

trying to set .buffer on v52

Uncaught TypeError: Cannot create property 'buffer' on number '0'
    at Object.body (eval at compile (regl.js:5409), <anonymous>:120:11)
    at Object.batch (eval at compile (regl.js:5409), <anonymous>:1968:6)
    at Object.REGLCommand [as ShadowCap] (regl.js:9293)
    at Game3D.jsx:135
    at Object.scope (eval at compile (regl.js:5409), <anonymous>:354:1)
    at Object.REGLCommand [as ShadowScope] (regl.js:9272)
    at Game3D.jsx:134
    at Object.scope (eval at compile (regl.js:5409), <anonymous>:340:1)
    at Object.REGLCommand [as Pass2Stencil] (regl.js:9272)
    at Game3D.cameraContext (Game3D.jsx:132)
    at Object.scope (eval at compile (regl.js:5409), <anonymous>:362:1)
    at Object.REGLCommand [as Camera] (regl.js:9285)
    at Game3D.renderTick (Game3D.jsx:111)
    at Timer.tick (fixed-game-loop.js:122)
return {
"body":function(a0,a1){
var v52,v53;
var v93,v97,v130,v218,v219,v220;
v93=v11[2];
if(!(v16(v93)&&v93.length===16))g17.commandRaise(g94,g51);
v1.uniformMatrix4fv(g92.location,false,(Array.isArray(v93)||v93 instanceof Float32Array)?v93:(v95[0]=v93[0],v95[1]=v93[1],v95[2]=v93[2],v95[3]=v93[3],v95[4]=v93[4],v95[5]=v93[5],v95[6]=v93[6],v95[7]=v93[7],v95[8]=v93[8],v95[9]=v93[9],v95[10]=v93[10],v95[11]=v93[11],v95[12]=v93[12],v95[13]=v93[13],v95[14]=v93[14],v95[15]=v93[15],v95));
v97=v11[3];
if(!(v16(v97)&&v97.length===16))g17.commandRaise(g98,g51);
v1.uniformMatrix4fv(g96.location,false,(Array.isArray(v97)||v97 instanceof Float32Array)?v97:(v99[0]=v97[0],v99[1]=v97[1],v99[2]=v97[2],v99[3]=v97[3],v99[4]=v97[4],v99[5]=v97[5],v99[6]=v97[6],v99[7]=v97[7],v99[8]=v97[8],v99[9]=v97[9],v99[10]=v97[10],v99[11]=v97[11],v99[12]=v97[12],v99[13]=v97[13],v99[14]=v97[14],v99[15]=v97[15],v99));
v130=v11[1];
if(!(v16(v130)&&v130.length===3))g17.commandRaise(g131,g51);
v1.uniform3f(g129.location,v130[0],v130[1],v130[2]);
v218=v6.elements;
if(v218)v1.bindBuffer(34963,v218.buffer.buffer);
v219=v6.primitive;
v220=v6.offset;
for(v52=0;
v52<a1;
++v52){
v53=a0[v52];
var v54,v56,v57,v58,v59,v60,v61,v62,v63,v64,v65,v66,v67,v68,v70,v71,v72,v73,v75,v76,v77,v78,v79,v80,v81,v82,v83,v84,v85,v86,v87,v89,v90,v91,v132,v135,v138,v140,v143,v146,v149,v152,v155,v158,v161,v164,v167,v170,v173,v176,v179,v182,v185,v188,v191,v194,v197,v200,v203,v206,v209,v212,v215,v221;
v54=v53["aomesh"];
v52.buffer=v54;

as var as I can tell v52 is a for loop iterator value for attributes?

for(v52=0;
v52<a1;
++v52){
kevzettler commented 5 years ago

just upgraded to regl@1.3.11 and still seeing it

rreusser commented 5 years ago

Yeah that looks maybe somewhat unlikely to be a valid behavior, even if it were to result from incorrect usage. I wasn't immediately able to track down the source in lib/core.js, though I have had luck trying to do that in the past, specifically by requiring require('regl/regl.js') and instrumenting the code manually instead of the default main import. I don't imagine you have any more context about the specific usage or path in lib/core that's triggering this? (Also, did you find the tiny little {} pretty-print button in the chrome source inspector? It can really help make sense of this generated code, though it does seem like you've tracked it down pretty well.)

kevzettler commented 5 years ago

Thanks much @rreusser I will update this thread with anymore info as I dig in. Do you have any further suggestions for debugging? is there a debug version or something that clarifies the generated cod?

Here is the pretty print version

for (v52 = 0; v52 < a1; ++v52) {
                v53 = a0[v52];
                var v54, v56, v57, v58, v59, v60, v61, v62, v63, v64, v65, v66, v67, v68, v70, v71, v72, v73, v75, v76, v77, v78, v79, v80, v81, v82, v83, v84, v85, v86, v87, v89, v90, v91, v132, v135, v138, v140, v143, v146, v149, v152, v155, v158, v161, v164, v167, v170, v173, v176, v179, v182, v185, v188, v191, v194, v197, v200, v203, v206, v209, v212, v215, v221;
                v54 = v53["aomesh"];
                v53.buffer = v54;
                if (!(v53 && (typeof v53 === "object" || typeof v53 === "function") && (v15(v53) || v8.getBuffer(v53) || v8.getBuffer(v53.buffer) || v15(v53.buffer) || ("constant"in v53 && (typeof v53.constant === "number" || v16(v53.constant))))))
                    g17.commandRaise(g55, g51);
                v56 = false;
                v57 = 1;
                v58 = 0;
                v59 = 0;
                v60 = 0;
                v61 = 0;
                v62 = null;
                v63 = 0;
                v64 = false;
                v65 = 5126;
                v66 = 0;
                v67 = 0;
                v68 = 0;
                if (v15(v53)) {
                    v56 = true;
                    v62 = v8.createStream(34962, v53);
                    v65 = v62.dtype;
                } else {
                    v62 = v8.getBuffer(v53);
                    if (v62) {
                        v65 = v62.dtype;
                    } else if ("constant"in v53) {
                        v57 = 2;
                        if (typeof v53.constant === "number") {
                            v58 = v53.constant;
                            v59 = v60 = v61 = 0;
                        } else {
                            v58 = v53.constant.length >= 0 ? v53.constant[0] : 0;
                            v59 = v53.constant.length >= 1 ? v53.constant[1] : 0;
                            v60 = v53.constant.length >= 2 ? v53.constant[2] : 0;
                            v61 = v53.constant.length >= 3 ? v53.constant[3] : 0;
                        }
                    } else {
                        if (v15(v53.buffer)) {
                            v62 = v8.createStream(34962, v53.buffer);
                        } else {
                            v62 = v8.getBuffer(v53.buffer);
                        }
                        v65 = "type"in v53 ? [v53.type] : v62.dtype;
                        v64 = !!v53.normalized;
                        v63 = v53.size | 0;
                        v66 = v53.offset | 0;
                        v67 = v53.stride | 0;
                        v68 = v53.divisor | 0;
                    }
                }
                v70 = g69.location;
                v71 = v10[v70];
                if (v57 === 1) {
                    if (!v71.buffer) {
                        v1.enableVertexAttribArray(v70);
                    }
                    v72 = v63 || 4;
                    if (v71.type !== v65 || v71.size !== v72 || v71.buffer !== v62 || v71.normalized !== v64 || v71.offset !== v66 || v71.stride !== v67) {
                        v1.bindBuffer(34962, v62.buffer);
                        v1.vertexAttribPointer(v70, v72, v65, v64, v67, v66);
                        v71.type = v65;
                        v71.size = v72;
                        v71.buffer = v62;
                        v71.normalized = v64;
                        v71.offset = v66;
                        v71.stride = v67;
                    }
                } else {
                    if (v71.buffer) {
                        v1.disableVertexAttribArray(v70);
                    }
                    if (v71.x !== v58 || v71.y !== v59 || v71.z !== v60 || v71.w !== v61) {
                        v1.vertexAttrib4f(v70, v58, v59, v60, v61);
                        v71.x = v58;
                        v71.y = v59;
                        v71.z = v60;
                        v71.w = v61;
                    }
                }
                v73 = v53["aomesh"];
                v52.buffer = v73; //Throws exception here...
kevzettler commented 5 years ago

Some more context...

I encountered this while trying to reproduce the shadow volume example at: https://github.com/regl-project/regl/blob/gh-pages/example/shadow-volume.js

I narrowed it down to the draw calls at this section of the code https://github.com/regl-project/regl/blob/gh-pages/example/shadow-volume.js#L530-L538

        pass2(() => {
          regl.clear({stencil: 0})
          shadowScope(() => {
            for (var i = 0; i < rabbits.length; i++) {
              drawShadowSilhoutte({model: rabbits[i]})
              drawShadowCaps({model: rabbits[i]})
            }
          })
        })

in my projected I had simplified it as

      this.regl.draw.Pass2Stencil(() => {
        this.regl.clear({stencil: 0});
        this.ShadowScope(() => {
          this.regl.draw.ShadowCap(statics);
        })
      });

I currently have a avoided the exception being thrown by moving the frag shader from ShadowScope into ShadowCap and removing the additional context call:

      this.regl.draw.Pass2Stencil(() => {
        this.regl.clear({stencil: 0});
        this.regl.draw.ShadowCap(statics);
      });