我有一个对象,在初始化期间创建一个几何体。
class Helix {
var width: GLfloat // x
var height: GLfloat // y
var depth: GLfloat // z
var radius: GLfloat
var pitchInherent: GLfloat
var pitchCurrent: GLfloat
/* Other SceneKit related properties used later */
init(width: Float, height: Float, depth: Float) {
/* Geometry logic */
geometry = SCNGeometry(sources: [vertexSource], elements: [element])
}
func getNode() -> SCNNode {
return SCNNode(geometry: geometry)
}
}
然后在我的视图控制器中,我将它添加到节点树。
let scene = SCNScene()
let helix = Helix(width: 30, height: 30, depth: 30)
let helixNode = helix.getNode()
scene.rootNode.addChildNode(helixNode)
我想为pitchCurrent
属性设置动画。在自定义Objective-C
对象的CALayer
世界中,我曾经将我想要设置为动态的属性dynamic
指定为适当的key
指定了一个侦听器。在这种情况下我该怎么做?
答案 0 :(得分:2)
每帧重建一个顶点数组并不是那么糟糕。但是,每帧重新上传到GPU,可能不会带来让您的一天变亮的性能。
相反,我建议使用shader modifiers在GPU的顶点阶段自定义几何体。 (请务必点击该页面顶部的"更多"链接进行详细讨论。)您甚至可以将其与自定义Helix
课程结合使用,以更改宽度/半径/音高来自Swift的/ etc参数很简单 - 实现SCNShadable
的SceneKit对象自动使用KVO让你将GLSL制服视为类属性。
要执行此操作,您首先需要重构,以便Helix
子类SCNGeometry
或SCNNode
,然后,就像在CALayer
情况下一样,声明您的属性为dynamic
。
然后,创建一个执行几何自定义的GLSL片段:
// declare uniforms whose names match your class' dynamic properties
uniform float width;
uniform float height;
// etc
// do your geometry math
_geometry.position = /* Geometry logic */
最后,使用shaderModifiers
入口点将此代码段分配给您的节点的SCNShaderModifierEntryPointGeometry
:
let shader = "all that GLSL stuff above" // or better, load it from a file
geometry.shaderModifiers = [ SCNShaderModifierEntryPointGeometry: shader ]
此时,您应该能够创建自定义Helix节点/几何的实例,并使用SceneKit的任何动画技巧来为其width
,height
等属性设置动画。