Three.js: Texture render issue on latest Chrome [Version 50.0.2661.75 m]

Created on 18 Apr 2016  路  36Comments  路  Source: mrdoob/three.js

Description of the problem

Hi there. This is the error message:

[.CommandBufferContext]RENDER WARNING: there is no texture bound to the unit 1

I try to ignore these warnings, but sometimes (more than 50% time in my 3D Game) it will stop loading textures. It drove me crazy for a whole day and finally found it was caused by the latest Chrome update [Version 50.0.2661.75 m]. (Chrome was updated from [Version 49.0.2623.110 m])

This is my test code for the issue:
test link for [r75]
test link for [dev]

It is a simple environment to reproduce the issue. It looks fine in this example, but if the scene is complex enough, some textures will be missing.

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

    Browser
  • [ ] All of them

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

    OS
  • [ ] All of them

  • [x] Windows
  • [ ] Linux
  • [ ] Android
  • [ ] IOS
    Hardware Requirements

Hardware isn't relevant.

Most helpful comment

Fixed!

All 36 comments

This is my test code for the issue: https://github.com/Rendxx/Test-ThreeJS/blob/master/TestThreeJS/LightIssue/sample.html

Do you mind doing a gh-pages in that repo? That way we'll be able to directly test https://Rendxx.github.io/Test-ThreeJS/TestThreeJS/LightIssue/sample.html

Also, have you tried with the build in the dev branch?

I have just created gh-pages for r75 and dev, here are the links:
test link for [r75]
test link for [dev]

Using the build in dev branch did not fix it. I have tested with r74 before and that did not help.

I guess there may be something different in shadow handling after Chrome updating.
In the test page, setting castShadow = false; on both spot lights (There are 2 in the test scene) will reduce the warning report number from infinity to 1 in r75 test, and clear all warning in dev test.

Also, removing any of the spot lights will make all warning disappeared.

Hope there information help.

I can duplicate the warning using the webgl_animation_cloth.html example in the dev branch. The flag renders black.

After removing the directional light, the scene renders normally, but the warning remains.

OS X 10.11.4, Chrome 50.0.2661.75 (64-bit).

I can duplicate the warning using the webgl_animation_cloth.html example in the dev branch. The flag renders black.

Yes! It renders black in r75 as well. I am using Window and Chrome.

I'm having this today as well, chrome updated over night: Version 50.0.2661.75 (64-bit)

It's worth reiterating that this only happens ~50% of the time so it might take a few refreshes to reproduce

Seems to be the same issue as #8670.

Loading image textures via TextureLoader and warning '[.CommandBufferContext]RENDER WARNING: there is no texture bound to the unit 1' - are different problems and should have different issues. First can be solved if convert textures to some compressed format like 'dds' and use DDSLoader. But even with correctly loaded textures usage of shadow map generates those warnings.

@linkedz I agree.
This warnings keep coming up even if I stop using image texture.
To reproduce this warning, we only need:

  • 2 or more spot light with more than 1 of them castShadow = true;
  • at least 1 mesh with receiveShadow = true;

Here are 2 new tests, simpler than the previous ones (only 2 spot lights and 1 plane in them):
test link for [r75] 2
test link for [r76] 2

I just noticed something strange:
If I set the second spot light castShadow = false, the warning message is:

[.CommandBufferContext]RENDER WARNING: there is no texture bound to the unit 1

but if I set the first spot light castShadow = false instead, the error message change to:

[.CommandBufferContext]RENDER WARNING: there is no texture bound to the unit 0

I don't know what does that mean by now. I am still looking into shaders and shadow map. Not sure whether this is relative to the TextureLoader issue. The guess is something is not right and stop loading following textures, or maybe in the opposite way.

I will run after the warning message, hopefully it could lead me to some interesting result.

Hi all.
I reproduced this warning with only WebGL.
Here are new test page:
Test with warning
Test without warning

The only difference is lacking of these 2 line of code in sample-warning.js

    gl.activeTexture(gl.TEXTURE1);
    gl.bindTexture(gl.TEXTURE_2D, textures[1]);

It looks like there is a different mechanism to handle multiple textures in latest chrome. So the links to multiple "shadow textures" may be broken in this way.

Well, I misunderstanded what @linkedz mean. These 2 issues are not unrelated. Thanks for the suggestion of dds.

