頂点の影響が4未満の場合、SceneKitはGPUで骨格アニメーションを実行します。ドキュメントから、belowを再現:このジオメトリソースでcomponentsPerVector数が4以下である場合にのみ
SceneKitは、GPU上で、骨格アニメーションを実行します。ベクトルが大きくなると、CPUベースのアニメーションが生成され、レンダリングのパフォーマンスが大幅に低下します。
IアニメーションがGPU上で行われているかどうかを検出するために、次のコードを使用しています
- (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
を添付しているノードの名前GPUまたはCPU上で実行されます。
しかし、GPUにアニメーションに関する隠された情報が1つあります。これは、骨格が60以上のボーンを持つ場合、GPUで実行されないということです。無効なシェーダーモディファイアエントリをexplained in this postとしてアタッチして、デフォルトの頂点シェーダを印刷することです。
#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個の骨に限定されるべきであることを意味します
頂点シェーダは、次のスキニング関連するコードが含まれています。
すべてのキャラクターが同じスケルトンを持っている場合は、上記のヒントを使用してアニメーションがCPUまたはGPU上で実行されているかどうかを確認することをおすすめします。さもなければ、あなたのキャラクタースケルトンを修正しなければならないかもしれません。
まあ...私のキャラクターは9回の影響が2回以上あると言っています4 :-( 影響を減らす唯一の方法はありますか? – ColdSteel
残念ながら、影響を減らす必要があります。たとえば、私はBlenderを使用しているような状況に直面し、重みを再配分するためのPythonスクリプトを作成しました:https://gist.github.com/ dmsurti/b502074eae2976d5e7a0e0829520132bだから、体重を再描画せずに、そのような演算子を適用し、アニメーションデータを再エクスポートするか、またはあなたが作業している3Dアーティストがあなたのためにそれを行うことができるはずです –
私の3Dアーティストは3ds maxを使用し、彼のために多くの時間を取るために:-(あなたの答えは大変ありがとうございました。私は何とかして働かそうとします。 – ColdSteel