SceneKit - Crossfade Texture Property Textures

The documentation for SCNMaterialProperty.contents claims to be an animated property, and I can do crossfades between two colors. However, Im failed to cross between the two images.

So, I'm starting to wonder if this is possible at all, or do I need to create a custom shader for this?


Ive tried implicit animation, in which case it immediately displays "after image:

 node.geometry.firstMaterial.diffuse.contents = [UIImage imageNamed:@"before"]; [SCNTransaction begin]; [SCNTransaction setAnimationDuration:5]; node.geometry.firstMaterial.diffuse.contents = [UIImage imageNamed:@"after"]; [SCNTransaction commit]; 

Explicit animation that does nothing:

 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"contents"]; animation.fromValue = (__bridge id)[UIImage imageNamed:@"before"].CGImage; animation.toValue = (__bridge id)[UIImage imageNamed:@"after"].CGImage; animation.duration = 5; [node.geometry.firstMaterial.diffuse addAnimation:animation forKey:nil]; 

As with CALayer , which does nothing:

 CALayer *textureLayer = [CALayer layer]; textureLayer.frame = CGRectMake(0, 0, 793, 1006); textureLayer.contents = (__bridge id)[UIImage imageNamed:@"before"].CGImage; node.geometry.firstMaterial.diffuse.contents = textureLayer; CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"contents"]; animation.fromValue = (__bridge id)[UIImage imageNamed:@"before"].CGImage; animation.toValue = (__bridge id)[UIImage imageNamed:@"after"].CGImage; animation.duration = 5; [textureLayer addAnimation:animation forKey:nil]; 
+7
core-animation opengl-es scenekit
source share
2 answers

From my own testing, it doesn't seem like this property is really animated when texture values โ€‹โ€‹(rather than solid color values) are involved. Either this is an error in SceneKit (i.e., it should be animatable, but not working), or an error in Apple documents (i.e. It is not intended for animation, but they say that it is). In any case, you must remove this error so that you receive a notification when Apple fixes it.

(It also doesn't seem to be a tvOS-specific issue - I also see it on OS X.)

I can understand why animated texture transitions cannot be ... from the point of view of GL / Metal, which requires the binding of an additional texture unit and the presence of two texture searches per pixel (instead of one) during the transition.

I can come up with a couple worthy possible workarounds:

  • Use a shader modifier. Write a GLSL (ish) snippet that looks something like this:

     uniform sampler2D otherTexture; uniform float fadeFactor; #pragma body vec4 otherTexel = texture2D(otherTexture, _surface.diffuseTexcoord); _surface.diffuse = mix(_surface.diffuse, otherTexel, fadeFactor); 

    Set it on the material you want to animate using the SCNShaderModifierEntryPointSurface entry SCNShaderModifierEntryPointSurface . Then use setValue:forKey: to associate a SCNMaterialProperty with otherTexture and a CABasicAnimation to animate fadeFactor from 0 to 1.

  • Use something more animated (like a SpriteKit scene) as your material property, and animate it to complete the transition. (As a bonus, when you do this, you can use other transition styles.)

+6
source share

Your animation does not happen because the "content" property is animated only when set to a color other than the image. You can read it in the documentation for the content box.

0
source share

All Articles