【问题标题】:SKEffectNode to an SKTexture?SKEffectNode 到 SKTexture?
【发布时间】:2017-03-01 01:32:17
【问题描述】:

SKEffectionNodes 有一个 shouldRasterise “开关”,可以将它们烘焙到位图中,并且在受效果影响的底层节点发生更改之前不会更新它们。

但是我找不到从这个光栅化的“图像”创建SKTexture 的方法。

是否可以从SKEffectNode 获得SKTexture

【问题讨论】:

  • 你到底想做什么?许多游戏资产是在非游戏时间构建的。所以问题是你可以在游戏之外使用其他方式创建它而不是在游戏中生成它们吗?
  • 我正在为一堆按钮制作性感的阴影和发光,其中许多颜色不同,我想使用 SKSpriteNode.color 和混合量动态更改它们的颜色。已经想好怎么做了。在概念性问题之后,还有第二个问题,即超出精灵边界的光晕和阴影模糊,并以丑陋的方式被裁剪。也解决了。有点hacky,但它有效。现在性能好多了,也节省了很多节点。
  • @MobileBen 如果没有您的工厂提示,我无法做到。这是一大步,拥有一个带有 SKView 的单独空间,可以在远离“屏幕”的空间中进行渲染。没必要,但给了我精神上的空间来弄清楚如何去做,而不是得到丑陋的庄稼
  • @MobileBen 添加了答案,包括设计人员对编码缩进模式的考虑

标签: ios sprite-kit sktexture skeffectnode


【解决方案1】:

我认为您可以尝试这样的代码(这只是一个示例):

if let effect = SKEffectNode.init(fileNamed: "myeffect") {
    effect.shouldRasterize = true
    self.addChild(effect)   
    ...         
    let texture = SKView().texture(from: self)
}

更新

在你回答之后,希望我能更好地理解你想要达到的目标。

这是我的观点:如果你想制作纹理的阴影,你可以简单地用这个纹理创建一个SKSpriteNode

let shadow = SKSpriteNode.init(texture: <yourTexture>)
shadow.blendMode = SKBlendMode.alpha
shadow.colorBlendFactor = 1
shadow.color = SKColor.black
shadow.alpha = 0.25

我想说的是,你可以一步一步来:

  • 获取您的纹理
  • 细化您的纹理(添加过滤器,制作其他效果..)
  • 得到阴影

这种工作方式产生了一系列有用的方法,您可以在项目中使用这些方法来构建其他类型的元素。 也许,通过分离你不需要使用的任务texture(from:)

【讨论】:

  • 您可能需要稍后再捕获纹理,效果可能不会在创建时发生,因为它可能在 GPU 上完成,因此无法保证执行时间。
  • 正确,我正在考虑一种等待渲染的调度延迟,但不安全,我们有正确的结果和丑陋的
  • 我想你总是可以在下一次更新时捕获它,我不知道任何“完成绘图”方法
【解决方案2】:

我已经用工厂解决了我的问题。

阅读更多关于如何制造工厂的信息,来自BenMobile's 耐心和清晰的表达,这里:Factory creation and use for making Sprites and Shapes

模糊SKTextureSKSpriteNode 会出现空间不足的问题。模糊/发光超出了精灵的边缘。为了解决这个问题,在下面,您将看到我创建了一个“成帧器”对象。这只是一个空的SKSpriteNode,它是要模糊的纹理大小的两倍。要模糊的纹理作为子对象添加到此“成帧器”对象。

不管这有多骇人听闻,它都能正常工作;)

在静态工厂类文件中:

import SpriteKit

class Factory {

    private static let view:SKView = SKView()  // the magic. This is the rendering space

    static func makeShadow(from source: SKTexture, rgb: SKColor, a: CGFloat) -> SKSpriteNode {
        let shadowNode = SKSpriteNode(texture: source)
            shadowNode.colorBlendFactor = 0.5  // near 1 makes following line more effective
            shadowNode.color = SKColor.gray // makes for a darker shadow. White for "glow" shadow
        let textureSize = source.size()
        let doubleTextureSize = CGSize(width: textureSize.width * 2, height: textureSize.height * 2)
        let framer = SKSpriteNode(color: UIColor.clear, size: doubleTextureSize)
            framer.addChild(shadowNode)
        let blurAmount = 10
        let filter = CIFilter(name: "CIGaussianBlur")
            filter?.setValue(blurAmount, forKey: kCIInputRadiusKey)
        let fxNode = SKEffectNode()
            fxNode.filter = filter
            fxNode.blendMode = .alpha
            fxNode.addChild(framer)
            fxNode.shouldRasterize = true
        let tex = view.texture(from: fxNode) // ‘view’ refers to the magic first line
        let shadow = SKSpriteNode(texture: tex)  //WHOOPEE!!! TEXTURE!!!
            shadow.colorBlendFactor = 0.5
            shadow.color = rgb
            shadow.alpha = a
            shadow.zPosition = -1

        return shadow
    }
}

在您可以访问要为其制作阴影或发光纹理的 Sprite 的任何地方:

shadowSprite = Factory.makeShadow(from: button, rgb: myColor, a: 0.33)
shadowSprite.position = CGPoint(x: self.frame.midX, y: self.frame.midY - 5)
addChild(shadowSprite)

- button 是要赋予阴影的按钮的纹理。 a: 是一个 alpha 设置(实际上是透明度级别,0.0 到 1.0,其中 1.0 是完全不透明的),这个值越低阴影越亮。

该定位用于将阴影稍微放在按钮下方,因此看起来光线从顶部射入,将阴影向下投射到背景上。

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    相关资源
    最近更新 更多