SceneKit animation animation increase

I have *.DAEfiles for characters, each has 45-70 bones, I want to have about 100 animated characters on the screen.

However, when I have ~ 60 characters, the animations take ~ 13 ms of the update cycle, which is very expensive and I have almost no space for other tasks.

I set the CAAnimationGroup animations to Mesh SCNNode when I want to share animations, I delete the previous animations with the ones fadeOutset to 0.2 and adding a new animation with FadeIn0.2. → Is it bad? Should I just pause the previous animation and play a new one? or is it even worse?

Are there any better ways to animate falsified characters in SceneKit, possibly using a GPU, or something like that?

Please bring me back in the right direction to reduce animation overhead in my update cycle.

Update After contacting Apple via Bug radar, I received this problem via E-Mail:

This problem will be fixed in a future update, we will inform you as soon as we have a beta version that you can check and verify this issue.

Thank you for your patience.

So, let's wait and see how Apple Engineers improves it :).

+1
source share
1 answer

SceneKit , 4 . :


SceneKit , componentsPerVector 4 . .


, , :

- (void)checkGPUSkinningForInScene:(SCNScene*)character
                          forNodes:(NSArray*)skinnedNodes {
  for (NSString* nodeName in skinnedNodes) {
    SCNNode* skinnedNode =
        [character.rootNode childNodeWithName:nodeName recursively:YES];
    SCNSkinner* skinner = skinnedNode.skinner;
    NSLog(@"******** Skinner for node %@ is %@ with skeleton: %@",
          skinnedNode.name, skinner, skinner.skeleton);
    if (skinner) {
      SCNGeometrySource* boneIndices = skinner.boneIndices;
      SCNGeometrySource* boneWeights = skinner.boneWeights;
      NSInteger influences = boneWeights.componentsPerVector;
      if (influences <= 4) {
        NSLog(@" This node %@ with %lu influences is skinned on the GPU",
              skinnedNode.name, influences);
      } else {
        NSLog(@" This node %@ with %lu influences is skinned on the CPU",
              skinnedNode.name, influences);
      }
    }
  }
}

SCNScene , SCNSkinner, , CPU.

GPU, , 60 , . , , , .

:

#ifdef USE_SKINNING
uniform vec4 u_skinningJointMatrices[60];

....

    #ifdef USE_SKINNING
  {
    vec3 pos = vec3(0.);
    #ifdef USE_NORMAL
    vec3 nrm = vec3(0.);
    #endif
  #if defined(USE_TANGENT) || defined(USE_BITANGENT)
    vec3 tgt = vec3(0.);
    #endif
    for (int i = 0; i < MAX_BONE_INFLUENCES; ++i) {
#if MAX_BONE_INFLUENCES == 1
        float weight = 1.0;
#else
        float weight = a_skinningWeights[i];
#endif
      int idx = int(a_skinningJoints[i]) * 3;
      mat4 jointMatrix = mat4(u_skinningJointMatrices[idx], u_skinningJointMatrices[idx+1], u_skinningJointMatrices[idx+2], vec4(0., 0., 0., 1.));
            pos += (_geometry.position * jointMatrix).xyz * weight;
      #ifdef USE_NORMAL
            nrm += _geometry.normal * mat3(jointMatrix) * weight;
      #endif
      #if defined(USE_TANGENT) || defined(USE_BITANGENT)
            tgt += _geometry.tangent.xyz * mat3(jointMatrix) * weight;
      #endif
    }
    _geometry.position.xyz = pos;

, 60 .

, , , . , 60 4 .

+2

Source: https://habr.com/ru/post/1673457/


All Articles