Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Black lines when capturing/saving sprites from imagesheet
Started by Studycat2 Oct 14 2019 09:14 PM

7 replies to this topic
capture save imagesheet filter shader bitmap fill texturepacker

Best Answer Studycat2 , 20 October 2019 - 06:45 PM

Hi, @Sporkfin! 

 

Sorry, I don't think that worked -- I'm still seeing the problem in the simulator. Luckily, the problem doesn't happen on device, so maybe it's ok to ignore it for now. Picture below:

https://imgur.com/a/zaFJG3z

 

My only problem in using this effect with spritesheets now is determining POT scale sizes on different device sizes. I'll update that post now, as it's the last bastion.

https://forums.coronalabs.com/topic/76429-displaysave-and-saved-resolution/

 

So glad my description is making the problem seem well-defined -- often in trying to ask a question well, I answer it for myself. So it's a self-preservation strategy.

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

Studycat2

[GLOBAL: userInfoPane.html]
Studycat2
  • Enthusiast

  • 92 posts
  • Corona SDK

I'm making billiards game, and I'm using a filter/shader to make things look like they're wrapped around a ball, and rotating on it. Here's what the final, desired effect looks like:

https://imgur.com/MX9xbyI

 

The filter/shader works fine, but it only works when the image that I am trying to wrap is a bitmap fill, like so:
 

sprite.fill = {
        type = "image",
        filename = "art/pool/sliced/ice.png"
    }

If I try to use this filter effect on a sprite from an imagesheet made by TexturePacker, it doesn't work, because the sprite is from a larger image, and the filter depends on the edge of the fill being the edge of the image file, if you catch my meaning. That is, if I use a spritesheet with my filter effect, I end up seeing other sprites once the ball "rotates", because I'm offsetting into a different part of the spritesheet, instead of just repeating a smaller image.

 

To fix this problem, I'm trying to use display.capture and display.save to CREATE a .png image that I can use as a repeating bitmap fill for each ball -- basically, extract the sprite with display.capture and display.save, and then use it as a fill, so my filter/shader will work. Unfortunately, there's a problem when trying to use display.capture with my rendered sprites -- they always get these weird alpha artifacts on the sides. Here:

 

https://imgur.com/a/qpP6wev

 

It makes sense that the fisheye filter is showing those black lines, because they're in the captured/displayed files, which is the real problem. Here's a file that I get from saving the screen, but the original, rendered file doesn't have these black lines:

 

https://imgur.com/a/OUhJFAz

 

