Search code examples
three.jsshaderfragment-shader

Three.js "Fragment shader is not compiled" error when using flat shading


I'm loading a model in three,js using GLTFLoader. It works fine, except I'm trying to use flat shading. If I set flatShading = true, I get an error saying that the fragment shader is not compiled. Here is the code I'm using to load the model:

function loadModel() {
    // Load the model
    gltfLoader.load(modelPath + '.gltf', function (gltf) {
        for (let i = 0; i < gltf.scene.children.length; i++) {
            // Skip bones
            if (gltf.scene.children[i].isBone) {
                continue;
            }

            // If a mesh has multiple segments, then it is a group with an array of children (segments/meshes)
            // If a mesh only has one segment, then it is a single object (mesh) with no children, not an array of length 1
            let numSegments = gltf.scene.children[i].isGroup ? gltf.scene.children[i].children.length : 1;
            for (let j = 0; j < numSegments; j++) {
                let mesh = gltf.scene.children[i].isGroup ? gltf.scene.children[i].children[j] : gltf.scene.children[i];

                mesh.material.flatShading = true;
                //mesh.material.needsUpdate = true;
            }
        }

        // Show the model
        scene.add(gltf.scene);

        }, undefined, function (error) {
            console.log(error);
        }
    );
}

If I omit the flatShading line, the model loads fine. However, with the flatShaing included, I get the following error message:

THREE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false

Program Info Log: Fragment shader is not compiled.


FRAGMENT

ERROR: 0:1233: 'vTBN' : undeclared identifier


  1228:     normal = normalize( normalMatrix * normal );
  1229: #elif defined( TANGENTSPACE_NORMALMAP )
  1230:     vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
  1231:     mapN.xy *= normalScale;
  1232:     #ifdef USE_TANGENT
> 1233:         normal = normalize( vTBN * mapN );
  1234:     #else
  1235:         normal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );
  1236:     #endif
  1237: #elif defined( USE_BUMPMAP )
  1238:     normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );
  1239: #endif

I am using revision 143.

I'm a noob at 3D modeling, so I don't really understand what this error means. If anyone has any suggestions on how to fix this, it would be greatly appreciated.


Solution

  • What you see is a bug in older versions of three.js. When flat shading is enabled and geometry tangents are present, there is a shader compilation error.

    It has been fixed since r154.

    If you can't upgrade your three.js version, traverse through the scene and remove all tangent buffer attributes from the geometries via the following line when using flat shading:

    geometry.deleteAttribute( 'tangent' );