Scirra / Construct-bugs

Public bug report submissions for Construct 3 and Construct Animate. Please read the guidelines then click the 'Issues' tab to get started.
https://www.construct.net
107 stars 83 forks source link

Pixelart displays incorrectly with fractional origin position #2401

Closed eleanorjmorel closed 5 years ago

eleanorjmorel commented 5 years ago

Problem description

Pixelart displays incorrectly and has artifacts image image

Attach a .c3p

https://puu.sh/CczJ4/5eb5843b64.c3p

Steps to reproduce

1.use the arrows keys to move one of the sprites with the camera

Observed result

sprites render incorrectly and get deformed and artifacts or seomthing

Expected result

I expect it to look good

First affected release

r127, r128

Affected browsers/platforms

Chrome: yes Firefox: yes

System details

View details Platform information Browser: Chrome Browser version: 70.0.3538.110 Browser engine: Blink Browser architecture: 64-bit Context: browser Operating system: Windows Operating system version: 10 Operating system architecture: 64-bit Device type: desktop Device pixel ratio: 1 Logical CPU cores: 12 Approx. device memory: 8 GB User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36 C3 release: r128 (beta) Language setting: en-US Local storage Storage quota (approx): 16 gb Storage usage (approx): 540 mb (3.3%) Persistant storage: Yes Browser support notes This list contains missing features that are not required, but could improve performance or user experience if supported. Nothing is missing. Everything is OK! WebGL information Version string: WebGL 2.0 (OpenGL ES 3.0 Chromium) Numeric version: 2 Supports NPOT textures: yes Supports GPU profiling: yes Supports highp precision: yes Vendor: Google Inc. Renderer: ANGLE (NVIDIA GeForce GTX 980 Ti Direct3D11 vs_5_0 ps_5_0) Major performance caveat: no Maximum texture size: 16384 Point size range: 1 to 1024 Extensions: EXT_color_buffer_float EXT_disjoint_timer_query_webgl2 EXT_texture_filter_anisotropic OES_texture_float_linear WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context Audio information System sample rate: 96000 Hz Output channels: 2 Output interpretation: speakers Supported decode formats: Ogg Opus (audio/ogg; codecs=opus) WebM Opus (audio/webm; codecs=opus) Ogg Vorbis (audio/ogg; codecs=vorbis) WebM Vorbis (audio/webm; codecs=vorbis) MPEG-4 AAC (audio/mp4; codecs=mp4a.40.5) MP3 (audio/mpeg) FLAC (audio/flac) PCM WAV (audio/wav; codecs=1) Supported encode formats: WebM Opus (audio/webm; codecs=opus) Video information Supported decode formats: WebM VP9 (video/webm; codecs=vp9) WebM VP8 (video/webm; codecs=vp8) Ogg Theora (video/ogg; codecs=theora) H.264 (video/mp4; codecs=avc1.42E01E) Supported encode formats: WebM VP9 (video/webm; codecs=vp9) WebM VP8 (video/webm; codecs=vp8)
tunepunk commented 5 years ago

Doesn't happen when you set full screen quality to High.

AshleyScirra commented 5 years ago

The problem is the object's Y origin is at a fractional position (21.5) and pixel rounding is enabled. If you turn off pixel rounding it works OK.

With pixel rounding on, it tries to align the draw co-ordinates with integers. Currently this rounds based on the origin point. However since this example uses a fractional origin, the quad that is actually drawn ends up offset by half a pixel. With linear sampling this would make it look blurred as it's exactly half way between pixels, but with point sampling it has to pick one side or the other. Given it's exactly on the boundary between pixels, floating point precision errors then cause it to sample unpredictably, causing visible glitches.

I tried changing this to round based on the drawn quad instead, but this then changes the problem to the sprite that is scrolled to. Now the viewport is centered on a fractionally positioned object, and it causes it to shake as the scroll position moves around, probably for the same reason (it's randomly rounded either up or down depending on floating point precision errors).

I'm not sure there's any good way to solve this - pixel art with fractional origin positions is a really awkward case to support. You might just have to work around it by making sure your origins are all at rounded positions.

tunepunk commented 5 years ago

Can confirm, setting the origin to 21, instead of 21,5 seems to fix the problem... I think part of the problem is that when you load an asset, sprite editor automatically sets the origin to Center, which in this case is 21.5 ...

Try save the asset, create a new frame, and import the asset again... origin is automatically set to 21.5 ... Maybe you could make sure that loaded assets always will get an intiger as origin, not subpixel... 21,5

tunepunk commented 5 years ago

you always get halfpixel origin if your asset has any uneven number in width/height, when you import.

AshleyScirra commented 5 years ago

Rounding the origin causes issues for non-pixel-art games, e.g. a rotating fan can appear to wobble slightly if the origin is not exactly (fractionally) centered.

eleanorjmorel commented 5 years ago

Maybe a toggle option for pixelart or non pixelart ?

AshleyScirra commented 5 years ago

What would that option do?

eleanorjmorel commented 5 years ago

Users that don't know about this bug or why it happens get to simply check a box if their asset is pixel-art or not otherwise it might be a little obscure, or document it somewhere

AshleyScirra commented 5 years ago

That doesn't explain what you think the option should do? Do you mean for it to round the origin position when it's enabled?

eleanorjmorel commented 5 years ago

Yeah I think so

ReflextionsDev commented 5 years ago

Does this happen in C2 as well?

AshleyScirra commented 5 years ago

At the moment this is all working as designed, but the fractional origin position creates a difficult case of floating point precision errors during rendering. The workaround is straightforward - make sure origins are at a rounded position - but Construct cannot easily apply this automatically since in some cases a fractional origin position is necessary (e.g. smoothly rotating objects). It's possible to add some kind of new mode to opt-in to automatically rounding origin positions too, but this would amount to a new feature that would require some more thought and would be best discussed on the forum and then posted to the feature suggestions platform, so closing this issue.