Could this be some load order thing. I seem to get this more if I disable network cache in the Chrome dev tools network tab. If you disable it it is more likely to happen.

I'm using this page to test http://threejs.org/examples/#webgl_loader_obj

The /examples/textures/UV_Grid_Sm.jpg texture has a Cache-Control:max-age=600. If cache is enabled, you'll get a quick 304 or directly using from cache (inside that 10mins, this can vary on Chrome thinks you are doing, if it will check 304 or not). When its returned from cache it's more likely the texture is already there before next render is called and you wont get this warning.

I can repro getting the black texture more often and those warnings if I disable cache (though not every time). This could be some kind of timing issue. The OBJLoader is doing this https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_obj.html#L93-L110

So when it it not read quickly from cache the material is initialized in render before the texture is in place.

Futhermore our app loads the textures to the material fully before its set to any meshes. Hence they will be initialized in render() only when textures are in place. It looks like we dont get these warnings even if cache is disabled. Some code that does not follow this pattern did produce the warnings :P

Just my 2 cents. Might be something that happens if material.needsUpdate = true; is set after the first material init.

Edit: Sometimes with cache disabled you can see the black texture there for a moment, then get few of those warnings, then the real texture is updated. Most times the last step is not done and you end up with black.

This console log from the above when cache is disabled I think is helpful:

      THREE.WebGLRenderer 76
      webgl_loader_obj.html:85 1% downloaded
(2x)  webgl_loader_obj.html:85 70% downloaded
      webgl_loader_obj.html:85 100% downloaded
      OBJLoader.js:558 OBJLoader: 33.298ms
      webgl_loader_obj.html:76 obj/male02/male02.obj 1 2
(2x)  webgl_loader_obj.html:1 [.CommandBufferContext]RENDER WARNING: there is no texture bound to the unit 0
      webgl_loader_obj.html:76 textures/UV_Grid_Sm.jpg 2 2
(26x) webgl_loader_obj.html:1 [.CommandBufferContext]RENDER WARNING: there is no texture bound to the unit 0
      < no more errors, and its not because of webgl said too many errors, 
       but because the texture is now fine >

This is a run where it was black (2x + 26x render() calls), but then loaded the texture and it stopped printing warnings. Usually WebGL says "too many warnings, no more will be printed", but this run it stopped because the cause of the warning went away. If that makes sense.

Looks to me like its related to using materials with unfinished (null texture units) texture loads in them. Then afterwards updating the texture and mat.needsUpdate = true;.

I found a temporary solution (thanks @hbriceno), don't know how useful it is for you guys, but this solves the problem for me.
I use the r75 and in THREE.ImageLoader.prototype replaced the load: function ( url, onLoad, onProgress, onError ) function body with this:

        if ( this.path !== undefined ) url = this.path + url;

        var scope = this;

        var cached = THREE.Cache.get( url );

        if ( cached !== undefined ) {

            scope.manager.itemStart( url );

            if ( onLoad ) {

                setTimeout( function () {

                    onLoad( cached );

                    scope.manager.itemEnd( url );

                }, 0 );

            } else {

                scope.manager.itemEnd( url );

            }

            return cached;

        }

        var image = document.createElement( 'img' );

        image.addEventListener( 'load', function ( event ) {    }, false );

        if ( onProgress !== undefined ) {

            image.addEventListener( 'progress', function ( event ) {

                onProgress( event );

            }, false );

        }

        image.addEventListener( 'error', function ( event ) {

            if ( onError ) onError( event );

            scope.manager.itemError( url );

        }, false );

        if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin;

        scope.manager.itemStart( url );

        image.src = url;

        var checkingClearId = setInterval(function () {
            if (isImageLoaded(image)) {
                clearInterval(checkingClearId);
                THREE.Cache.add( url, image );

                if ( onLoad ) onLoad( image );

                scope.manager.itemEnd( url );
            }

        }, 100);

        function isImageLoaded(imgTag){
            return imgTag["complete"] || imgTag["readyState"] == "complete";
        };
        return image;

Here I removed the onload event listener, as the problem is this event not being triggered at all.
Instead I added an interval that checks the status of the image every 100 ms.
nothing genius, but this saved my project for now.

Is the global THREE.Cache enabled by default in the latest release?

This is good idea @aramavetisyan .

In my own project, I used dds files instead. That did solve part of the problem (and I met another problem of loading blender models with dds texture).
The good news is, this image loading issue seems to be fixed in latest version of Chrome Canary. Hopefully, next update of Chrome will include this fix.

