fill effects and newImage (or newRect with image fill) broken.

So I really love the filter effects but just came across an issue that is stopping me in my tracks from using the effects on certain things…

So I have an imagesheet with some icons on it, and create a newImage using this imagesheet (or fill image on rect) doesn’t matter which one as they both do the same thing but for this example i will just use newImage.

local testImage = display.newImage(group, imageSheet, imageIndex) testImage.anchorX, testImage.anchorY = 0.5, 0.5 testImage.x, testImage.y = 0, 0

Now lets do a transition with a fill effect.

testImage.fill.effect = "filter.swirl" testImage.fill.effect.intensity = 0 transition.to(testImage.fill.effect, { time=2000, intensity=1 } )

Now run it and you will see that it rotates the “entire imagesheet” inside of the testImage content area (not just the selected index from the image).

I am guessing that when using a imageSheet it simply creates a mask and positions the sheet in the width/height of the object etc. which reduces the overhead of the opengl texture memory and thats great.

However what it should be doing is something like rotation does (rotates the object not the imagesheet).

This is a total show stopper in my book as you cannot use any effects on a image sheet without, even the linear gradients etc. are kind of messed up in above logic because the gradient etc. really doesn’t start where it should so you have to changes the effects values to get it to look right depending on where the image is inside of the image sheet… This one didn’t occur to me until i was using a mirror effect and was thinking i was on crack because some images had different values in the gradient effect if the image was at the top of the imagesheet the values were direction : 1, smoothness : 0.6, progress : 0.54 where if they were at the bottom of the sheet the values where direction : -0.2, smoothness : 0.6, progress : 0.54.

Please tell me you can resolve this, as it is a major issue for me.

You can use a snapshot as a workaround. Copy you image into the snapshot and apply effects to that specific snapshot.

I don’t think what you ask is reasonably possible.

Lerg,

There is nothing unreasonable about how it should work I shouldn’t have to copy into a snapshot in order to pull of what should already be happening behind the scenes. 

Most of us here are experienced programmers in one area or another and yes, I can do work around after work around and more often than not I do but this one is kind of a ordeal as I am not just talking about 1 or 2 images that are effecting me I am talking about upwards of about 500 and forgetting all the areas I would have to go back and make this change to for a second why would I want to add another object for every image that this effects? 

I am not one for complaining and I always just find a work around until such time it is resolved etc. but there is no way I am putting in a work around on this many lines of code when it is something that should already be happening…

Why would I go through so many hoops just to create a image from a image sheet just to copy it into another object so i can do effects on it, that is just silly talk.

Btw just switched to snapshots for a test and while it does let me do the effect it also doubles the texture memory and slows down the game so that is kind of a show stopper, it actually takes less of a hit on texture memory just by loading the image up directly from the file.

@cbishop0, I hear you. 

The thing is we’re beholden to what’s possible on the GPU.

Image sheets (aka texture atlases) are an optimization and as with any optimization, you have to pay the piper. In this case, they are supposed to provide the illusion of an actual image, but it’s well known that this is not a true illusion.

In particular, anyone who’s done tile-based games (where the tiles lay on a single texture atlas) knows that you have to extrude the border pixels of a frame, or else you get seam artifacts that appear/disappear as you translate around the world.

Another way this could be solved is to render each frame of the texture atlas to a true distinct texture (e.g. what snapshots do under the hood), but as you noted, this doubles up texture, and defeats the whole point of using texture atlases. 

Normally, this sort of issue doesn’t come up when using normal shaders. Unfortunately, this frame bleeding issue will occur under very specific shaders like swirl, typically ones that involve some sort of distortion, and in those cases, the issue is magnified.

And the remedy is the same as in the tile-based use case, you have to pad the border of the frame. Except instead of a one pixel border, you have to do it on a case by case basis, accounting for the amplitude of the distortion of that shader, and padding it on one (or all sides) as appropriate. 

I know that’s not the answer you were looking for, but that is the reality of working with the GPU and using advanced features like shaders. 

Walter,

Thanks for your well thought out response, that is one thing I do love about corona staff very helpful and good at calming nerves lol…

I guess I am just use to working with open gl in 3d where i can just texture map something and do whatever i want to it (shaders and all) I have been using shaders for a very very long time but have never come up against the limitation that you are referring to, “not that it doesn’t make sense” just never had to deal with this.

I can do some work around’s like on swirls for example i can simply blur and do rotation to “almost” mimic the filter (or at least close enough for government lol)…

So let me ask you this seeing how I have never found a straight answer on it (anyone else feel free to chime in) :slight_smile:

Question: What is the “max” texture memory you would go to without sacrificing performance? Yes I know I can get the max limit on each device, I am just more asking as a general rule for the “reason” below. I have always made any corona project never go over 40mb most of mine “at any given time” sit between 14 and 32mb.

