hajimehoshi / ebiten

Ebitengine - A dead simple 2D game engine for Go
https://ebitengine.org
Apache License 2.0
10.98k stars 657 forks source link

ebiten: add `FilterCrispScaling` #2826

Open hajimehoshi opened 11 months ago

hajimehoshi commented 11 months ago

Operating System

What feature would you like to be added?

We propose to add a new filter FilterCripsScaling, which enlarges the image without losing crisp edges and without being blurred. This is the same scaling as the current Ebitengine screen's scaling.

The current problem is that the filter might not work well when rotating.

In the future, we might be able to replace the default filter from FilterNearest, but we are not sure.

Why is this needed?

To provide a better scaling instead of FilterNearest.

hajimehoshi commented 1 week ago

Is there a way to do this without any uniform variables?

hajimehoshi commented 1 week ago

https://www.shadertoy.com/view/MlB3D3

hajimehoshi commented 1 week ago

This worked well:

//kage:unit pixels

package main

func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
    // Blend source colors in a rectangle region, whose size is inverseScale.
    inverseScale := vec2(abs(dfdx(srcPos.x)), abs(dfdy(srcPos.y)))
    pos := srcPos
    p0 := pos - inverseScale/2.0
    p1 := pos + inverseScale/2.0

    c0 := imageSrc0UnsafeAt(p0)
    c1 := imageSrc0UnsafeAt(vec2(p1.x, p0.y))
    c2 := imageSrc0UnsafeAt(vec2(p0.x, p1.y))
    c3 := imageSrc0UnsafeAt(p1)

    rate := clamp(fract(p1)/inverseScale, 0, 1)
    return mix(mix(c0, c1, rate.x), mix(c2, c3, rate.x), rate.y) * color
}