Page curl effect using graphics 2.0 and shaders

I’ve added some provisional touch controls.

It’s more straightforward than what I thought would need doing, but seems decent enough. What I’m going for is that the part you grabbed on the side will track the touch (though allowing for a little “windup” near the right-hand side), but the “how much to roll” scale factor is a bit off, and currently defeating my attempts to puzzle it out. Also, it can kind of freak out near the corners.  :smiley: (I’m probably doing a math.atan2(0, 0) there.)

Anyhow, I’ll continue trying to nail this down.

UPDATE : The touch controls are nearly there, I think. The early part of the roll is a little off (this is more obvious with some orientations than others), mostly owing to trying to combine a couple kludges. :unsure: A bit too tired to do it the right way, at the moment, but I’ll need to figure it out eventually if I want to be maintain shadow proxies outside the shader, or anything along the same lines.

I still don’t have any great ideas about fixing touch along the right-hand side. Try dragging up and down there to see what I mean.

Any styling recommendations from anybody who’s used one of these before? It seems to make most sense to me to have just a vertical strip at the edge as done here for the touchable region, but obviously one wouldn’t want a translucent rounded rect indicating that part… Or can I safely assume “they’ll know what to do”?

Anyhow, I’ll probably give it a couple days’ rest and then begin trying to package it up.

EDIT : Well, I couldn’t get this out of my head, so I figured out the early parts of the roll. Man, so many sheets full of slightly wrong formulae…

Hi!

I slogged away and now have what I consider a feature-complete version 1.0. In any event, the API is basically in place. A few use cases can be found in main.lua ; these can be enabled by changing the appropriate

