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

Drawing Canvas self-erasing when updated after rescaling Layout or Window #5481

Closed
OverboyDev opened this issue Feb 15, 2022 · 7 comments
Closed
Assignees

Comments

@OverboyDev
Copy link

OverboyDev commented Feb 15, 2022

Problem description

After the Layout or the Window scale changes,
If an already-drawn Drawing Canvas is updated (using any of the Draw Action),
The Drawing Canvas self-erases.

Attach a .c3p

[Bug] DrawingCanvas_SelfErasing_OnUpdateAfterRescale.zip

Steps to reproduce

  1. Draw something on a Drawing Canvas
  2. Rescale the Layout (using a set layout scale event) or rescale the window (manually)
  3. Draw something else on the Drawing Canvas => what was drawn in step 1. disappeared

Observed result

On the .c3p sample, a red ellipse is drawn on the Drawing Canvas at the Bullet position every tick, and the layout is rescaled to 1.0+random(-0.01,0.01) every 0.2 seconds.
Everytime the layout is rescaled, the "red trail" drawn on the Canvas disappears.

Bug  DrawingCanvas_SelfErasing_BadObservedResult

Expected result

(Same .c3p disabling the layout rescale)

Bug  DrawingCanvas_SelfErasing_ExpectedResult

More details

(note : it's not self-erasing right after rescale, only if the drawing canvas is updated after the rescale)

If this issue is made by design by Construct Team, because of performance issues related to CPU/GPU when rescaling a Drawing Canvas, for example, : it would still be nice to implement a work-around that fixes this automatically behind-the-scene so Construct users doesn't need to take care about this. For example by saving the drawing canvas right before the Window/Layout scale changes and redrawing it right before a Draw action is called after that.

Some counter-intuitive work-arounds were found but doesn't cover most use cases. For example, the current issue makes it impossible or at least difficult and costly to have a game in which the layout scale changes every tick (thanks to dynamic zooming camera system based on main character position in Level) and being able to "paint" the Canvas by drawing moving particle systems. (to draw and keep blood splatters of all previously killed ennemies on the environment for example)

This issue seems pretty important to fix because even games who doesn't need to rescale layout are affected as if the player just rescales the game window by hand, it happens. Making the whole Drawing Canvas feature unusable in a lot of cases, which is a shame because otherwise this plugin is amazing and opens a lot of possibilities !

Affected browsers/platforms: Chrome + Firefox + Edge at least, but probably all platforms/browsers (everybody I asked on the Discord has the same issue)

First affected release: The issue is there since at least a year (maybe it was always there). I'm checking if it's still there everytime an update fixes something related to Drawing Canvas.

System details

View details

Platform information
Browser: Chrome
Browser version: 98.0.4758.82
Browser engine: Chromium
Context: browser
Operating system: Windows
Operating system version: 10
Device type: desktop
Device pixel ratio: 0.8999999761581421
Logical CPU cores: 8
Approx. device memory: 8 GB
User agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36
C3 release: r283 (beta)
Language setting: en-US

Local storage
Storage quota (approx): 559 gb
Storage usage (approx): 433 mb (0.1%)
Persistant storage: No

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. (NVIDIA)
Renderer: ANGLE (NVIDIA, NVIDIA GeForce GTX 1070 Direct3D11 vs_5_0 ps_5_0, D3D11-30.0.14.9729)
Major performance caveat: no
Maximum texture size: 16384
Point size range: 1 to 1024
Extensions:

EXT_color_buffer_float
EXT_color_buffer_half_float
EXT_disjoint_timer_query_webgl2
EXT_float_blend
EXT_texture_compression_bptc
EXT_texture_compression_rgtc
EXT_texture_filter_anisotropic
EXT_texture_norm16
KHR_parallel_shader_compile
OES_texture_float_linear
WEBGL_compressed_texture_s3tc
WEBGL_compressed_texture_s3tc_srgb
WEBGL_debug_renderer_info
WEBGL_debug_shaders
WEBGL_lose_context
WEBGL_multi_draw
OVR_multiview2
Audio information
System sample rate: 48000 Hz
Output channels: 2
Output interpretation: speakers
Supported decode formats:

WebM Opus (audio/webm; codecs=opus)
Ogg Opus (audio/ogg; codecs=opus)
WebM Vorbis (audio/webm; codecs=vorbis)
Ogg Vorbis (audio/ogg; 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 AV1 (video/webm; codecs=av01.0.00M.08)
MP4 AV1 (video/mp4; codecs=av01.0.00M.08)
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)

@AshleyScirra
Copy link
Member

This is currently by design. See the section on handling resizing and resolution in the Drawing Canvas manual entry.

@OverboyDev
Copy link
Author

OverboyDev commented Feb 16, 2022

This is currently by design. See the section on handling resizing and resolution in the Drawing Canvas manual entry.

I know it is by design, see the "More Details", I'm just wondering why it is impossible to solve this behind the scene so Construct User doesn't need to take care of this. It makes the whole plugin unusable in a lot of use cases. Sometimes it is impossible to redraw the canvas every frame, for example if what was drawn were particle systems.

@AshleyScirra
Copy link
Member

It's a difficult problem. If you paste to a low-resolution surface and then scale it up, it will look blurry. Creating a new surface with a higher resolution ensures you can still get good quality rendering to the surface, but it clears it. If the old content is drawn over the top, it still appears blurry, and if that happens while the scale smoothly changes over time, it has a weird effect where the old content progressively blurs further and further across the image, since low-resolution's blurriness essentially does an expanding blur effect over time. I'm not sure how to better handle it. I think for the use case described here, it may be better just to spawn lots of sprites. The engine can easily handle tens of thousands of them - hundreds of thousands on some systems.

@pigmalien
Copy link

How about adding a way to load the binary from local storage directly in to Drawing Canvas so we don't have to load it in to a Sprite to paste in to DC?

@OverboyDev
Copy link
Author

OverboyDev commented Feb 16, 2022

It's a difficult problem. If you paste to a low-resolution surface and then scale it up, it will look blurry. Creating a new surface with a higher resolution ensures you can still get good quality rendering to the surface, but it clears it. If the old content is drawn over the top, it still appears blurry....

Thank you for those additional explanations.

But still, something i don't understand is why it would be impossible to redraw what was erased right after the Canvas is rescaled (and cleaned), using some maths and the draw features behind the scene.
Is it because it would involve a complicated algorithm to upscale what was previously drawn ?

If this really is a problem, don't you think something such as having a drawing canvas with higher resolution by default, would help to prevent this need to erase the canvas to keep good quality ?
(like by default it would be corresponding to the resolution for full screen in 1080p, but user could opt for 4K if needed, or putting a value that allows them to keep good quality whatever the zoom in/out of their game will be),
Like the canvas by default is higher rez and just rendered scaled down instead of changing its actual resolution depending on window size/layout scale ?

It could be 2 additional properties of the Drawing Canvas object :

  • a boolean that allows to choose between dynamic resolution (how the plugin works right now) and fixed resolution (as described in my paragraph just above)
  • if the boolean Fixed Resolution is true, an other properties that allow to choose the desired resolution, that would be then scaled up or down depending on layout and window scale or even the scale of the Drawing Canvas object itself. That way no need to change the actual resolution of the drawing canvas, just scale it up or down.

@AshleyScirra
Copy link
Member

AshleyScirra commented Feb 16, 2022

I guess Drawing Canvas could keep a history of every draw command and re-run them when resizing. However it is essentially a memory leak: every drawing operation you ever do will have to be stored, so the more you draw, the more memory it will use. Further, if you do something like 10,000 draw operations over a long period of time then smoothly scale the layout, it will be extraordinarily slow as every frame it will be re-running thousands of draw operations over and over again.

I think a fixed resolution mode would be a better direction to go in, but that has its own complications - in particular I'm not sure how easy "paste object" will be to support if you paste to a surface that does not have the same scale as the layer. There is already extremely complicated code in "paste object" and it is extremely difficult to change, having been a place where regressions have often come up whenever we change things in the rendering code. Also a fixed resolution mode will still go blurry if you scale beyond the fixed resolution you're using, setting a size larger than you really need will waste memory, and if you make the size too large you'll hit the hardware maximum surface size limit.

I'm not sure there's one simple and good solution that will always work. But if you want a fixed resolution mode, the best approach is to file it as a suggestion here: https://construct3-21h2.ideas.aha.io/

@OverboyDev
Copy link
Author

I'm not sure there's one simple and good solution that will always work. But if you want a fixed resolution mode, the best approach is to file it as a suggestion here: https://construct3-21h2.ideas.aha.io/

Ok thank you for explaining this ! I just added a suggestion about the Fixed Resolution for Drawing Canvas here :
https://construct3-21h2.ideas.aha.io/ideas/C321H2-I-226

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

3 participants