2017-04-03 50 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

相關問題