Three.js: composer.render() has strange dependency on EffectComposer

Created on 31 May 2016  路  5Comments  路  Source: mrdoob/three.js

Description of the problem

When calling composer.render() I get this strange error in the Chrome console. EXCEPTION: TypeError: Right-hand side of 'instanceof' is not an object.

When I swap it out for the WebGLRenderer everything is fine. I log the composer and it is defined and all passes are visible in Chrome Devtools. The Stacktrace points to this line of EffectComposer.js:

if ( pass instanceof THREE.MaskPass ) {

If I am interpreting this correctly, it means I need to also load THREE.MaskPass into my project as a dependency to even use EffectComposer. This seems like an architectural flaw and it also appears to be a circular dependency since THREE.MaskPass depends on THREE.Pass which is found in EffectComposer.js. Indeed, loading THREE.MaskPass I was able to resolve the error.

Three.js version
  • [ ] Dev
  • [x] r77
  • [ ] ...

    Browser
  • [ ] All of them

  • [x] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer

    OS
  • [x] All of them

  • [ ] Windows
  • [ ] Linux
  • [ ] Android
  • [ ] IOS
    Hardware Requirements (graphics card, VR Device, ...)

Most helpful comment

Implemented!

All 5 comments

three.js uses a pass chain to describe post-processing effects. EffectComposer currently needs to evaluate the type of each pass to identify an active mask operation (see maskActive in EffectComposer .render()). In other words, the appearance of an instance of MaskPass in the chain enables masking, the appearance of ClearMaskPass disables masking.

If we want to solve the dependency of EffectComposer to MaskPass/ClearMaskPass, we need a different approach to check ongoing masking. Maybe one solution would be to directly evaluate WebGLState or WebGLStencilBuffer.

@mugen87 That's fine, but the EffectComposer doesn't need to do this if the user does not need a Mask. It doesn't make sense to include dependencies in a project that are not required. I think all that needs to happen is the if statement should become :

if ( THREE.MaskPass !== undefined && pass instanceof THREE.MaskPass ) {

The browser can't check instanceof if the variable in question (THREE.MaskPass) is not of type 'Object'. Since THREE.MaskPass is undefined then instanceof fails.

Good point! I think we can implement this as a workaround. It does not solve the conceptual problem but it will avoid the mentioned runtime error. So instead of

if ( pass instanceof THREE.MaskPass ) {

    maskActive = true;

} else if ( pass instanceof THREE.ClearMaskPass ) {

    maskActive = false;

}

we have

if ( THREE.MaskPass !== undefined && pass instanceof THREE.MaskPass ) {

    maskActive = true;

} else if ( THREE.ClearMaskPass !== undefined && pass instanceof THREE.ClearMaskPass ) {

    maskActive = false;

}

@steveblue Okay like this?

if ( THREE.MaskPass !== undefined ) {

    if ( pass instanceof THREE.MaskPass ) {

        maskActive = true;

    } else if ( pass instanceof THREE.ClearMaskPass ) {

        maskActive = false;

    }

}

馃槉

Implemented!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yqrashawn picture yqrashawn  路  3Comments

jack-jun picture jack-jun  路  3Comments

akshaysrin picture akshaysrin  路  3Comments

konijn picture konijn  路  3Comments

seep picture seep  路  3Comments