ebiten icon indicating copy to clipboard operation
ebiten copied to clipboard

internal/shader: utility functions to treat normalized values

Open hajimehoshi opened this issue 1 year ago • 7 comments

Operating System

  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] FreeBSD
  • [ ] OpenBSD
  • [ ] Android
  • [ ] iOS
  • [ ] Nintendo Switch
  • [ ] Xbox
  • [ ] Web Browsers

What feature would you like to be added?

I propose to add these functions

  • func normalizeDstPosition(pos vec2) vec2: converts pos in pixels to [0, 1] of the destination image.
  • func normalizeSrcPosition(pos vec2) vec2: converts pos in texles to [0, 1] of the source image.

Note that the units might be affected by #1431.

For more details, see https://docs.google.com/document/d/1lJTKxMqyyO-LxNS4KmuNakQwlhdBgzkmP2LNwpJk5bg/edit#bookmark=id.b8qzndnzk6yq

TBD: Do we need inverted functions?

Why is this needed?

From the discussion of #2639, we found that normalizing positions of textures to [0, 1] is very common. To do this, users need to understand how images and textures work in Ebitengine, and to write some tricky code with an origin and a texture. Thus, it should be very useful to have utility functions to do that for Kage.

For more details, see https://docs.google.com/document/d/1lJTKxMqyyO-LxNS4KmuNakQwlhdBgzkmP2LNwpJk5bg/edit?usp=sharing

hajimehoshi avatar Apr 16 '23 05:04 hajimehoshi

For #1870, we might have to have these functions:

  • func normalizeDstPosition(pos vec2) vec2: converts pos in pixels to [0, 1] of the destination image.
  • func normalizeSrcNPosition(pos vec2) vec2: converts pos in texles to [0, 1] of the source image. N is 0 to 3.

hajimehoshi avatar Apr 25 '23 13:04 hajimehoshi

By the way, to use position directly in pixels, without normalizing to [0, 1], don't we also need to use the origin from imageDstRegionOnTexture() and transform it from texels to pixels with tricky calculations too? Because if this is the case, we should also have a normalization function for it. Until we actually get the pixels mode, this specific conversion (if I'm imagining it correctly) seems extremely convoluted.

tinne26 avatar Jul 06 '23 17:07 tinne26

don't we also need to use the origin from imageDstRegionOnTexture() and transform it from texels to pixels with tricky calculations too?

In the pixel mode, we don't treat texels even for destination textures, right?

hajimehoshi avatar Jul 06 '23 18:07 hajimehoshi

Right. What I'm asking is this: given a target of 400x400, will position go from 0.5 to 395.5, or do we have to correct first for the destination origin? Unless I'm misunderstanding something (which is highly likely), I assume that in pixel mode we simply would do:

//kage:pixel-mode
func Fragment(position vec4, _ vec2, _ vec4) vec4 {
    origin, _ := imageDstRegionOnTexture()
    dstPosition := position.xy - origin
}

But without pixel mode, this is currently much harder to do? Or is this step already unnecessary?

EDIT: I know that for many subimages position won't start at zero, but I still don't know if destination images with (0, 0) origin require atlas origin normalization or not to use position in the "natural range" of the destination image. If doing this is necessary, maybe we should have a normalization function for it too?

tinne26 avatar Jul 06 '23 18:07 tinne26

But without pixel mode, this is currently much harder to do? Or is this step already unnecessary?

If you are talking about how to get [0, 1] value, yes, this is a little much harder, but it's still possible. See https://github.com/hajimehoshi/ebiten/blob/2.5/examples/shader/texel.go (texel mode) vs https://github.com/hajimehoshi/ebiten/blob/main/examples/shader/texel.go (pixel mode).

I know that for many subimages position won't start at zero, but I still don't know if destination images with (0, 0) origin require atlas origin normalization or not to use position in the "natural range" of the destination image. If doing this is necessary, maybe we should have a normalization function for it too?

For a sub-image, I think we should provide a function to return [0, 1] assuming the sub-image's left-upper is (0, 0) and right-bottom is (1, 1). But this might be ambiguous. Let me think.

hajimehoshi avatar Jul 07 '23 03:07 hajimehoshi

No, I'm talking about how to get the position value in [0, N] where N is the size of the destination image (let's assume it's a square image), without considering special cases like subimages or scaling due to anti-aliasing. Technically it's [0.5, N - 0.5], but you get the point. I don't know if we need to account for the origin or not in the current state.

tinne26 avatar Jul 07 '23 07:07 tinne26

This requires more discussion. I'll reset the milestone.

hajimehoshi avatar Sep 12 '23 19:09 hajimehoshi