gpt4 book ai didi

iphone - 是否可以实现 MAX(As,Ad) openGL 混合?

转载 作者:行者123 更新时间:2023-12-03 18:20:17 24 4
gpt4 key购买 nike

我正在开发一款游戏,我想在网格上的一系列 Sprite 下创建阴影。阴影比 Sprite 本身大,并且 Sprite 是动画的(即移动和旋转)。

我不能简单地将它们渲染到 sprite png 中,否则阴影将与相邻的 sprite 重叠。

我也不能简单地将阴影本身放在较低层上,因为当它们重叠时,它们会在交叉处创建暗带。

这些 Sprite 是动画的,因此无法批量渲染它们。

基本上,我希望 Sprite 的阴影混合在一起,以便它们在设定的不透明度下达到最大。示例:

enter image description here

我相信这相当于 (Rs,Gs,Bs,Max(As,Ds)) 的 openGL 混合,我并不真正关心 R,G 和 B,因为它总是相同的src 和 dst 中的颜色。

但是,这不是有效的 openGL 混合模式。有没有一种简单的方法可以实现这一点,特别是在 cocos2d-iphone 中?

我可以通过使阴影 Sprite 不透明,然后将它们应用到父 Sprite ,并使父 Sprite 不透明度为 40% 来近似这一点。然而,cocos2d 的工作方式只是将每个子元素的不透明度设置为 40%,而不是组合 Sprite 图像,从而产生相同的条纹。

最佳答案

好吧,我想经过大量研究,我意识到我的想法是错误的。

首先,有一种方法可以进行 Max Alpha openGL 混合,那就是使用 glBlendEquations。您必须修改绘制方法才能执行此操作(并为纹理节点创建一些新属性以在这些方法之间切换),并使用以下任一方法:

 glBlendEquationOES( GL_MAX_EXT );
glBlendEquationSeparateOES( GL_FUNC_ADD_OES, GL_MAX_EXT );

第一个对 RGBA 使用 max(),第二个对 RGB 使用标准加法,对 alpha 使用 max()。

现在的问题是,每个 Sprite 及其子元素(按 z 顺序)都被绘制到屏幕。这意味着,绘制第一个阴影后,它就成为主屏幕缓冲区的一部分。换句话说,它的不透明度发生了变化,并且通过 max() 混合和标准的不透明背景,它现在被绘制到背景上,因此当您绘制下一个阴影时,它将执行 max(As, 1) ,即 1,因为背景是不透明的。所以我没有达到我想要的混合效果。如果我的背景是透明的,它会“工作”,但是我无法在其“后面”应用任何背景,我们只能添加到缓冲区。

我可以先使用 max() 混合绘制阴影,然后执行 {ONE_MINUS_DST_ALPHA, DST_ALPHA} glBlend。这是一个不错的解决方法,但我还有其他问题使这变得困难。

现在,我终于意识到,真正的解决方案是使用 RenderTexture 将阴影渲染到单独的缓冲区,然后再将它们应用到背景。这可能会对性能产生影响,所以我们将看看它会发生什么。

更新:

好的,我现在有了一个可行的解决方案。

奇怪的是,我最终不需要这个解决方案,因为在我的特殊情况下, strip 不够明显,不足以保证这一努力,但是这是我想出的解决方案,它似乎可以满足我的要求:

  1. 首先在整个屏幕上绘制一个 0% 黑色 alpha png。 (我不知道这是否有必要。我不知道屏幕的默认alpha是多少)。

  2. 使用 glEquationSeperateOES( GL_ADD, GL_MAX_ENT)glBlend( GL_ONE, GL_ONE ) 将阴影绘制到屏幕上。这将按照描述将所有阴影混合在一起,并采用 Alpha 的 max()。

    • 因为您要合成黑色,所以相当于使用 glBlendEquationOES( GL_MAX_ENT )。 (X+0 == max(X,0))

    • glBlend( GL_ZERO, GL_ONE ) 将消除步骤 1 的需要,或者至少消除该层为 0% 黑色的要求。 GL_ZERO 实质上强制其为 0% 黑色。

  3. 绘制地板,将其覆盖在阴影之上,但使用 glBlend( ONE_MINUS_DST_ALPHA, DST_ALPHA )。这会产生与使用 glBlend( SRC_ALPHA, ONE_MINUS_SRC_ALPHA ) 将阴影添加到地板完全相同的结果,但是如果您这样做,您将无法将阴影混合在一起 (请阅读答案顶部的原因)。

  4. 你完成了!此方法的好处是阴影 Sprite 可以像往常一样进行动画处理,而无需在单独的 renderTexture 上调用“visit”。

其余:

我还修改了 CocosNode,以允许我向链接到另一个 CocosNode 的图层添加阴影。这样,阴影将渲染为地板的子级(或用于阴影混合的 0% 黑色背景 Sprite ),但链接到另一个 CocosNode。当 Sprite 移动时,如果它有阴影,它也会更新阴影位置。这使我可以将所有阴影置于屏幕上所有对象的下方,并让阴影自动跟随对象。

抱歉回答太长。也许我的解决方案很笨拙,但看起来效果很好。

关于iphone - 是否可以实现 MAX(As,Ad) openGL 混合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2143690/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com