And the empty (black) texture issue is not relative to the warning message. The test I gave before just reproduce the warning message, not the texture problem. At first I thought the black texture may be caused by a broken shadow map, but this is not true.

For texture problem: go to #8670 for more details.
For warning problem:
In the shader, if you run code like vec4 color1 = texture2D(u_image1, v_texCoord); in fragment-shader before binding a texture to u_image1, there will be a warning. It will not "break" the texture if you ignore it in this case (three.js handled this situation but my test case didn't).

Is the global THREE.Cache enabled by default in the latest release?

Nope.

As previously noted, this is a Chrome regression. It's been fixed already in beta/dev and they are trying to backport to Chrome 50.

Cool, do you have link to their tracker or something. Would be interested to read more.

@jonnenauha should be this one #604944

Thanks. That looks like a pretty serious bug :) I cant really tell if its just webgl related, related or any load event listener (I would doubt that). But looks like they agree this should go to a 50 update (https://bugs.chromium.org/p/chromium/issues/detail?id=586183#c43).

Now that I think of it, I actually got this while working on my objloader PR branch, was wondering what the hell was going on. Had to hit F5 a lot of times before getting all the model textures loaded to take screenshots.

Can we expect chrome guys to give an update anytime sooner? It is becoming a blocking issue as many systems are on auto update for chrome.

If chrome would delay its update will have to figure out some kind of work around. Any suggestions plz?

@admin-3dphy The workaround for the Chrome 50 loading bug is to retain a reference to the image in order to avoid premature garbage collection. See an example workaround for THREE.ImageLoader in #8670.

As far as I understand this bug is not about Chrome skipping texture loads (see #8670 for that).
@Rendxx test pages (r75,r76) do not load any external textures and show the warning

RENDER WARNING: there is no texture bound to the unit x

in Chrome (M50 + Canary) but none in Firefox Nightly.
This seems to be related to _shadow maps_ and not to external textures.

I'm seeing the same infinite warning message. After reading this thread and trying different things to debug and get rid of that warning, I'd have to say this a Chrome issue. I only started seeing TextureLoader malfunctions after the most recent Chrome update.

I don't know if the webGL warnings are related though.

@carstenschwede the workaround in #8670 did solve the problem with texture loading. I modified Threejs image loader function and retained a local copy of the image.

Thanks..

@mrdoob the warnings described by @Rendxx in the original post still appear in r76 and latest Chrome and are AFAIK not related to the Chrome bug described in #8670 since they don't use any external textures.

In Chrome 50.0.2661.94 (64-bit) on MacOS ( MacBook Air ) it was not fixed, http://threejs.org/examples/#webgl_animation_cloth - still has a warnings

Indeed, I can reproduce on a MacBook Air (Chrome 50.0.2661.94).

screen shot 2016-04-30 at 11 28 41

Also reproducing on Chrome Canary...

screen shot 2016-04-30 at 11 41 31

/ping @kenrussell

Fixed!

I dont know if this helps but I added needsUpdate to all my material maps and the material itself..
I got this same bug after new chrome / three updates

ex.
material.normalMap.needsUpdate = true;

same for emissiveMap, map, bumpMaps etc.

This got rid of all the warnings

Hi,

Just to let you know, it looks like the fix is not working on mobile ( or perhaps I missed something ).
But I tried (on the animation/cloth sample ) on my Nexus 5X and on a Samsung 6, and I had textures issue.
Note that mobile chrome version is 50.0.2661.89.
And I didn't had these issues with the version 49.

Thanks

Same bug reproduces when I have changed order in which lights are added to scene:
With warning - https://jsfiddle.net/fuhpvs2g/
And without - https://jsfiddle.net/fuhpvs2g/1/
Lines 32-33. Light which cast shadow should be added in the end. (Chrome 50.0.2661.102)

This has been fixed in the dev branch already.

https://jsfiddle.net/fuhpvs2g/2/

By the way, the new Chrome version (v51) has been pushed by Google on mobile also, and fixed the pb...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexprut picture alexprut  路  3Comments

clawconduce picture clawconduce  路  3Comments

donmccurdy picture donmccurdy  路  3Comments

fuzihaofzh picture fuzihaofzh  路  3Comments

boyravikumar picture boyravikumar  路  3Comments