将ShaderMaterial“skinning”属性设置为“true”会导致“制服太多”错误

时间:2017-04-03 17:06:31

标签: three.js glsl

我有以下函数从JSON文件加载网格:

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 个答案:

答案 0 :(得分:1)

当然,它必须是愚蠢的事情,就像ThreeJS WebGLProgram将我的着色器文件中的MAX_BONES宏设置为1024,并且我在我的着色器中使用该值来初始化这个制服:{{ 1}},我的系统最多只支持1024个制服

现在问题是uniform mat4 boneMatrices[MAX_BONES]的{​​{1}}函数执行此操作的原因:

allocateBones

即。为什么满足THREE.WebGLPrograms需要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; } } 自动为1024.但这是另一个问题,而且我现在并不特别关注这个问题。所以我决定只使用capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture并手动将我的MAX_BONES宏设置为适当的值。