--[[ 

lines to

---[[ 

(I’m still uncertain whether the somewhat odd capture results are par for the course with groups or an error on my part.)

As a reminder, the current WIP is here. I think I’ll freeze that once I finally submit this as a plugin, in the not-too-distant future.

Also, while probably not the most exciting reading material, the current documentation can be found here. This is very much a first draft, which aims above all for accuracy, but could probably stand a few revisions for clarity. Any constructive criticism would be most appreciated!

Bug testing ought to follow fairly soon, though I think I’ll give it a few days, especially since I need to give some other things a little love. The sample I have in mind for the plugin should be equally well-suited for stress-testing the various features.

Known issue : Switching “modes” while the page is unrolling (after releasing a touch) freezes the page in place. (I have a pretty good idea of the cause.) EDIT: Seems to be fixed.

That is just amazing! I have tested your code and the effect looks awesome. I will dig into the code later but I bet I won´t understand half of it  :unsure:

I´m just thinking about how will the effect look when the page is turned back?!?

Seems like this video might have a good sollution: https://www.youtube.com/watch?v=IShu45tqtuk

It would also be possible and maybe easier to “animate” the whole “turn back” effect like in this video: https://www.youtube.com/watch?v=EVHksX0GdIQ

Thank you so much for doing this Steve  :slight_smile:

You are my hero  :rolleyes:

Good to hear, Tom.

I’ve just uploaded an update of the project and the docs, together with quite a few samples. There were some last-minute interface changes, but now I’m finally pleased with them. I felt it was quite well along, so I filed a plugin submission, too.

Dragging from a corner or horizontally looks pretty straightforward, but I’m not quite sure what an off-center curl is doing. I think the curl in these cases could be reasonably approximated by a cylinder (or half of one), the axis of which is perpendicular to the direction of motion.

*Plays with sheet of paper for a while*

Okay, I have a rough idea of how this must work. It looks like cones would suit the rest.

Off-hand it’s hard to estimate how difficult it would all be. I’ve got cylinder code, but nothing for cones. They are both conics, so in theory an either-or shader is possible.

I could put together some notes if someone wanted to pursue this, though probably not tonight. Not sure I’d be able to tackle it any time soon myself…

For anybody who knows, how do these sorts of techniques tend to handle motions that would tear a physical page?

Thanx for the input starCrunch!

I really would LOVE this kind of effect, but I havent started playing with shaders yet. I think this is going to be too much for me to handle as a novice.

Maybe Steven Johnson from Xibaba Studios would be the “shader maestro” for this kind of task  :rolleyes: With the help from Jason Schroeder (and his module) and your (starCrunch) notes.

My storybook clients always ask for this effect and I see other Corona developers are asking for this effect.

It would be great if some coding ninja/ninjas took the challenge.

Our Corona storybook apps would look awesome!

The community could start a fundraiser.  

I will chip in with $100 to the guy(s)/girl(s) who manages to make this effect and shares it with the community.

I would also print out a picture of you and put it on my nightstand, so I can thank you every night before I go to sleep  :smiley:

(The effect has to be able to turn the pages both ways)

Oh, heh. That’s me, actually.

That… would be incredibly weird.  :slight_smile:

I’m open to it (err, the page curl, not the picture thing), though it would be good to know I wasn’t stepping on any toes, say if Jason has plans to pick up on his own implementation soon. That said, I’ve got a few little projects I’d like to finish or at least get going on over the next couple weeks, so it’s not something I’d be willing to start immediately.

Also, I probably need to let all the touch mechanics stew in my mind for a while anyhow. (It would be a bit spooky if it calls for something I only just got working recently, but it actually might…)

No worries about stepping on toes, Steven. If you think there’s a good way to accomplish this using shaders, then please have at it! My own method works as seen in the video I made but it’s not as flexible (or as organized) as I’d want to consider it “release ready,” which it why it sort of withered on the vine, as other projects and client work picked up. I’ll try to revisit it when I can - but like you, I’m not able to drop everything and work on it immediately.

@Tom: if you want, I can post my “not ready for prime time” version of the module here, but you’d have to work through it on your own for now - and it’s probably none too pretty or organized. Let me know if that interests you at all.

Thanks,
Jason

Oh! So you are starCrunch, Steven

*Feels embarrassed and a little starstruck*  :unsure:

The picture on the nightstand is off the table then, but not the money.

I´m happy to hear this is stewing in your mind Steven. It gives me hope.

There is of course no rush but I just feel like this is something that is missing in Corona.

I hope you get some help from the community with this, but I can’t contribute because this is way over my level of intelligence  :unsure:

I would love to see your code @Jason.

I feel there is a need for both effects.

I would use the “Jason page curl” on books for children because that effect is less confusing for a child. But the advanced effect would be amazing in a book for youths or adults.

So no toe stepping in my mind  :slight_smile:

-Tom

Hi Tom,

You can download a zipped-up sample project (the one seen in that YouTube video) here: http://www.jasonschroeder.com/corona/pageCurl/pageCurlSample_Alpha.zip 

You can load that project in the Simulator and try it out, and you’ll see “pageCurl.lua” is the module that enables the page curl effect.

In particular, I didn’t release this because I’m not sure it’s stable yet on all device types and screen ratios, and I’m certain that the math being used is not the most efficient (and might be downright wrong in some areas). This first pass at the module was all about getting it working in my sample - and it does - but I stand firm in my assertion that it’s “not ready for prime time” just yet. But you can at least take it for a spin and see how it works under the hood. You may even be able to use it in a project, depending on the particulars, but I don’t vouch for it’s durability just yet.

I’ll try to put some time into it in the next few weeks to see if I can spiff it up. If I do, I’ll post an update on this thread.

Thanks,

Jason

Nice job Jason!

I really like what you have done and I´m pretty impressed by the way you have solved this.

It seems to run smoothly on the simulator, but there is a lag on my Iphone 6 plus the first time I start the template and go to a scene (only from the first scene). After that it works great:

https://youtu.be/1be3W78Kwzk

I will check this out when I get the time, but it seems like the module works great and I will try to implement this in a project one day. If it doesn´t work, I know who to blame :wink:

No seriously! You should not worry about the module not working perfectly Jason. The community can find the bugs themselves and post their own sollutions or improvements in the forum.

I like your effect a lot and it will look great in my books for children, but I´m also hoping for that advanced page curl one day for other projects. So just keep stewing Steven!

The advanced effect has the ability to make a Corona app go from " oh this is a cute app" ^_^ to " WOW THIS APP IS SO FREAKING BEAUTIFUL I WANT TO FRENCH HUG IT!" :o

Thanks for the hard work for the community Jason and Steven!

-Tom

It’s messy and far from complete–among other things, I’m still puzzling out the touch controls–but here’s a WIP for anyone interested: Page Curl I’ll try to give an overview of the ideas at some point, but that entails explanatory pictures that I don’t want to make just now.  :slight_smile:

I’ll probably try to turn this into a plugin eventually, so I’d be interested in others’ suggestions or experience from using similar libraries. Among other things:

  • Preferred API, if any.
  • Methods for getting the previous / next page (up-front array, callback, etc.).
  • Options, e.g. separate back texture, shadow stuff, curl radius.
  • Other stuff? I’m thinking support for use as a scene transition, at least.

DAAAAAAAAAMN, Steven. :slight_smile:

Wow, that’s fantastic! Amazing work.

This would be really useful as a Composer scene transition option. It doesn’t need to be interactive, just a preset transition which occurs automatically between scenes. You might define: transition duration, easing, x,y start and end. Shadows would be nice…

Even with what you’ve done now, it could go straight into Composer scenes for those already using custom effectsList. Is it the enterFrame listener where you are defining the current looping animations? It would be great to know what to put in there to achieve say… a curl from bottom right to top left easing out with an inQuad type shape…

Very very cool.

Thanks!

@ kilopop

By the looks of it, I’m not really gaining much by breaking the three stages up into separate shaders (well, except for some interesting accidents when I got the alpha wrong!), so I’ll probably merge them soon. What you see in the enterFrame is updating the inputs, yes. (The “clip” shader should also just take an angle for consistency, rather than nx and ny.) Basically, the u and v arguments make up some point (each component goes from 0 to 1: 0 being left and bottom, respectively; 1, right and top) along the “edge”, where the page starts to curl, and angle  (in radians) defines the outward-facing normal, i.e. the direction facing “away” from the page, perpendicular to the edge / curl axis.

Assuming you just want a right-to-left roll, you’d transition u from 1 to 0. (Or 0 to 1, with angle = math.pi.) You can play around from there.  :slight_smile:

Right now it’s wrapping as if around a basic circular cylinder, but I’m going to experiment with tapering between two radii (if you curl a physical page you can see how the shape gets a bit cone-like).

Nice one, have this working now as Composer scene transitions with u tethered to parameters returned from the effectsList.

Specifically about using the curl as Composer scene transitions: In order to curl a scene, the screen needs to be captured (display.captureScreen()), but there will be an extra step involved to save it to the cache in order for the image to be applied as a fill. Have yet to try this, but I imagine it will result in a pause before the transition begins… I’ll report back with findings, otherwise if anyone has ideas around screen captures vs speed tests? Or is there another way other than defining a paint fill? It would be better to pass an already loaded object such as a screen capture without saving it somewhere first…

@ kilopop

I saw your other thread about texture memory. I’ve now uploaded a new version with an all-in-one shader. I’ve only commented stuff out for now, so look at the code to see what’s changed. Basically, just take a capture and slap the shader on it rather than add a paint. Don’t bother with the “* 2” stuff you see me doing, since I assume the transition is full-screen already. Round it out by adding a #define NO_CLIP line early in kernel.fragment’s code. (As an aside, whenever captures / snapshots as paints do work, there will be much rejoicing on my part!)

For anyone interested, I’ve tried to explain what’s going on in the shader’s comments. I hope it at least gives an idea, but man, it’s hard to distill some of this stuff into words.  :mellow:

EDIT : I suppose NO_CLIP gets it exactly backwards… probably will be NO_EXPAND in the future.

Good stuff Star Commander. Your new version works a treat! Now one screen capture is all that’s required which certainly helps with the texture memory biz. Roll on capture images in bitmapPaint…

The speed of the scene transitions has also improved although the curl is not quite as smooth on the device. In a scene transition of time=500, the pageCurl enterFrame function happens around 22 times. On iPad device, this is more like 7 times. Perhaps this is to do with the way I have set this up. But essentially, t is tethered to a sceneGroup property such as alpha or x which changes during a non-concurrent, custom made scene transition. You may have another approach with better speed results.

In your first version, the back of the page could be set as a color - is that easy to re-apply?

I have no idea how you do this stuff -  it’s wizards work!

Hi.

About to head off to sleep here, but I’ll try to give a quick couple points.

On the smoothness thing I don’t know off-hand. Increasing shader length and including a bunch of if branches isn’t a free lunch, but your other comments don’t make it sound like it’s slow. Hmm.

If you only want to set the back of the page, just remove the second CoronaColorScale (), which handles the “front”. (Actually, that’s probably better terminology than the “lower” and “upper” I used in the comments.)

Shadows aside, this effect is mostly just some geometry and trigonometry. But yeah, some effects can get quite arcane.  :slight_smile: