w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 656 forks source link

[css-images] object-fit setting for integer-multiple-scaled pixelated images #5967

Open increpare opened 3 years ago

increpare commented 3 years ago

I made a comment in this thread and it was recommended I make a new proposal here.

For images with image-rendering:pixelated if the image display size dimensions aren't integer multiples of the underlying bitmap, you can get some nasty artefacts, because the rectangles representing these pixels can be different sizes.

See these images from the original thread:

(cf increpare/PuzzleScript#568 )

[If you have a desktop pc with non-integral devicePixelRatio you can repro it yourself here https://www.puzzlescript.net/play.html?p=fd4e3445b63068676f72 by resizing the window down]

You can see some horizontal lines like on the "S" of "simple block pushing game" are thick, while the "start game" lines are thin, even though both are one pixel high.

Because Window.devicePixelRatio doesn't have to be an integer, this can end up becoming a ferociously difficult problem to solve, so it seems something worth suggesting at the spec level.

A poster on the original thread suggested the following:

[That] is probably a good fit for an object-fit value, probably as a modifier alongside cover/contain. Then you could apply object-position: center to position it as you described.

I guess my proposal would this:

For an 'integer-multiple-contain' object-fit property that would, given an image, find the largest integer-multiple scaling of the image (not at the logical-pixel level, but at the render-pixel level) that nonetheless would fit inside the content box.

Edge case behaviour:

Other considerations: wouldn't one want a similar behaviour for cover as well? integer-multiple-cover? Maybe theoretically, but I don't think it's likely to be as much a thing that people would want.

(Please excuse any errors/misconceptions in this post - I'm new here - and correct me if I've stuffed something up :) )

fantasai commented 3 years ago

Hi! I'm concerned that with object-fit, we'd end up with the rendered image smaller than the box allocated to it, and that this would not be an expected result. But we did recently adjust the scaling algorithm in https://github.com/w3c/csswg-drafts/issues/5837 to use pixelated scaling to the nearest integer, and then use smooth scaling from there. Would that solve the problem once it's implemented?

tabatkins commented 3 years ago

I think that's actually the exact expected result. I suggested this person file a new issue specifically because they might want a different behavior than what we decided in #5837. ^_^

increpare commented 3 years ago

I have been meaning to maybe put together a list of games that include integer-multiple upscaling in their options as further evidence that it is indeed a thing, though here's a very exhaustively long survey article about integer scaling - it mentions that AMD and NVIDIA have support for this at a driver level, and also gives Owlboy, Dusk, and Quakespasm as examples of games that have it built-in - there are many others though. Some games do automatic upscaling, some let you choose a multiple.

https://tanalin.com/en/articles/integer-scaling/

(I'm not recommending anyone read this - I haven't read it all myself, more including it as potentially relevant bibliography).

What else can I find that definitely features integer multiple upscaling (as evidence that it's a thing).

https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.11-Intel-Graphics-IS emulator bsnes has it https://tanalin.com/en/projects/bsnes-mt/ (though for emulation of CRT games...whether or not you want to do this is a complicated matter)

The much-loved indie gaming classic cave story I think had this as well, the "sharp" vs "stretched" scale modes

tabatkins commented 3 years ago

Thanks for the screenshots, that Cave Story "sharp" example is exactly what's being requested here, yeah.