【问题标题】:How to use SceneKit vortex field to create a tornato effect如何使用 SceneKit 漩涡场创建龙卷风效果
【发布时间】:2018-09-01 14:35:03
【问题描述】:

在 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)

这会产生这种效果: 我在哪里俯视顺时针旋转的粒子,半径非常大。它看起来一点也不像龙卷风效果。如何创建这种效果?

【问题讨论】:

    标签: swift scenekit


    【解决方案1】:

    你说龙卷风,我说龙卷风,让我们把整个事情都取消……

    SceneKit WWDC 2014 演示/幻灯片是 sample code project,因此您可以亲眼看看他们是如何制作您在其中看到的任何效果的。在这种情况下,看起来“漩涡”演示实际上并没有使用vortexField API,而是使用自定义字段 API,它允许您在评估器块中提供自己的数学。 (请参阅该块中的代码链接。)

    您可以通过将涡旋(仅导致旋转)与径向重力(向内吸引)与线性重力(向下吸引)或其他一些组合(可能涉及电荷)相结合,在没有自定义字段的情况下获得类似的行为.但是您可能不得不尝试对参数进行相当多的调整。

    【讨论】:

    • 非常感谢!从来没有意识到他们把源放在网上。奇怪的是,他们如何在带有幻灯片的视频中说这是一个 vortexField,但它是一个自定义的(尽管它几乎是一个向内的 vortexField)。
    【解决方案2】:

    如果有人仍然对这个话题感兴趣 - 这是传说中的龙卷风效应的 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多