2017-04-03 62 views
0

我有以下的功能,从JSON文件加载网:设置ShaderMaterial`skinning`属性为TRUE;使“太多制服”的错误

loadJSONModel(filename, modelName) { 
let loader = new THREE.JSONLoader(); 
loader.load(`assets/${filename}`, (geometry, materials) => { 

    let material = Shader.createShaderMaterial(Shader.LINEAR_BLEND_SKINNING_VERT, Shader.BASIC_FRAG); 
    let mesh = new THREE.SkinnedMesh(geometry, material); 
    mesh.material.skinning = true; 
    mesh.rotation.x = 0.5 * Math.PI; 
    mesh.rotation.z = 0.7 * Math.PI; 
    this.scene.add(mesh); 

}); 

其中Shader.createShaderMaterial函数执行以下操作:

static createShaderMaterial(vertex, fragment, uniforms) { 
    if (uniforms === undefined) uniforms = {}; 
    return new THREE.ShaderMaterial({ 
     uniforms: uniforms, 
     vertexShader: vertex, 
     fragmentShader: fragment, 
    }); 
    } 

现在我不断收到这种卑鄙的错误:

THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders ERROR: too many uniforms 

这如果我没有做mesh.material.skinning = true就会消失,但是当然,我需要在着色器中设置蒙皮标志,所以我需要在那里。

我的问题似乎与我迄今为止通过Google找到的其他人不一样。我不会重复使用其他网格中的几何体。我也构建了一个SkinnedMesh,而不是任何旧的网格。我的设置可以支持1024个制服。我很困惑。任何帮助将非常感激。

回答

1

当然它必须是愚蠢的东西一样的事实ThreeJS WebGLProgram在我的着色器文件中的MAX_BONES宏设置为1024,而我是用我的着色器值初始化这个统一:uniform mat4 boneMatrices[MAX_BONES],和我的系统最多只支持1024个制服。

现在的问题是为什么THREE.WebGLProgramsallocateBones功能做到这一点:

function allocateBones(object) { 

     if (capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture) { 

      return 1024; 

     } else { 

      // default for when object is not specified 
      // (for example when prebuilding shader to be used with multiple objects) 
      // 
      // - leave some extra space for other uniforms 
      // - limit here is ANGLE's 254 max uniform vectors 
      // (up to 54 should be safe) 

      var nVertexUniforms = capabilities.maxVertexUniforms; 
      var nVertexMatrices = Math.floor((nVertexUniforms - 20)/4); 

      var maxBones = nVertexMatrices; 

      if (object !== undefined && (object && object.isSkinnedMesh)) { 

       maxBones = Math.min(object.skeleton.bones.length, maxBones); 

       if (maxBones < object.skeleton.bones.length) { 

        console.warn('WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)'); 

       } 

      } 

      return maxBones; 

     } 

    } 

即。为什么满足capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture意味着MAX_BONES自动为1024.但这是另一个问题,在这一点上我不是特别关心的问题。所以我决定只使用RawShaderMaterial并手动将我的MAX_BONES宏设置为适当的值。

+1

这听起来像一个bug ...如果可以的话,three.js将骨骼浮点纹理用于骨骼。如果它不能,那么它使用制服。它使用浮点纹理,因为没有足够的制服。在你的情况下,它看起来像有一个错误,因为在你突出显示的代码中,它认为它可以使用浮点纹理,但是它没有真正使用它们,而是分配太多的制服。 – gman

+0

我最近重新构造了这一点。你介意检查'dev'分支,看看这是否仍然是一个问题? – mrdoob

相关问题