SKSpriteNode lighting doesn't work with textures from SKTextureAtlas

664 views Asked by At

I ran into a problem with SpriteKit (tried Xcode 7 beta and Xcode 6.4 on OS X 10.11 beta) where normal-mapped lighting breaks down if I create a SKTextureAtlas from the image and normal files that work when used individually. See this example:

enter image description here

From left to right:

  • Sprite with texture + normal + lighting (textures from atlas)
  • Sprite with texture + normal (textures from atlas)
  • Sprite with texture (texture from atlas)
  • Sprite with normal texture (texture from atlas)
  • Sprite with texture + normal + lighting (textures created from individual files via imageNamed:)

The atlas is created at runtime with SKTextureAtlas atlasWithDictionary: and it contains the following textures:

creating atlas with files: {
    "shield-normal.png" = "shield-normal.png";
    "shield.png" = "shield.png";
    "swords-normal.png" = "swords-normal.png";
    "swords.png" = "swords.png";
}

Note: I get the exact same problem if I create the Atlas in Xcode and load it via atlasNamed: - so the problem definitely isn't with how or when the atlas is created, but because the textures are obtained from the atlas in the first place.

If I create the sprite with individual files the lighting works (rightmost image):

tex = [SKTexture textureWithImageNamed:@"shield.png"];
normal = [SKTexture textureWithImageNamed:@"shield-normal.png"];
test2 = [SKSpriteNode spriteNodeWithTexture:tex normalMap:normal];
test2.position = CGPointMake(580, 400);
test2.lightingBitMask = 0xffffffff;
[self addChild:test2];

I do the exact same thing with the atlas files and the screenshot above proves that I do get the correct images (3rd and 4th from left) for the sprite texture and normal as textures from the atlas. Yet the result is the 1st image from the left, a lit sprite without normal mapping.

I wonder, do normal textures require a form of postprocessing that SKTextureAtlas doesn't apply? Or did anyone else have problems with normal textures in a atlas?

Or perhaps this might be a bug?


Update: I have reproduced this behavior in a new SpriteKit app (OS X, download it here and try for yourself) with the following code:

-(void)didMoveToView:(SKView *)view {
    SKLightNode* light = [SKLightNode node];
    light.position = CGPointMake(0, 0);
    [self addChild:light];

    id move1 = [SKAction moveByX:400 y:300 duration:3];
    id move2 = [SKAction moveByX:-400 y:-300 duration:3];
    id repeat = [SKAction repeatActionForever:[SKAction sequence:@[move1, move2]]];
    [light runAction:repeat];


    SKTexture* tex, *nor;
    SKSpriteNode* spr;
    {   // sprite with textures from individual files: lighting works
        tex = [SKTexture textureWithImageNamed:@"shield.png"];
        nor = [SKTexture textureWithImageNamed:@"shield-normal.png"];
        spr = [SKSpriteNode spriteNodeWithTexture:tex normalMap:nor];
        spr.position = CGPointMake(111, 111);
        spr.lightingBitMask = 0xffffffff;
        [self addChild:spr];
    }
    {   // sprite with textures from atlas: lighting does not work (no normal-map)
        SKTextureAtlas* atlas = [SKTextureAtlas atlasNamed:@"TicTac"];
        NSLog(@"atlas texture names: %@", atlas.textureNames);

        tex = [atlas textureNamed:@"shield.png"];
        nor = [atlas textureNamed:@"shield-normal.png"];
        spr = [SKSpriteNode spriteNodeWithTexture:tex normalMap:nor];
        spr.position = CGPointMake(222, 111);
        spr.lightingBitMask = 0xffffffff;
        [self addChild:spr];
    }
}
0

There are 0 answers