Strange behavior of a sprite loaded from resource.set_texture (SOLVED)

Hi for all.

I create a 64x64 buffer and fill it with red pixels. I use the Draw Pixel extension for this.

self.buffer_info = {
  buffer = buffer.create(64* 64, {{name = hash("rgba"), type = buffer.VALUE_TYPE_UINT8, count = 4}}),
  width = width,
  height = height,
  channels = 4
}
self.header = {
  width = 64,
  height = 64,
  type = resource.TEXTURE_TYPE_2D,
  format = resource.TEXTURE_FORMAT_RGBA,
  num_mip_maps = 1
}
drawpixels.fill(self.buffer_info, 255, 0, 0, 0) -- Fills the buffer with filled pixels r,g,b,a
resource.set_texture(go.get("#sprite", "texture0"), self.header, self.buffer_info.buffer)

If I use drawpixels.fill(self.buffer_info, 255, 0, 0, 255) I get this:


For drawpixels.fill(self.buffer_info, 255, 0, 0, 0) I get this:

It is assumed that if the alpha channel is 0, then nothing should be displayed. Why does it work like this?

Blend Mode on sprite set to Alpha.

Thank you!

+, if move resource.set_texture to update or on_input, then it works

1 Like

This causes problems with antialiasing.

How it should be:


I filled the buffer in red and drew a circle.

How does this happen:


I filled the buffer with empty pixels and drew a circle.

Maybe someone knows how to solve this problem?

Sergey, can you walk me through the steps I need to take to reproduce the problem?

I will prepare a project for you with this example soon.

Example.zip (5.2 MB)

There are two examples. One does not work correctly - “back_color”, the other as it should - “fill_color”. Also, everything is fine with white color in both examples.

You can also change the width and height of the buffer to see it in higher resolution. 512 pixels maximum.

Maybe I need to consider something when I use blending?

1 Like

What this looks like to me is that the red and the blue are being added together instead of being “normal” as in Photoshop layer. I assume you may not be multiplying the alpha onto the red layer when setting it? So at full alpha 1 of blue the red bg should be multiplied by 0. It should be something like this I think https://github.com/subsoap/defblend/blob/master/defblend/materials/sprite/blend_normal.fp I have not looked at the drawpixels source though.

I’ll try to describe the problem again, in the example it’s easier to understand.

For the first image, where everything is fine:

  1. I am creating a sprite that uses material with standard shaders.
  2. In the code, I create a buffer (in the example 64x64).
  3. I fill the pixels in the buffer in red.
  4. I draw an object with alpha. I added normal blending to the library. And everything works well.

For second:

  1. Creating a sprite that uses material with standard shaders.
  2. Create a buffer.
  3. fill the pixels in the buffer with (0, 0, 0, 0). As you can see alpha at 0, i.e. when drawing, I don’t have to mix pixels with anything.
  4. I draw an object with alpha. For example, a pixel may be (255, 255, 255, 100).
  5. I make the game background red.
  6. Pixels in which alpha is not 0 or 255 behave strangely. More precisely, they behave as if they are mixed with white color.

How can I record pixels so that they behave as translucent and render normally?
This can be done?
Maybe something needs to be considered when recording pixels?

Has record_mix_pixel and getmixrgb been tested on their own to give accurate results?

Probably I am missing the point, but it seems to me to be something related to “premultiplied alpha”. Again, this maybe completely wrong. Ciao!

2 Likes

If the pixel in which the color will be written is empty (alpha is 0), then the pixel is just written.
For example, if you need to write red with alpha, it simply writes 4 numbers to the buffer (255, 0, 0, 130).
For such cases, I do not use normal blending, because I just do not know what to mix with the pixel.

I don’t know how can I find out the pixels of the background or sprite that are behind the sprite into which we draw from the buffer.

The problem is that sprite blending works strangely, you can see the topmost post.
The problem can really be in premultiplied alpha. Is it possible to somehow set up my own blending to sprite, except for standard ones?

This is how alpha behaves when another sprite is behind:
image

The problem really was with premultiplied alpha.

Final code:

buffer_info.bytes[i] = r * a >> 8;
buffer_info.bytes[i + 1] = g * a >> 8;
buffer_info.bytes[i + 2] = b * a >> 8;
buffer_info.bytes[i + 3] = a;

Thank you all for your help.

3 Likes

Happy to hear that you solved it. And sorry for not having the time to help out!