SceneKit-Crossfade材质属性纹理 [英] SceneKit - Crossfade material property textures

查看:122
本文介绍了SceneKit-Crossfade材质属性纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

The documentation for SCNMaterialProperty.contents states that it is an animatable property and indeed I can perform a crossfade between two colors. However I’m unable to crossfade between two images.

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

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

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

I’ve tried an implicit animation, in which case it immediately shows the ‘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];

不执行任何操作的显式动画:

An explicit animation, which 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];


以及通过CALayer都不起作用:


As well as through a 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];

推荐答案

根据我自己的测试,当涉及纹理值(而不是纯色值)时,似乎该属性实际上不是可动画的.这可能是SceneKit中的错误(即本来可以进行动画处理,但不起作用),也可能是Apple文档中的错误(即,本来不是可以进行动画处理,但他们说是可以的).无论哪种方式,您都应该提交该错误,以便在Apple对其进行修复时得到通知.

From my own testing, it doesn't look like this property is actually animatable when texture values are involved (rather than solid color values). Either that's a bug in SceneKit (i.e. it's intended to be animatable but that's not working) or it's a bug in Apple's docs (i.e. it's not intended to be animatable but they say it is). Either way, you should file that bug so you get notified when Apple fixes it.

(这看起来也不是特定于tvOS的问题-我也在OS X上也看到了它.)

(It also doesn't look like this is a tvOS-specific issue -- I see it on OS X as well.)

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

I can understand why animated texture transitions might not be there... from a GL/Metal perspective, that requires binding an extra texture unit and having two texture lookups per pixel (instead of one) during the transition.

我可以想到一些不错的潜在解决方法:

I can think of a couple of decent potential workarounds:

  1. 使用着色器修改器.编写一个看起来像这样的GLSL(ish)代码段:

  1. 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);

使用SCNShaderModifierEntryPointSurface入口点将其设置在要设置动画的材质上.然后使用setValue:forKey:SCNMaterialPropertyotherTexture关联,并使用CABasicAnimationfadeFactor的动画从0设置为1.

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

使用更具动画性的内容(例如SpriteKit场景)作为材质属性内容,并对其进行动画处理以执行过渡. (此外,当您这样做时,可以使用其他过渡样式.)

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

这篇关于SceneKit-Crossfade材质属性纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