You can see the black lines that are in the captured/saved sprite from the simulator. I'm not sure what is causing this distortion. i've attached the original spritesheet created by texturepacker, as well as my fisheye filter code (in case anybody's interested)

 

Does anyone know what's going wrong? Has anyone seen the black lines before? Is it something to do with the image file, or do you think it's something to do with corona?

 

 

Attached Files



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,240 posts
  • Corona SDK

It is not possible to use texture wrap modes (reference) in conjunction with image sheet frames. This is because OpenGL only supports wrap modes on entire textures, not subsections of textures.

https://docs.coronalabs.com/api/type/ImageSheetPaint/index.html#gotchas

 

Since those textures that you plan to repeat need to be in power of two sizes anyway, there are no texture memory benefits to be gained from adding them into image sheets. For non-repeating images that you'd need to take from the image sheet and then save as individual files, you'd also completely eliminate the gains from using image sheets. As such, I'd simply skip the image sheets and that hack altogether.

 

Now, those black lines are odd and regrettably I have no idea as to what might be causing them.

 

Also, that billiard ball effect of yours is brilliant. I've actually been thinking of how I could accomplish something like that on Corona for a mini golf game, but I personally have no knowledge of shaders or how they work.



[TOPIC: post.html]
#3

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Corona Geek

  • 1,240 posts
  • Corona SDK

I just tried out your shader code and it is neat. Thanks for sharing it!

Did you add the shadows/shading to your billiard balls using shaders or did you just add the shadow by placing an image on top them?



[TOPIC: post.html]
#4

Studycat2

[GLOBAL: userInfoPane.html]
Studycat2
  • Enthusiast

  • 92 posts
  • Corona SDK

First of all, XeduR, glad you liked the effect! Hooray. The shadows are a separate layer I added on top of the ball. It's just a simple PNG. the texturing/dirtiness of the balls is the same fisheye effect, but with a different layer. So actually each ball consists of three layers, in this order:

 

1. a texture with spots, to make the ball look dirty. this uses the fisheye effect.

2. the sprite using the fisheye effect. note that this moves with the same offset as #1, to make it look like they move together.

3. a flat shadow image

 

https://docs.coronalabs.com/api/type/ImageSheetPaint/index.html#gotchas

 

Since those textures that you plan to repeat need to be in power of two sizes anyway, there are no texture memory benefits to be gained from adding them into image sheets. For non-repeating images that you'd need to take from the image sheet and then save as individual files, you'd also completely eliminate the gains from using image sheets. As such, I'd simply skip the image sheets and that hack altogether.

 

Thanks for your response here, but I don't think you're understanding my use case exactly, because I haven't explained it well. I'm working in a project where all the art assets are already stored in many, many spritesheets, and I need to be able to take from any of these to make my game work -- the idea is that the game is dynamic, and can serve up any of this content if requested. So I'm not putting these images in spritesheets in hopes of a performance gain -- I'm trying to take assets we already have/are using happily in many other places, and making them available to this game, which uses this special filter effect. The solution I use here will also be useful in other places I'm sure, because if I can find a way to use this filter with a sprite, then I can use lots of other filter effects as well -- at the start of the game I just have a graphics prep phase where I prepare/cache all my sprite bitmaps for filtering, and then in the game use them with as little overhead as possible, considering they were originally stored in spritesheets!

 

With regard to POT sized images, I'm hoping I can solve this by scaling it correctly, given that I can figure out the content size/scale of the screen, and therefore always display.saving something that is, say, 512 x 512.

 

As for what may be causing these black lines, I'm not sure, but I suspect it's something to do with alpha blending, since my artifacts look so similar to the ones in these pictures:

http://esotericsoftware.com/forum/Premultiplied-Alpha-Guide-3132



[TOPIC: post.html]
#5

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 808 posts
  • Corona SDK

Is the flat shadow image the one that is getting the weird artifacts?  If so, is the flat shadow a solid color at 100% alpha or another color with a reduced alpha value?

 

Yes, make sure you are obeying POT for the fill textures

 

I assume you are using something like this for repeating fills:

display.setDefault( "textureWrapX", "repeat" )
display.setDefault( "textureWrapY", "repeat" )
 
If so, be sure to reset the "clampToEdge" default when you are finished applying your fills. 

display.setDefault( "textureWrapX", "clampToEdge" )
display.setDefault( "textureWrapY", "clampToEdge" )

You will need to toggle the display defaults every time you want to add a repeating fill.  I'm not sure how this applies to sprites/screen captures but if you forget to reset the defaults with regular image files, you can get weird line problems.


[TOPIC: post.html]
#6

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 808 posts
  • Corona SDK

@Studycat2 By the way, your posts are very well done; descriptive with both images and explanations.  That makes them easy to read and sink your teeth into, thanks!



[TOPIC: post.html]
#7

Studycat2

[GLOBAL: userInfoPane.html]
Studycat2
  • Enthusiast

  • 92 posts
  • Corona SDK

  Best Answer

Hi, @Sporkfin! 

 

Sorry, I don't think that worked -- I'm still seeing the problem in the simulator. Luckily, the problem doesn't happen on device, so maybe it's ok to ignore it for now. Picture below:

https://imgur.com/a/zaFJG3z

 

My only problem in using this effect with spritesheets now is determining POT scale sizes on different device sizes. I'll update that post now, as it's the last bastion.

https://forums.coronalabs.com/topic/76429-displaysave-and-saved-resolution/

 

So glad my description is making the problem seem well-defined -- often in trying to ask a question well, I answer it for myself. So it's a self-preservation strategy.



[TOPIC: post.html]
#8

sporkfin

[GLOBAL: userInfoPane.html]
sporkfin
  • Contributor

  • 808 posts
  • Corona SDK

Oh yes, the display.setDefault is a device problem only - sorry, I should have mentioned that


  • Studycat2 likes this


[topic_controls]
[/topic_controls]

Also tagged with one or more of these keywords: capture, save, imagesheet, filter, shader, bitmap, fill, texturepacker