开发者

iOS: Smooth button Glow effect by blending between images

开发者 https://www.devze.com 2023-03-01 09:01 出处:网络
I am creating a custom button that needs to be able to glow to a varying degree How would I use these pictures to make a button that \'glows\' the diamond when it is pressed,and have this glow grad

I am creating a custom button that needs to be able to glow to a varying degree

iOS: Smooth button Glow effect by blending between images

How would I use these pictures to make a button that 'glows' the diamond when it is pressed, and have this glow gradually fade back to inert state?

I want to churn out several different colours of diamond as well... I am hoping to generate all different coloured diamonds from the same stock images presented here.

I would like to get my head around the basic methods available, in enough detail that I can see each one through and make a decision which path to take...


My tangled efforts so far... ( I will delete all of this, or move it into possibly several answers as a solution unfolds... )

I can see 3 potential solution paths:

  • GL

    it looks as though GL has everything it takes to get complete fine-grained control over the process, although functions exposed by core graphics come tantalisingly close, and that would save several hundred lines of code spread over a bunch of source files, which seems a bit ridiculous for such a basic task.

  • core graphics, and core animation to accomplish the blending

    iOS: Smooth button Glow effect by blending between images

    documentation goes on to say

    Anything underneath the unpainted samples, such as the current fill color or other drawing, shows through.

    so I can chroma-key mask the left image, setting {0,0,0} ie Black as the key.

    this at least secures a transparent background, now I have to work on making it yellow instead of grey.

    so maybe I could have started instead with setting a yellow back colour for my image context, then use some CGContextSetBlendMode(...) to imprint the开发者_运维知识库 diamond on the yellow, THEN use chroma-key masking to get a transparent background

    ok, this covers at least getting the basic unlit image on-screen

    now I could overlay the sparkly image, using some blend mode, maybe I could keep it in its current greyscale state, and that would just boost the colours of the original

    only problem with this is that it is a lot of heavy real-time blending

    so maybe I could pre-calculate every image in the animation... this is looking increasingly mucky...

  • Cocos2D

    if this allows me to set the blend mode to additive blending then I could just composite the glowing image over the original image with an appropriate Alpha setting.


After digging through a lot of documentation, the optimal solution seems to be to use core graphics functions to get the source images into a single 2-component GL texture, and then use GL to blend between them.

I will need to pass a uniform value glow_factor into the shader

The obvious solution might seem to simply use

r,g,b = in_r,g,b * { (1 - glow_factor) * inertPixel + glow_factor * shinyPixel }

(where inertPixel is the appropriate pixel of the inert diamond etc)...

it looks like I would also do well to manufacture my own sparkles and add them over the top; a gem should sparkle white irrespective of its characteristic colour.


After having looked at this problem a little more, I can see several solutions

Solution A -- store the transition from glow=0 to glow=1 as 60 frames in memory, then load the appropriate frame into a GL texture every time it is required.

this has an obvious benefit that a graphic designer could construct the entire sequence and I could load it in as a bunch of PNG files.

another advantage is that these frames wouldn't need to be played in sequence... the appropriate frame can be chosen on-the-fly

however, it has a potential drawback of a lot of sending data RAM->VRAM

this can be optimised by using glTexSubImage2D; several frames can be sent simultaneously and then unpacked from within GL... in fact maybe the entire sequence. if this is so, then it would make sense to use PVRT texture compression.

iOS: playing a frame-by-frame greyscale animation in a custom colour

Solution B -- load glow=0 and glow=1 images as GL textures, and manually write shader code that takes in the glow factor as a uniform and performs the blend

this has an advantage that it is close to the wire and can be tweaked in all sorts of ways. Also it is going to be very efficient. This advantage is that it is a big extra slice of code to maintain.

Solution C -- set glBlendMode to perform additive blending.
then draw the glow=0 image image, setting eg alpha=0.2 on each vertex.
then draw the glow=1 image image, setting eg alpha=0.8 on each vertex.

this has an advantage that it can be achieved with a more generic code structure -- ie a very general ' draw textured quad / sprite ' class.

disadvantage is that without some sort of wrapper it is a bit messy... in my game I have a couple of dozen diamonds -- at any one time maybe 2 or 3 are likely to be glowing. so first-pass I would render EVERYTHING ( just need to set Alpha appropriately for everything that is glowing ) and then on the second pass I could draw the glowing sprite again with appropriate Alpha for everything that IS glowing.


it is worth noting that if I pursue solution A, this would involve creating some sort of real-time movie player object, which could be a very useful reusable code component.

0

精彩评论

暂无评论...
验证码 换一张
取 消