简体   繁体   English

iOS:通过在图像之间混合的平滑按钮发光效果

[英]iOS: Smooth button Glow effect by blending between images

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 gradually fade back to inert state?我将如何使用这些图片制作一个按钮,当它被按下时“发光”钻石,并让这种发光逐渐消退到惰性 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:我可以看到 3 个潜在的解决方案路径:

  • 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.看起来 GL 似乎拥有对流程进行完全细粒度控制所需的一切,尽管核心图形暴露的功能非常接近,这将节省分布在一堆源文件中的数百行代码,这似乎是一个对于这样一个基本任务来说有点荒谬。

  • core graphics , and core animation to accomplish the blending核心显卡核心animation完成融合

    色度键掩蔽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.所以我可以用色度键屏蔽左侧图像,设置 {0,0,0} 即黑色作为键。

    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所以也许我可以开始为我的图像上下文设置黄色背景颜色,然后使用一些 CGContextSetBlendMode(...) 将钻石印在黄色上,然后使用色度键蒙版来获得透明背景

    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现在我可以覆盖闪亮的图像,使用一些混合模式,也许我可以将它保持在当前的灰度 state,这只会增强原始的颜色

    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...所以也许我可以预先计算 animation 中的每个图像......这看起来越来越脏......

  • Cocos2D 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.如果这允许我将混合模式设置为加法混合,那么我可以使用适当的 Alpha 设置将发光图像合成到原始图像上。

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.经过大量文档的挖掘,最佳解决方案似乎是使用核心图形功能将源图像变成单个 2-component GL 纹理,然后使用 GL 将它们混合。

I will need to pass a uniform value glow_factor into the shader我需要将一个统一的值 gloom_factor 传递给着色器

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)... (其中 inertPixel 是惰性钻石等的适当像素)...

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.解决方案A——在memory中存储从glow=0到glow=1的过渡为60帧,然后每次需要时将适当的帧加载到GL纹理中。

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.这有一个明显的好处,即图形设计师可以构建整个序列,我可以将它作为一堆 PNG 文件加载。

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但是,它有一个潜在的缺点,即大量发送数据 RAM->VRAM

this can be optimised by using glTexSubImage2D;这可以通过使用 glTexSubImage2D 进行优化; several frames can be sent simultaneously and then unpacked from within GL... in fact maybe the entire sequence.可以同时发送几个帧,然后从 GL 中解包……实际上可能是整个序列。 if this is so, then it would make sense to use PVRT texture compression.如果是这样,那么使用 PVRT 纹理压缩将是有意义的。

iOS: playing a frame-by-frame greyscale animation in a custom colour iOS:以自定义颜色播放逐帧灰度 animation

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解决方案B——将glow=0和glow=1的图像加载为GL纹理,并手动编写着色器代码,将辉光因子作为一个uniform并执行混合

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.解决方案 C -- 设置 glBlendMode 以执行加法混合。
then draw the glow=0 image image, setting eg alpha=0.2 on each vertex.然后绘制发光=0 图像图像,例如在每个顶点上设置 alpha=0.2。
then draw the glow=1 image image, setting eg alpha=0.8 on each vertex.然后绘制发光=1 图像图像,例如在每个顶点上设置 alpha=0.8。

this has an advantage that it can be achieved with a more generic code structure -- ie a very general ' draw textured quad / sprite ' class.这有一个优势,它可以通过更通用的代码结构来实现——即非常通用的'绘制纹理四边形/精灵'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.缺点是没有某种包装会有点乱……在我的游戏中,我有几十颗钻石——在任何时候,可能有 2 或 3 颗钻石可能会发光。 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.所以第一遍我会渲染一切(只需要为所有发光的东西适当地设置Alpha),然后在第二遍我可以用适当的Alpha再次为所有发光的东西绘制发光的精灵。


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.值得注意的是,如果我追求解决方案 A,这将涉及创建某种实时电影播放器 object,这可能是一个非常有用的可重用代码组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM