如何(有效地)测试SKTexture的可见内容?

时间:2021-09-14 10:40:40

My app currently animates thousands of "mini textures" with SpriteKit. The conversion process for each object of interest is UIView to UIImage to SKTexture to many, many, very small SKTextures (miniTextures). What I'm having trouble with is how to further process only those miniTextures that are "useful."

我的应用程序目前使用SpriteKit为数千个“迷你纹理”制作动画。每个感兴趣对象的转换过程是UIView到UTemage到SKTexture到很多很小的SKTextures(miniTextures)。我遇到的问题是如何进一步处理那些“有用”的miniTextures。

Many of the miniTextures, coming from blank parts of an object/view/image/texture, contain no useful visual information (i.e., they're blank). As such, it would be wasteful to animate them. The problem is, I don't know of any good, efficient test for this. I had hoped to somehow be able to examine each texture's pixels, and if every pixel in a texture had an alpha value of 0, that texture would not get processed (i.e., no SKSpriteNode would get created for it).

许多来自对象/视图/图像/纹理的空白部分的miniTextures不包含有用的视觉信息(即,它们是空白的)。因此,为它们制作动画会很浪费。问题是,我不知道有什么好的,有效的测试。我曾希望以某种方式能够检查每个纹理的像素,并且如果纹理中的每个像素都具有0的alpha值,那么该纹理将不会被处理(即,不会为其创建SKSpriteNode)。

As a workaround, I tried creating an SKPhysicsBody for each miniTexture (see code below), using SKPhysicsBody(texture: alphaThreshold: size:), which returns nil when nothing in the texture exceeds the alphaThreshold. That then might have at least allowed me to test for and selectively process the useful miniTextures. But when doing that, I ran into two problems: Firstly, the simulator slowed to a virtual standstill. Secondly, when making the textures very small, all of them were determined to be nil, regardless of my alphaThreshold.

作为一种解决方法,我尝试使用SKPhysicsBody(texture:alphaThreshold:size :)为每个miniTexture创建一个SKPhysicsBody(参见下面的代码),当纹理中没有任何内容超过alphaThreshold时,它返回nil。那可能至少让我测试并有选择地处理有用的miniTextures。但是当我这样做时,我遇到了两个问题:首先,模拟器减速到虚拟停顿状态。其次,当使纹理非常小时,无论我的alphaThreshold如何,它们都被确定为nil。

Insights? Solutions? Sympathy?

见解?解决方案?同情?

for j in stride(from: 0, to: 1, by: yFraction) {
    for i in stride(from: 0, to: 1, by: xFraction) {

        let miniTexture = SKTexture(rect: CGRect(x: CGFloat(i), 
                                                 y: CGFloat(j), 
                                                 width: CGFloat(xFraction), 
                                                 height: CGFloat(yFraction)), 
                                    in: texture)

        spriteNode.physicsBody = SKPhysicsBody(texture: miniTexture, 
                                               alphaThreshold: 0.5, 
                                               size: CGSize(width: 1, 
                                                            height: 1))

        // BUT WHEN THE miniTextures ARE VERY SMALL, THESE ALL ARE NIL!
        // AND THE ANIMATION COMES TO A VIRTUAL STANDSTILL!
        if spriteNode.physicsBody == 0 { continue }

        // spriteNode.position details here
        // spritNode.run(specificAnimation) details here

        let spriteNode = SKSpriteNode(texture: miniTexture)
        spriteNodes.addChild(spriteNode)
    }
}

1 个解决方案

#1


0  

As it turns out, SpriteKit already culls invisible and offscreen nodes by default, which may be why my app didn't perform poorly without testing for and removing fully transparent SKSpriteNodes. (But maybe my understanding is wrong, if by "invisible" Apple merely means "set to isHidden.")

事实证明,SpriteKit默认已经剔除了隐形和屏幕外节点,这可能就是为什么我的应用程序在没有测试和删除完全透明的SKSpriteNodes的情况下表现不佳的原因。 (但也许我的理解是错误的,如果通过“隐形”Apple只是意味着“设置为隐藏。”)

Apple's documentation of the shouldCullNonVisibleNodes instance property (default value is true) is here.

Apple的shouldCullNonVisibleNodes实例属性文档(默认值为true)就在这里。

A better, upstream solution would be to test for invisibility before creating the images/textures, but that would involve a deeper understanding of low-level iOS graphics manipulation than I currently have.

更好的上游解决方案是在创建图像/纹理之前测试不可见性,但这将涉及对我现有的低级iOS图形操作的更深入理解。

#1


0  

As it turns out, SpriteKit already culls invisible and offscreen nodes by default, which may be why my app didn't perform poorly without testing for and removing fully transparent SKSpriteNodes. (But maybe my understanding is wrong, if by "invisible" Apple merely means "set to isHidden.")

事实证明,SpriteKit默认已经剔除了隐形和屏幕外节点,这可能就是为什么我的应用程序在没有测试和删除完全透明的SKSpriteNodes的情况下表现不佳的原因。 (但也许我的理解是错误的,如果通过“隐形”Apple只是意味着“设置为隐藏。”)

Apple's documentation of the shouldCullNonVisibleNodes instance property (default value is true) is here.

Apple的shouldCullNonVisibleNodes实例属性文档(默认值为true)就在这里。

A better, upstream solution would be to test for invisibility before creating the images/textures, but that would involve a deeper understanding of low-level iOS graphics manipulation than I currently have.

更好的上游解决方案是在创建图像/纹理之前测试不可见性,但这将涉及对我现有的低级iOS图形操作的更深入理解。