opengl-es - SceneKit - 交叉淡入淡出 Material 属性纹理

标签 opengl-es core-animation scenekit

SCNMaterialProperty.contents 的文档声明它是一个动画属性,实际上我可以在两种颜色之间执行交叉淡入淡出。但是我无法在两个图像之间交叉淡入淡出。

所以我开始怀疑这是否可能,或者我是否需要为此创建一个自定义着色器?

我尝试了一个隐式动画,在这种情况下它会立即显示“后”图像:

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

一个明确的动画,它什么都不做:
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];

以及通过 CALayer ,什么都不做:
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];

最佳答案

从我自己的测试来看,当涉及纹理值(而不是纯色值)时,这个属性实际上并不是可动画的。要么是 SceneKit 中的错误(即它旨在动画化但不起作用),要么它是 Apple 文档中的错误(即它不打算动画化但他们说它是)。无论哪种方式,您都应该 file that bug所以当 Apple 修复它时你会收到通知。

(看起来这也不是 tvOS 特有的问题——我在 OS X 上也看到了。)

我可以理解为什么动画纹理过渡可能不存在......从 GL/Metal 的角度来看,这需要绑定(bind)一个额外的纹理单元并在过渡期间每个像素(而不是一个)有两个纹理查找。

我可以想到几个不错的潜在解决方法:

  • 使用着色器修改器。编写一个看起来像这样的 GLSL(ish) 片段:
    uniform sampler2D otherTexture;
    uniform float fadeFactor;
    #pragma body
    vec4 otherTexel = texture2D(otherTexture, _surface.diffuseTexcoord);
    _surface.diffuse = mix(_surface.diffuse, otherTexel, fadeFactor);
    

    使用 SCNShaderModifierEntryPointSurface 将其设置在您要设置动画的 Material 上入口点。然后使用 setValue:forKey:关联 SCNMaterialPropertyotherTextureCABasicAnimationfadeFactor 设置动画从 0 到 1。
  • 使用更具动画效果的东西(如 SpriteKit 场景)作为您的 Material 属性内容,并对其进行动画处理以执行过渡。 (作为奖励,当您这样做时,您可以使用其他过渡样式。)
  • 关于opengl-es - SceneKit - 交叉淡入淡出 Material 属性纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33235058/

    相关文章:

    swift - SCNCamera 限制弧球旋转

    objective-c - 在 cocos2d 2.0 中重复绑定(bind)到山丘的 OpenGL-es 纹理

    Android:跨屏幕旋转保留 EGLContext

    ios - 在 iOS 中将 NPOT PVR 纹理转换为 POT

    android - 尽管更改渲染模式,GLSurfaceView 仍持续渲染

    objective-c - 核心动画对图像数组进行动画处理

    ios - UIImageView 的显示速度比 CG 或 CALayer 快得多。有人知道为什么吗?

    ios - 使用AVSynchronizedLayer时动画无法开始

    ios - 使用AVCaptureDevice作为SCNScene背景内容

    ios - 错误 "OBJ file has no faces"