Search code examples
swiftscenekitarkitsimdrealitykit

Understanding SceneKit's SIMD


I'm trying to understand Apple documentation regarding Scenekit, finding some issue when talking about SCNNode variables:

for example, what the difference between apply the scale using simdScale variable or scale variable?

Reading the doc, can't understand when and why using the variables under "Managing the Node’s Transform (SceneKit Types)" and when use the variables under Managing the Node's Transform

for example, is better to change the scale of a SCNode using var "scale" or simdScale?


Solution

  • SIMD is Single Instruction, Multiple Data. Up-to-date CPU designs include SIMD instructions to improve the performance of 3D graphics and multimedia. Touching your question, the main difference between SCNVector3 and SIMD3<Float> structs is in their initializers. SCNVector3 supports:

    • Float, Double, CGFloat, Int, SIMD3<Float> and SIMD3<Double> types

    for X, Y and Z elements. As you know, SIMD3<Float> and its simd_float3 typealias supports only 32-bit Float. By the way, SIMD3<Float> is actively used in RealityKit.

    So, in SceneKit you can use both SCNVector3 and SIMD3<Float> depending on what type needed for particular instance property. Here's eight examples, showing how you can scale a SCNNode. In all these examples we use the same scaling values (x=5, y=2, z=5).

    1.

    let node = SCNNode()
    
    node.scale = SCNVector3(5, 2, 5)
    
    node.simdScale = simd_float3(5, 2, 5)
    
    node.simdScale = SIMD3<Float>(5, 2, 5)
    
    node.transform.m11 = 5
    node.transform.m22 = 2
    node.transform.m33 = 5
    
    node.transform = SCNMatrix4( m11: 5, m12: 0, m13: 0, m14: 0,
                                 m21: 0, m22: 2, m23: 0, m24: 0,
                                 m31: 0, m32: 0, m33: 5, m34: 0,
                                 m41: 0, m42: 0, m43: 0, m44: 1 )
    
    node.simdTransform.columns.0.x = 5
    node.simdTransform.columns.1.y = 2
    node.simdTransform.columns.2.z = 5
    
    node.simdTransform = simd_float4x4(diagonal: SIMD4<Float>(5, 2, 5, 1))
    
    node.simdTransform = .init( SIMD4<Float>(5, 0, 0, 0),
                                SIMD4<Float>(0, 2, 0, 0),
                                SIMD4<Float>(0, 0, 5, 0),
                                SIMD4<Float>(0, 0, 0, 1) )
    


    If you need more info about 4x4 matrices and simd_float4x4 type, read my Medium story.