Reason: IF I can get away with 60-70 texture memory without a performance hit and it still run smooth on 90% of the devices then I could in theory snapshot->do effect->destroy on a “as needed” basis but doing that “just in my head” would peak about 10-20mb when running the effect (as it wouldn’t be one image but several at a time).

Thanks in advance :slight_smile:

I think this can only be answered empirically, so am curious what other folks have tried. 

I’ll wager that the results will vary depending on the device. And the more recent the device (especially iOS devices), the more texture memory you will be able to use.

I just ran a little test on an old iPhone 4 and normal game running is between 24-38mb (at full load) then a spike up to 57mb doing a snapshot->effects->transition->dispose() (on a as needed basis) and ran pretty smooth (with a couple of small tweaks to the frame animations to adjust for lower framerate) also tried it on a old first gen droidX with no issues so I would venture to say that most devices can at least handle that.

The newer iOS devices iPhone 5 etc. and Nexus 7 didn’t even blink twice at it.

My actual memory only spiked to 2.1mb as well so while not the perfect solution it is a “workable” solution and should be able to just create a function to perform the effect and swap out my existing function.

You can use a snapshot as a workaround. Copy you image into the snapshot and apply effects to that specific snapshot.

I don’t think what you ask is reasonably possible.

Lerg,

There is nothing unreasonable about how it should work I shouldn’t have to copy into a snapshot in order to pull of what should already be happening behind the scenes. 

Most of us here are experienced programmers in one area or another and yes, I can do work around after work around and more often than not I do but this one is kind of a ordeal as I am not just talking about 1 or 2 images that are effecting me I am talking about upwards of about 500 and forgetting all the areas I would have to go back and make this change to for a second why would I want to add another object for every image that this effects? 

I am not one for complaining and I always just find a work around until such time it is resolved etc. but there is no way I am putting in a work around on this many lines of code when it is something that should already be happening…

Why would I go through so many hoops just to create a image from a image sheet just to copy it into another object so i can do effects on it, that is just silly talk.

Btw just switched to snapshots for a test and while it does let me do the effect it also doubles the texture memory and slows down the game so that is kind of a show stopper, it actually takes less of a hit on texture memory just by loading the image up directly from the file.

@cbishop0, I hear you. 

The thing is we’re beholden to what’s possible on the GPU.

Image sheets (aka texture atlases) are an optimization and as with any optimization, you have to pay the piper. In this case, they are supposed to provide the illusion of an actual image, but it’s well known that this is not a true illusion.

In particular, anyone who’s done tile-based games (where the tiles lay on a single texture atlas) knows that you have to extrude the border pixels of a frame, or else you get seam artifacts that appear/disappear as you translate around the world.

Another way this could be solved is to render each frame of the texture atlas to a true distinct texture (e.g. what snapshots do under the hood), but as you noted, this doubles up texture, and defeats the whole point of using texture atlases. 

Normally, this sort of issue doesn’t come up when using normal shaders. Unfortunately, this frame bleeding issue will occur under very specific shaders like swirl, typically ones that involve some sort of distortion, and in those cases, the issue is magnified.

And the remedy is the same as in the tile-based use case, you have to pad the border of the frame. Except instead of a one pixel border, you have to do it on a case by case basis, accounting for the amplitude of the distortion of that shader, and padding it on one (or all sides) as appropriate. 

I know that’s not the answer you were looking for, but that is the reality of working with the GPU and using advanced features like shaders. 

Walter,

Thanks for your well thought out response, that is one thing I do love about corona staff very helpful and good at calming nerves lol…

I guess I am just use to working with open gl in 3d where i can just texture map something and do whatever i want to it (shaders and all) I have been using shaders for a very very long time but have never come up against the limitation that you are referring to, “not that it doesn’t make sense” just never had to deal with this.

I can do some work around’s like on swirls for example i can simply blur and do rotation to “almost” mimic the filter (or at least close enough for government lol)…

So let me ask you this seeing how I have never found a straight answer on it (anyone else feel free to chime in) :slight_smile:

Question: What is the “max” texture memory you would go to without sacrificing performance? Yes I know I can get the max limit on each device, I am just more asking as a general rule for the “reason” below. I have always made any corona project never go over 40mb most of mine “at any given time” sit between 14 and 32mb.

Reason: IF I can get away with 60-70 texture memory without a performance hit and it still run smooth on 90% of the devices then I could in theory snapshot->do effect->destroy on a “as needed” basis but doing that “just in my head” would peak about 10-20mb when running the effect (as it wouldn’t be one image but several at a time).

Thanks in advance :slight_smile:

I think this can only be answered empirically, so am curious what other folks have tried. 

I’ll wager that the results will vary depending on the device. And the more recent the device (especially iOS devices), the more texture memory you will be able to use.

