hajimehoshi / ebiten

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

ebiten: add `FilterCrispScaling` #2826

Open hajimehoshi opened 1 year ago

hajimehoshi commented 1 year 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 month ago

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

hajimehoshi commented 1 month ago

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

hajimehoshi commented 1 month 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
}