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

WebGLRenderTargets shouldn't be treated like special Textures #8615

Closed
1 of 2 tasks
vanruesc opened this issue Apr 12, 2016 · 11 comments
Closed
1 of 2 tasks

WebGLRenderTargets shouldn't be treated like special Textures #8615

vanruesc opened this issue Apr 12, 2016 · 11 comments

Comments

@vanruesc
Copy link
Contributor

vanruesc commented Apr 12, 2016

Preface

Following up on #8417.

This issue's purpose is to keep track of a problem that was identified during an attempt to refactor the WebGLRenderer in order to move away from treating render targets like special textures.

The goal

WebGLRenderTargets should not be used like Textures. Their texture property should be used instead.

material.map = renderTarget.texture; // not material.map = renderTarget;
The first attempt

WebGLRenderer: e255f01
WebGLPrograms: ae22bc1
WebGLRenderTargetCube: dcfcd4d

Description of the problem

By dropping the special treatment for WebGLRenderTargets, this flipEnvMap check and these cube render target checks: 1 | 2 become problematic.

When texture properties of materials are always Texture instances, it's no longer possible to rely on instanceof WebGLRenderTargetCube. The only way to know whether the texture at hand belongs to a WebGLRenderTargetCube is an ugly flag. Furthermore, the WebGLRenderTargetCube has a Texture instance because it extends WebGLRenderTarget. CubeTexture is therefore not involved in these checks, so instanceof THREE.CubeTexture is not an option.

Shader texture uniforms are another problem, because they are updated every frame.

Providing the user with warnings after checking for instanceof THREE.WebGLRenderTarget shouldn't be done every frame, but I couldn't find a better place for this.

Any suggestions would be much appreciated. Don't hesitate to make your own PR if you find a solid solution to the problem.

Three.js version
  • Dev
  • r75
@tschw
Copy link
Contributor

tschw commented Apr 14, 2016

Just moved that code around in #8606 . Now we already know whether a texture is 2D or Cube (because WebGL gives us that info querying the uniforms of the program). The entry points (from WebGLUniforms) into the renderer are now setTexture2D (formerly setTexture) and setTextureCube.

Furthermore, the WebGLRenderTargetCube has a Texture instance because it extends WebGLRenderTarget

A quite elegant solution (possible in JavaScript, but one that would break in C++) is to defer the creation of the value that is used for .texture to a method (e.g. createTexture). The constructor of WebGLRenderTarget would call that method and WebGLRenderTargetCube would override it to get a proper CubeTexture.

I think, mipmapping should be switchable, and off by default for render targets, and the renderer-internal function setCubeTexture could really use a bit of a cleanup.

Shader texture uniforms are another problem, because they are updated every frame.

Could force .needsUpdate to true on the render target texture by setting a property.

Providing the user with warnings after checking for instanceof THREE.WebGLRenderTarget shouldn't be done every frame, but I couldn't find a better place for this.

See here.

HTH to pull your PR up (bet I broke it).

@vanruesc
Copy link
Contributor Author

Thanks for the heads-up! These changes might really help, will look into it as soon as I can.

mrdoob pushed a commit that referenced this issue May 1, 2016
* Don't treat render targets like textures.

Expect Texture instances from now on. Added backwards compatibility
measures to ensure that render targets can still act as textures for the
time being. A deprecation warning will be given. Resolves #8615.

* Added comments to clear up RT-Cube detection.

* Revised the previously added comments.

* Added a TODO note.

Forgot to include this one in the last commit.

* Documentation: updated WebGLRenderTarget.

* Docs: added more Texture info to WebGLRenderTarget.

Also removed an unnecessary html line break.

* Docs: added a notification to ShaderMaterial.

WebGLRenderTarget and WebGLRenderTargetCube must not be used as
uniforms. Their texture instance must be used instead.

* Docs: revised a notification in ShaderMaterial.
@vanruesc vanruesc closed this as completed May 8, 2016
@verteAzur
Copy link
Contributor

verteAzur commented Jun 25, 2016

What does it means from a user perspective when one sees this warning:

three.webglrenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead.

@mrdoob
Copy link
Owner

mrdoob commented Jun 25, 2016

@verteAzur

Instead of doing this...

var renderTarget = new THREE.RenderTarget( 256, 256 );
var material = new THREE.MeshBasicMaterial( {
    map: renderTarget
} );

You should do this:

var renderTarget = new THREE.RenderTarget( 256, 256 );
var material = new THREE.MeshBasicMaterial( {
    map: renderTarget.texture
} );

What code is triggering this?

@verteAzur
Copy link
Contributor

verteAzur commented Jun 25, 2016

Thank you for the info. It's the only warning/error I have seen from r77 to r78 migration.

@WestLangley
Copy link
Collaborator

@mrdoob You mean renderTarget and THREE.WebGLRenderTarget.

@verteAzur
Copy link
Contributor

verteAzur commented Jun 25, 2016

@mrdoob

What code is triggering this?

I have to pin point the exact spot. It is in the last part of the large loading process though. I have updated the mirror and water shaders, thinking it could be coming from that piece of code, but in vain. I'll get back to you when I find the line...

@mrdoob
Copy link
Owner

mrdoob commented Jun 25, 2016

@mrdoob You mean renderTarget and THREE.WebGLRenderTarget.

Ops! Thanks! It was early in the morning... 😇
Fixed!

@verteAzur
Copy link
Contributor

The code triggering the warning is vast. It comes from the dynamic terrain example prior v75. It could be in the long list of integrated shaders: maybe the blooming or the blurring one. Do you have any idea?

@mrdoob
Copy link
Owner

mrdoob commented Jun 25, 2016

No... Shouldn't you be able to check the callstack?

@verteAzur
Copy link
Contributor

re mrdoob: I have found the line that needed the "renderTarget.texture" update. It was located in the render member function of the THREE.ShaderPass.prototype. I did make the change, but the warning was still triggering. Then, I've decided to update all postprocessing classes and shaders (Convolution, Copy,Effectcomposer, Shaderpass, Maskpass, RenderPass, Bloompass, FilmPass) and it did work like a charm. Everything is working without any warning nor error.

We did notice a few things while going through the update process that might help others: #9267

Thank you all for all!

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

No branches or pull requests

5 participants