I just ran a little test on an old iPhone 4 and normal game running is between 24-38mb (at full load) then a spike up to 57mb doing a snapshot->effects->transition->dispose() (on a as needed basis) and ran pretty smooth (with a couple of small tweaks to the frame animations to adjust for lower framerate) also tried it on a old first gen droidX with no issues so I would venture to say that most devices can at least handle that.

The newer iOS devices iPhone 5 etc. and Nexus 7 didn’t even blink twice at it.

My actual memory only spiked to 2.1mb as well so while not the perfect solution it is a “workable” solution and should be able to just create a function to perform the effect and swap out my existing function.

Hi Chris,

If you’re still reading this,

how exactly do you do the ‘snapshot -> effect -> transition -> dispose’ you mentioned in your last entry?

Are you able to do this without flickering? 

regard, Johannes

It is actually easier to “not” use snapshot and just load the image from a file using newImage but regardless of how you do it it is pretty simple.

create a new image (from file, imagesheet or snapshot)

call transition.to(object.fill.effect, {params for fill.effect, onComplete = function()

    timer.performWithDelay(1, function()

        //dispose of object or do whatever you want after it finishes the transition.

    end, 1)

end})

Not sure what you mean about flickering, do you mean flickering between images? If so there are a ton of tricks you can do to avoid the “visual” flicker.

If you don’t need to take a snap shot (because of imagesheets) then simple revert the effect back to normal using the same process of transition.to but in reverse.

You only need to do this kind of thing on certain types of transitions/fill effects like blur, rotation etc. the reason for this is because all they are really doing on a imagesheet when you do new image is masking off everything except your x/y/w/h values so “most” of the time it isn’t a big deal like with fillColor etc. and so forth.

Thanks Chris,

I’d like to dynamically add a glow effect on whatever display object I want with as little prerequists as possible.

This includes groups: I want to be able to painlessly add a glow effect on a group, even when a project is in it’s end phase, when I don’t want to rebuild graphics or rearrange things into snapshots.

All solutions I came up with are unsatisfying, probably I’m missing something.

First thing I tried, was to just exchange the a given group with the group of a snapshot object, later invalidate->effect.

This doesn’t work well, because all local coordinate transformations also have to be touched (parent/ localToContent/etc is different then).

And, as you stated, I would always appr. double the memory usage for these elements for all times. So this is not a solution.

The other obvious thing I tried was to insert the group into a dynamically created snapshot -> invalidate -> do effect -> reinsert group where it was -> discard snapshot.

But this solutution flickered. Perhaps I did something wrong, that’s why I was asking if you have a working (and leightweight) solution for that.

display.capture is also somewhat unusable because it doesn’t always work (elements have to be on screen. why?)

Walter, in case of you also still following this:

What would have been wrong about just giving us a function

   render2obj( display.obj ) -> display object / fill object.

like display.capture, just usable. This is what we really need: a working, robust, fast display.capture.

I don’t get the whole point of snapshots: given we had said function, what would we need snapshots for.

I get that corona wants to give us something that’s used like a group with the properties of a single texture. This would have been ok, if and only if groups and snapshots would habe been mutually exchangable, but they aren’t

Or am I getting something horribly wrong?

Johannes,

I think you are over thinking this and given “what i understand about your post” off the top of my head you have a few options.

1: Particle Effects

Just from what you explain above I would guess you could use particles to create a glow effect and then just resizing, modifying on the fly depending on what object I was wanting to create the effect with.

There are a few options you can use to achieve what you are looking for if you are on a mac you can use particle editor/designer and use coronas built in support for particle effects or particle candy is another good choice that is what I actually use as I haven’t had any time to mess around with particle editor or the build in stuff that corona has now.

2: Image Sheets (with a glow image for each image you want to have a glow effect.)

This one requires some advanced knowledge of something like photoshop but what you can do is have your base image and then have another image that is the glow effect.

The idea being is you place both images in a group glow first and then game image, then you can use stuff like add/multiply,alpha and misc other effects on the “glow” image to achieve the desired effect.

Because they would all be in the same imagesheet you would not take any kind of extra performance or memory hit because the entire imagesheet would already be loaded up.

Unless of course I am not fully understanding what it is you are trying to do :slight_smile:

Granted I haven’t had my first cup of cafe so I am a little out of it at the moment :slight_smile:

Oh, sorry, I was a little inconcise. And ‘glow’ was perhaps misleading.

I just want to be able to use the corona filter effects on arbitrary display objects (that is groups).

I picture the following process for that

 - render a group of objects to a temporary texture

 - obtain a temporary display object texured with that texture

 - exchange the original group with that display object to…

 - do some corona filter effects with it

 - and then discard the temporal stuff and show the original group

This process has to be robust and such that I don’t have to take any preparations for it, so that any time I could write

local tmp = render2texture( group )

transition.to( tmp.fil, {…})

I just haven’t found any acceptable solution for exactly this in corona, but there probably is a way :slight_smile: