Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading Texture for null Mapped MeshBasicMaterial #2073

Closed
zz85 opened this issue Jun 18, 2012 · 4 comments
Closed

Loading Texture for null Mapped MeshBasicMaterial #2073

zz85 opened this issue Jun 18, 2012 · 4 comments
Labels

Comments

@zz85
Copy link
Contributor

zz85 commented Jun 18, 2012

Here's an interesting scenario I encountered.

    planeTest = new THREE.Mesh(
        new THREE.PlaneGeometry(1000, 1000, 2, 2),
        new THREE.MeshBasicMaterial({ color: 0xffffff })
    );
  1. Initialize a plane mesh, geometry + material with no textures.
  2. Add to Scene and Start rendering
  3. Load a texture, assigned it to the plane's material's texture. Errors encountered.
GL_INVALID_OPERATION : glDrawXXX: attempt to access out of range vertices uitest.html:1
WebGL: too many errors, no more errors will be reported to the console for this context. uitest.html:1

The work around is to remove the plane from scene, deallocate plane mesh, recreate new geometry, a new material with texture, add plane mesh back to the scene. (If you deallocate a mesh, while reusing the geometry, you would get an error like WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER

This error does not appear when a material has first been initialized with a texture. That means, if a plane's material has initialized with a texture at first, you can load another texture and set the new texture to the material without getting any errors.

@alteredq
Copy link
Contributor

Yes, this is expected. Attribute buffers are created based on material which is present on the first render. If there is no texture in the material, no uvs would be created. So if you put there texture later on, whole VBO will be invalid.

This is btw documented here:

https://github.com/mrdoob/three.js/wiki/Updates

And for textures specifically suggested workaround is to use some dummy white texture. In this way you do not have to do any expensive changes in runtime, you simply switch textures.

There is even a helper specifically for this, for generating single color DataTexture easily in ImageUtils so that you wouldn't have to bother with image files or canvas (also DataTextures are the fastest):

var dummyTexture = THREE.ImageUtils.generateDataTexture( 1, 1, new THREE.Color( 0xffffff ) );

planeTest = new THREE.Mesh(
        new THREE.PlaneGeometry(1000, 1000, 2, 2),
        new THREE.MeshBasicMaterial({ color: 0xffffff, map: dummyTexture })
    );

https://github.com/mrdoob/three.js/blob/master/src/extras/ImageUtils.js#L151

@zz85
Copy link
Contributor Author

zz85 commented Jun 19, 2012

I see, good to know its an expected issue, just a little confusing to users who have no understanding of the buffers.

Using a blank Canvas could be a good idea too. For large textures, it seems like generating a big data texture takes up some CPU time. Will need to do a little benchmarks on this.

@zz85 zz85 closed this as completed Jun 19, 2012
@alteredq
Copy link
Contributor

You don't need a large texture here, any size will do, that's why I put 1x1 pixel example.

Anyways, independently of this issue, DataTexture should be fast - I don't know about creation time but rendering should be the fastest (if I remember well from some benchmarks, compared to using images from DOM, canvas or video elements).

@zz85
Copy link
Contributor Author

zz85 commented Jun 19, 2012

oh yes, i realized that after i tried it too (didn't realize you used a 1 pixel data texture in the example ;)

I was also trying a 2048x2048 data texture vs canvas method, on canary the difference was about 300ms to 250ms, canvas method being slightly faster only.

var s = 2048;

texture = THREE.ImageUtils.generateDataTexture(2048, 2048, new THREE.Color());

vs

var c = document.createElement('canvas');
c.width = c.height = 2048;
texture = new THREE.Texture(c);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants