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

WebGLRenderer: Setting Scissor and Viewport is imprecise due to rounding issues #27655

Closed
gkjohnson opened this issue Jan 31, 2024 · 2 comments · Fixed by #27703
Closed

WebGLRenderer: Setting Scissor and Viewport is imprecise due to rounding issues #27655

gkjohnson opened this issue Jan 31, 2024 · 2 comments · Fixed by #27703

Comments

@gkjohnson
Copy link
Collaborator

gkjohnson commented Jan 31, 2024

Description

For three-gpu-pathtracer I've been rendering the image in tiles for the sake of performance but found that it's not possible to set the exact pixels that the renderer rasterize due to the multiplication with the pixel ration and subsequent rounding that occurs in the setScissor and setViewport functions.

This means that when rendering tiles side by side the rounding can result in pixels being missed when rendering tiles. For three-gpu-pathtracer I've switched to using the WebGLRenderTarget's .scissor property since it affords setting the sciossor via exact pixel values.

Reproduction steps

  1. Try to render in a tiled fashion with a combination of pixel ratio and dimensions that do not cleanly divide
  2. See that the tiles miss rows and columns of pixels due to rounding error

Code

See live example.

Live example

Demo with selected pixel ratio and dimensions that result in the skipped pixels.

https://jsfiddle.net/cfhwous9/

Screenshots

image
image

https://twitter.com/mrdoob/status/1752366500621746617

Version

r160

Device

Desktop, Mobile

Browser

Chrome, Firefox, Safari, Edge

OS

Windows, MacOS, Android

@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 31, 2024

According to the WebGL/OpenGL spec the values passed to gl.viewport() and gl.scissor() are supposed to be GLint. To be spec compliant, the engine should round values. So maybe the usage of floor() is incorrect? Would using round() solve the issue?

@gkjohnson
Copy link
Collaborator Author

Yeah perhaps using "round" with a clamp to the max width of the canvas would work best.

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