Skip to content

WebGLRenderer display bug at large sizes #5194

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

Closed
jhickner opened this issue Aug 13, 2014 · 12 comments
Closed

WebGLRenderer display bug at large sizes #5194

jhickner opened this issue Aug 13, 2014 · 12 comments

Comments

@jhickner
Copy link

Hello,

I'm running into a display bug at large output sizes with the WebGLRenderer. Fiddle here.

When setting the canvas size (with renderer.setSize) to a width or height above 4096, the output begins to distort and the camera appears to go off center. It happens with both Orthographic and Perspective cameras. You can get a feel for what's happening by just changing the width in the fiddle. Above 4096 the effect begins and becomes more and more pronounced as you go up from there.

It looks like everything renders correctly when using CanvasRenderer, so I think it's a problem in the WebGLRenderer.

Thanks!

@WestLangley
Copy link
Collaborator

The size of the drawing buffer you get is limited. How it is limited is not clear. This appears to be a WebGL issue, and is implementation dependent according to the spec.

console.log( renderer.getContext().drawingBufferWidth );
console.log( renderer.getContext().drawingBufferHeight );
console.log( renderer.getContext().canvas.width );
console.log( renderer.getContext().canvas.height ); 

Fiddle updated to current version: http://jsfiddle.net/862de4nj/47/

@arose
Copy link
Contributor

arose commented Aug 14, 2014

There are two WebGL context parameters that could help

var gl = renderer.getContext();
var maxRenderBufferSize = gl.getParameter( gl.MAX_RENDERBUFFER_SIZE );
var maxViewportDimensions = gl.getParameter( gl.MAX_VIEWPORT_DIMS );

console.log( "maxRenderBufferSize", maxRenderBufferSize );
console.log( "maxViewportDimensions", maxViewportDimensions );

On my machine I get

maxRenderBufferSize 16384
maxViewportDimensions [16384, 16384]

I guess these must be divided by four to get the size available for a RGBA4 render buffer. At least it would fit the observation that things happen with dimensions > 4096 (also on my machine).

So, if width or height are greater than the limit stated in maxViewportDimensions or maxRenderBufferSize you better handle re-sizing width and height to fit to the limits yourself.

@jhickner
Copy link
Author

thanks @arose and @WestLangley! So are you saying there's a way to adjust the drawingBuffers? I'm aiming for 7560x1080 so I want more width but less height. It's a lot less total pixels.

@jhickner
Copy link
Author

...and if not, what do you think is the best option to achieve a canvas this large in a single browser window? I'm doing it now with two side-by-side WebGL canvases that each render 3780x1080, but there doesn't seem to be a way to share the same scene between them, so I'm working with two duplicate scenes.

@WestLangley
Copy link
Collaborator

That sounds reasonable, given the constraints. How are you aligning the camera views?

@jhickner
Copy link
Author

I'm using the Orthographic camera with different x/y offsets for the objects in each scene. It makes them appear to be aligned. I'm not sure how you'd do it with the Perspective camera.

@jhickner
Copy link
Author

Is there any way to reuse the scene across the two renderers? It looks like WebGL buffers are created directly on the geometry objects, which I think is why they can't be shared. Would it be possible to just keep two sets of buffers and swap references between render passes? Or are there other considerations as well?

@mrdoob
Copy link
Owner

mrdoob commented Aug 15, 2014

Is there any way to reuse the scene across the two renderers?

That's something I'm currently fixing.

@SpencerIO
Copy link

When your stage is larger than 4096px wide, you can fix the weird scaling in the PerspectiveCamera with the setViewOffset function. Change the width value without changing the height value and you will be able to correct the camera. The only bad thing about this is that you aren't getting full resolution. I'm pretty sure it still renders at 4096px so it will not be pixel perfect.

@mrdoob
Copy link
Owner

mrdoob commented Jan 1, 2015

I wonder whether we should check gl.getParameter( gl.MAX_RENDERBUFFER_SIZE ); and gl.getParameter( gl.MAX_VIEWPORT_DIMS ); at init time and then if setSize() is being called with bigger values show an error.

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 4, 2020

I wonder whether we should check gl.getParameter( gl.MAX_RENDERBUFFER_SIZE ); and gl.getParameter( gl.MAX_VIEWPORT_DIMS ); at init time and then if setSize() is being called with bigger values show an error.

We could implement something like this in setSize() and setDrawingBufferSize():

var maxRenderbufferSize = capabilities.maxRenderbufferSize;

if ( _canvas.width > maxRenderbufferSize || _canvas.height > maxRenderbufferSize ) {

	console.warn( 'THREE.WebGLRenderer.setSize(): Requested size %ix%i is too large. Maximum size of renderbuffer is %i.', _canvas.width, _canvas.height, maxRenderbufferSize );

}

However, this check does not work in Chrome since the browser checks for 5760 x 5760 total backbuffer area. Also see latest Chromium bug.

It seems browsers behave differently in this context which makes implementing a check like above not feasible.

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

7 participants
@mrdoob @jhickner @arose @WestLangley @SpencerIO @Mugen87 and others