首页 > 解决方案 > Three.js 着色器错误:超出最大寄存器限制

问题描述


我正在尝试使用three.js 和socket.io 为现场音乐会创建一个虚拟多人平台。
虽然在单人游戏中一切正常,但是当我尝试进行测试以查看该网站是否可以通过同时创建多个 NPC 来处理大量玩家时,一切都崩溃了,它给了我这些错误:
THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog Varyings over maximum register limit


THREE.WebGLProgram: shader error:  1282 35715 false gl.getProgramInfoLog Varyings over maximum register limit

当我使用这个 for 循环创建超过 8 个 NPC 时出现错误:

for (let i = 0; i < 50; i++) {
        var x,y,z;
        x = Math.random() * 2000;
        x *= Math.round(Math.random()) ? 1 : -1;
        z = Math.random() * (19000-8000)+8000;
        let smurf = new Npc(this, this.options, "Groupie", x, -190, -z, false, "Fan");
        this.npcs.push(smurf);
        this.remoteNPCsColliders.push(smurf);
    }

从我通过three.js 文档了解到的情况来看,问题在于同时传递了太多的变量,但与此同时,变量似乎是来自着色器的附加数据,在我的代码中没有使用。这是 NPC 对象代码:

class Npc {
  constructor(game, options, identifier, x, y, z, conv, type) {
    let model, colour;

    const colours = ['Black', 'Brown', 'White'];
    colour = colours[Math.floor(Math.random() * colours.length)];

    if (options === undefined) {
      const people = ['BeachBabe', 'BusinessMan', 'Doctor', 'FireFighter', 'Housewife', 'Policeman', 'Prostitute', 'Punk', 'RiotCop', 'Roadworker', 'Robber', 'Sheriff', 'Streetman', 'Waitress'];
      model = people[Math.floor(Math.random() * people.length)];
    }
    this.model = model;
    this.colour = colour;
    this.game = game;
    this.animations = this.game.animations;

    const geometry = new THREE.BoxGeometry(100, 300, 100);
    const material = new THREE.MeshBasicMaterial({
      visible: false
    });
    const box = new THREE.Mesh(geometry, material);
    box.name = "Collider";
    box.position.set(0, 150, 0);
    this.collider = box;

    const loader = new FBXLoader();
    const npc = this;


    loader.load(`${game.assetsPath}fbx/people/${type}.fbx`, function(object) {

      object.mixer = new THREE.AnimationMixer(object);
      npc.root = object;
      npc.mixer = object.mixer;

      object.name = identifier;
      object.conv = conv;

      object.traverse(function(child) {
        if (child.isMesh) {
          child.castShadow = true;
          child.receiveShadow = true;
        }
      });

      const textureLoader = new THREE.TextureLoader();

      npc.object = new THREE.Object3D();
      npc.object.position.set(x, y, z);
      //npc.object.position.set(0, 0, 0);
      npc.object.rotation.set(0, -Math.PI / 2, 0);
      npc.object.scale.set(2.3, 2.3, 2.3);

      npc.object.add(object);
      if (npc.deleted === undefined) game.scene.add(npc.object);

      npc.object.add(box);

      //if (game.animations.Idle!==undefined) npc.action = "Happy";
      npc.action = object.animations[0]
    });
  }
    set action(name){
        //Make a copy of the clip if this is a remote player
        if (this.actionName == name) return;
        const clip = this.animations[name];
        const action = this.mixer.clipAction( name );
        action.time = 0;
        this.mixer.stopAllAction();
        
        action.startAt(0.03333);
        this.actionName = name;
        this.actionTime = Date.now();

        action.fadeIn(0.5);
        action.play();
    }
    get action(){
        return this.actionName;
    }
}

我试过在这里注释每一段代码,但没有成功。修复错误的唯一方法是禁用渲染器的阴影贴图,但由于某种原因,整个贴图曝光过度,导致一切无法播放。
我能找到的关于该主题的唯一其他问题将问题放在灯光上,我想这可能是一个解释,因为禁用阴影贴图修复了错误,但我已经禁用了每一盏灯,错误仍然发生。

我真的为此发疯了,我希望有人能帮助我!

标签: javascriptthree.jswebgl

解决方案


推荐阅读