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

WebGL2: improve RGBFormat texture handling. #18858

Closed
sciecode opened this issue Mar 10, 2020 · 3 comments · Fixed by #18859
Closed

WebGL2: improve RGBFormat texture handling. #18858

sciecode opened this issue Mar 10, 2020 · 3 comments · Fixed by #18859

Comments

@sciecode
Copy link
Contributor

sciecode commented Mar 10, 2020

WebGL2 context doesn't offer support to rendering to a texture with RGBFormat. The way we currently deal with this limitation is by outputting a warning when checking the internalFormat of a texture.

} else if ( internalFormat === _gl.RGB16F || internalFormat === _gl.RGB32F ) {
console.warn( 'THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.' );
}

However this is a premature warning, because the texture might not be used in the context of a framebuffer. Using the texture as a sampler uniform is supported and completely fine. So, I believe we can improve this warning to only trigger when the texture in question is used as a framebuffer.

Unfortunately, this doesn't solve the problem as well. Because, in some cases, three.js itself uses the RGBFormat. This is the case of PMREMGenerator, which simply copies the target envMap settings to the RenderTarget texture. We could modify PMREM to always use RGBAFormat, but I think the current behavior is reasonable and we can solve the problem by other means.

What if we fallback to RGBAFormat framebuffers if we detect we are using a WebGL2 context and if rendertarget.texture.format == RGBFormat. We can reinforce this with a warning and this solves the issue for all cases where either the user or three.js itself uses an unsupported format.

This would look something like this:

function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {

    if ( isWebGL2 && renderTarget.texture.format == RGBFormat ) {

        if ( renderTarget.texture.type == FloatType || renderTarget.texture.type == HalfFloatType ) {

            renderTarget.texture.format = RGBAFormat;

            console.warn( 'THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA instead.' );

        }

    }

    // setup frame buffer

}
@sciecode
Copy link
Contributor Author

sciecode commented Mar 10, 2020

I believe @Mugen87 was the one dealing with this case previously, friendly ping 😊

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 10, 2020

This was the original issue: #15493

WebGL2 context doesn't offer support to rendering to a texture with RGBFormat.

We should clarify that this issue is about floating point textures.

What if we fallback to RGBAFormat framebuffers if we detect we are using a WebGL2 context and if rendertarget.texture.format == RGBFormat.

Sounds good. I've tested your patch for setupFrameBufferTexture() with this test and it seems to work:

let camera, scene, renderer, target;

init();
animate();

function init() {

	const canvas = document.getElementById( 'canvas' );
	const context = canvas.getContext( 'webgl2' );

	scene = new THREE.Scene();
	camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
	camera.position.z = 1.0;

	renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );

	target = new THREE.WebGLRenderTarget( 256, 256, {
		format: THREE.RGBFormat,
		type: THREE.FloatType
	} );

}

function animate() {

	requestAnimationFrame( animate );
	renderer.setRenderTarget( target );
	renderer.render( scene, camera );

}

@sciecode
Copy link
Contributor Author

WebGL2 context doesn't offer support to rendering to a texture with RGBFormat.

We should clarify that this issue is about floating point textures.

Correct, the issue is only related with FloatType and HalfFloatType rendering to a RGBFormat framebuffer. Thank you for clarifying.

Sounds good. I've tested your patch for setupFrameBufferTexture() with this test and it seems to work

Great, I did some preliminary tests and I believe it should cover all cases where it happens. I'm gonna create a PR and continue the tests, just to make sure.

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

Successfully merging a pull request may close this issue.

2 participants