在SceneKit WWDC 2014中,他们有一个具有此效果的涡旋场示例:
粒子系统看起来很像龙卷风,因为它向内旋转有一个空心。
但是,涡旋字段的文档没有关于如何实现此效果的信息。现在,我有这个:
// create the particle system
let exp = SCNParticleSystem()
exp.loops = true
exp.particleMass = 5
exp.birthRate = 10000
exp.emissionDuration = 10
exp.emitterShape = SCNTorus(ringRadius: 5, pipeRadius: 1)
exp.particleLifeSpan = 15
exp.particleVelocity = 2
exp.particleColor = UIColor.white
exp.isAffectedByPhysicsFields = true
scene.addParticleSystem(exp, transform: SCNMatrix4MakeRotation(0, 0, 0, 0))
// create the field
let field = SCNPhysicsField.vortex()
field.strength = -5
field.direction = SCNVector3(x: 0, y: 1, z: 0)
let fieldNode = SCNNode()
fieldNode.physicsField = field
scene.rootNode.addChildNode(fieldNode)
答案 0 :(得分:1)
你说龙卷风,我说龙卷风,让我们把整个事情搞定......
SceneKit WWDC 2014演示/幻灯片是sample code project,因此您可以亲自了解他们如何制作您在其中看到的任何效果。在这种情况下,看起来“vortex”演示实际上并没有使用vortexField
API,而是使用自定义字段API,它允许您在评估程序块中提供自己的数学运算。 (请参阅该块中代码的链接。)
通过将涡旋(仅引起旋转)与径向重力(吸引向内)与线性重力(向下吸引)或其他一些组合(可能涉及电荷的东西)相结合,您可能能够在没有自定义场的情况下获得类似的行为。但是你可能不得不尝试相当多地调整参数。
答案 1 :(得分:0)
如果有人仍然对这个话题感兴趣 - 这是传说中的龙卷风效果的 Swift 5 实现。
这是一个可以创建龙卷风的示例函数。
func addTornadoPhysicsField() {
// Tornado Particles Field Example
guard let tornadoSystem = SCNParticleSystem(named: "tornado.scnp", inDirectory: nil) else { return }
let emitterGeometry = SCNTorus(ringRadius: 1.0, pipeRadius: 0.2)
emitterGeometry.firstMaterial?.transparency = 0.0
let fieldAndParticleNode = SCNNode(geometry: emitterGeometry)
fieldAndParticleNode.position = SCNVector3(0.0, 0.0, -20.0)
tornadoSystem.emitterShape = emitterGeometry
fieldAndParticleNode.addParticleSystem(tornadoSystem)
yourScene.rootNode.addChildNode(fieldAndParticleNode)
// Tornado
let worldOrigin = SCNVector3Make(fieldAndParticleNode.worldTransform.m41,
fieldAndParticleNode.worldTransform.m42,
fieldAndParticleNode.worldTransform.m43)
let worldAxis = simd_float3(0.0, 1.0, 0.0) // i.Ex. the Y axis
// Custom Field (Tornado)
let customVortexField = SCNPhysicsField.customField(evaluationBlock: { position, velocity, mass, charge, time in
let l = simd_float3(worldOrigin.x - position.x, 1.0, worldOrigin.z - position.z)
let t = simd_cross(worldAxis, l)
let d2: Float = l.x * l.x + l.z * l.z
let vs: Float = 27 / sqrt(d2) // diameter, the bigger the value the wider it becomes (Apple Default = 20)
let fy: Float = 1.0 - Float((min(1.0, (position.y / 240.0)))) // rotations, a higher value means more turn arounds (more screwed, Apple Default = 15.0))
return SCNVector3Make(t.x * vs + l.x * 10 * fy, 0, t.z * vs + l.z * 10 * fy)
})
customVortexField.halfExtent = SCNVector3Make(100, 100, 100)
fieldAndParticleNode.physicsField = customVortexField // Attach the Field
}
其他配置选项:
最后,这一切都会导致这样的结果:
注意:如果您想像真正的龙卷风一样移动静态龙卷风,则必须找到一种方法来为每个渲染帧重新应用物理场。如果你不这样做,评估块中使用的世界原点将不会移动,它会扭曲你的龙卷风。
注意:您还可以将粒子/场节点拆分为两个彼此独立移动的不同节点。将场节点约束到粒子节点的位置,玩转影响因子(每帧还需要重新应用场)
有关自定义字段的更多信息,请查看 here。