WebGLRenderTarget.copy Bug: Copying from render target results in targets sharing .texture.image
See original GitHub issueHere’s a snippet to reproduce the issue:
const x = new THREE.WebGLRenderTarget();
const y = new THREE.WebGLRenderTarget();
console.log( x.texture.image === y.texture.image ); // false
x.copy( y );
console.log( x.texture.image === y.texture.image ); // true
What this means is that when x.setSize
is called the object at y.texture.image
is inadvertently modified but and is now out of sync with the true dimensions of render target y
.
This line is the problem in Texture.copy
:
this.image = source.image;
I assume this was originally intended to handle moving over an <img>
tag without duplicating it – ~maybe it makes sense to duplicate the image tag? Or maybe it should clone the object in some cases:~
this.image = source.image instanceof Image ? source.image : { ...source.image };
~I imagine copy would behave a bit confusingly for DataTexture
, as well.~
Edit: I see now that retaining the image data reference is important for dealing with cloning textures before they’ve been fully loaded and is valuable for minimizing data duplication.
Issue Analytics
- State:
- Created 3 years ago
- Comments:7
Top Results From Across the Web
Persistence postprocessing in three.js with 2 renderTargets
You need 3 render targets. Let's call them sceneTarget , previousTarget , resultTarget. Step 1: Render your scene to the sceneTarget .
Read more >Tutorial 5: Render to Texture - TDA362/DIT223
A framebuffer is a "render target", a place OpenGL can draw pixels to. ... 2 textures: the color texture, which is copied to...
Read more >WebGLRenderTarget – three.js docs
WebGLRenderTarget. A render target is a buffer where the video card draws pixels for a scene that is being rendered in the background....
Read more >WebGL Rendering to a Texture
In this article we'll render to textures using WebGL. Note this topic was covered tersely under image processing but let's cover it in...
Read more >Three.js Render Targets
By default WebGLRenderTarget creates 2 textures. A color texture and a depth/stencil texture. · You might need to change the size of a...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Good catch. Let me fix this with a PR.
@mrdoob Now cloning WebGLRenderTarget breaks (?) it’s texture, as far as I understand. In the constructor texture receives this flag:
If you don’t add it during/after cloning, f.e. like this:
then, if texture then is used in shader, setTexture2D() will try to upload the texture, resulting in
gl.texSubImage2D
throwing an error, as it can’t find the correct method overload to load the imageStruggled with this issue when tried to implement outline effect using
postprocessing@6.25.0
+three@0.138.3
.postprocessing
modules use code like this to create internally used textures for shaders:Worth mentioning, the lacking flag wasn’t breaking my code per se, but it generated dubious error message, which I believed was the reason, why my code didn’t work, leading me in a completely wrong direction from actual solution %). Don’t know, if it’s an issue with cloning, or such usage of WebGLRenderTarget should be discouraged in a consumer code.