/// <summary> /// 设置动画片段的Material->Shader属性,使用GPU计算动画片段数据 /// </summary> /// <param name="mpb"> 需要设置的MaterialPropertyBlock </param> /// <param name="playingClip"> 当前播放的动画片段 </param> /// <param name="frameIndex"> 帧索引 </param> /// <param name="frame"> 帧数据 </param> /// <param name="rootMotionEnabled"> 是否应用RootMotion </param> /// <param name="lastPlayedClip"> 上一次播放的动画片段 </param> /// <param name="frameIndex_crossFade"> 需要CrossFade的上一个动画片段帧索引(上一次播放到的动画片段) </param> /// <param name="crossFadeTime"> CrossFade所花的时间 </param> /// <param name="crossFadeProgress"> CrossFade已经处理的时间 </param> public void UpdatePlayingData( MaterialPropertyBlock mpb, GPUSkinningClip playingClip, int frameIndex, GPUSkinningFrame frame, bool rootMotionEnabled, GPUSkinningClip lastPlayedClip, int frameIndex_crossFade, float crossFadeTime, float crossFadeProgress) { //Profiler.BeginSample("Res.UpdatePlayingData"); //设置mpb的Vector属性 mpb.SetVector(shaderPorpID_GPUSkinning_FrameIndex_PixelSegmentation, new Vector4(frameIndex, playingClip.pixelSegmentation, 0, 0)); //如果开启RootMotion if (rootMotionEnabled) { Matrix4x4 rootMotionInv = frame.RootMotionInv(anim.rootBoneIndex); mpb.SetMatrix(shaderPropID_GPUSkinning_RootMotion, rootMotionInv); } //如果开启CrossFade if (IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress)) { if (lastPlayedClip.rootMotionEnabled) { mpb.SetMatrix(shaderPropID_GPUSkinning_RootMotion_CrossFade, lastPlayedClip.frames[frameIndex_crossFade].RootMotionInv(anim.rootBoneIndex)); } mpb.SetVector(shaderPorpID_GPUSkinning_FrameIndex_PixelSegmentation_Blend_CrossFade, new Vector4(frameIndex_crossFade, lastPlayedClip.pixelSegmentation, CrossFadeBlendFactor(crossFadeProgress, crossFadeTime))); } //Profiler.EndSample(); }
public void UpdatePlayingData(MaterialPropertyBlock mpb, GPUSkinningClip playingClip, int frameIndex, GPUSkinningFrame frame, bool rootMotionEnabled) { mpb.SetFloat(shaderPorpID_GPUSkinning_FrameIndex, frameIndex); mpb.SetFloat(shaderPropID_GPUSkinning_PixelSegmentation, playingClip.pixelSegmentation); mpb.SetFloat(shaderPropID_GPUSkinning_RootMotionEnabled, rootMotionEnabled ? 1 : -1); if (rootMotionEnabled) { Matrix4x4 rootMotionInv = frame.RootMotionInv(anim.rootBoneIndex); mpb.SetMatrix(shaderPropID_GPUSkinning_RootMotion, rootMotionInv); } }
private void UpdateJoints(GPUSkinningFrame frame) { if (joints == null) { return; } //fzy delete:never used //Matrix4x4[] matrices = frame.matrices; GPUSkinningBone[] bones = res.anim.bones; int numJoints = joints.Count; for (int i = 0; i < numJoints; ++i) { GPUSkinningPlayerJoint joint = joints[i]; Transform jointTransform = Application.isPlaying ? joint.Transform : joint.transform; if (jointTransform != null) { // TODO: Update Joint when Animation Blend Matrix4x4 jointMatrix = frame.matrices[joint.BoneIndex] * bones[joint.BoneIndex].BindposeInv; if (playingClip.rootMotionEnabled && rootMotionEnabled) { jointMatrix = frame.RootMotionInv(res.anim.rootBoneIndex) * jointMatrix; } jointTransform.localPosition = jointMatrix.MultiplyPoint(Vector3.zero); Vector3 jointDir = jointMatrix.MultiplyVector(Vector3.right); Quaternion jointRotation = Quaternion.FromToRotation(Vector3.right, jointDir); jointTransform.localRotation = jointRotation; } else { joints.RemoveAt(i); --i; --numJoints; } } }
/// <summary> /// 根据当前动画片段播放状态设置Material /// fzy remak:CPU资源消耗过多 /// </summary> /// <param name="deltaTime">本帧Update消耗的时间</param> private void UpdateMaterial(float deltaTime) { //Profiler.BeginSample("UpdateMaterial.Other"); int frameIndex = GetFrameIndex(); //动画片段(WrapMode.Once)播放完毕 if (lastPlayingClip == playingClip && lastPlayingFrameIndex == frameIndex) { //res.Update(deltaTime); resTime += deltaTime; //for (int i = 0; i < playerMonosCount; i++) // playerMonos[i].UpdateMaterial(deltaTime); return; } //记录上一帧播放的动画片段 lastPlayingClip = playingClip; //记录上一次播放的动画片段帧数(有可能跳帧) lastPlayingFrameIndex = frameIndex; blend_crossFade = 1; frameIndex_crossFade = -1; // 新建动画帧,用于crossFade GPUSkinningFrame frame_crossFade = null; if (IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress)) { frameIndex_crossFade = GetCrossFadeFrameIndex(); frame_crossFade = lastPlayedClip.frames[frameIndex_crossFade]; blend_crossFade = CrossFadeBlendFactor(crossFadeProgress, crossFadeTime); } GPUSkinningFrame frame = playingClip.frames[frameIndex]; //Profiler.EndSample(); //模型可以被看见(Culling)或者CullingMode为AlwaysAnimate if (Visible || CullingMode == GPUSKinningCullingMode.AlwaysAnimate) { //author version //res.Update(deltaTime); resTime += deltaTime; //fzy remark:不需要每帧调用,已在初始化时设置属性 //for (int i = 0; i < playerMonosCount; i++) //{ // playerMonos[i].UpdateMaterial(deltaTime); //} /*author version * res.UpdatePlayingData( * mpb, playingClip, frameIndex, frame, playingClip.rootMotionEnabled && rootMotionEnabled, * lastPlayedClip, GetCrossFadeFrameIndex(), crossFadeTime, crossFadeProgress * ); * mr.SetPropertyBlock(mpb);*/ //if (Time.frameCount % updatePreFrame != updateRemark) return; //Profiler.BeginSample("UpdatePlayingData"); //计算临时变量 isRootMotionEnabled = playingClip.rootMotionEnabled && rootMotionEnabled; framePixelSegmentation = new Vector4(frameIndex, playingClip.pixelSegmentation, 0, 0); rootMotionInv = frame.RootMotionInv(anim.rootBoneIndex); if (lastPlayedClip != null && frameIndex_crossFade >= 0) { framePixelSegmentation_Blend_CrossFade = new Vector4(frameIndex_crossFade, lastPlayedClip.pixelSegmentation, CrossFadeBlendFactor(crossFadeProgress, crossFadeTime)); rootMotionInv_Last = lastPlayedClip.frames[frameIndex_crossFade].RootMotionInv(anim.rootBoneIndex); } //设置动画播放的Material数据 //UpdatePlayingData(framePixelSegmentation, rootMotionInv, isRootMotionEnabled, rootMotionInv_Last, framePixelSegmentation_Blend_CrossFade); UpdatePlayingData(); //Profiler.EndSample(); //bone.isExposed //UpdateJoints(frame); } //Profiler.BeginSample("RootMotion"); /* * if (playingClip.rootMotionEnabled && rootMotionEnabled && frameIndex != rootMotionFrameIndex) * { * if (CullingMode != GPUSKinningCullingMode.CullCompletely) * { * rootMotionFrameIndex = frameIndex; * DoRootMotion(frame_crossFade, 1 - blend_crossFade, false); * DoRootMotion(frame, blend_crossFade, true); * } * }*/ //Profiler.EndSample(); //UpdateEvents(playingClip, frameIndex, frame_crossFade == null ? null : lastPlayedClip, frameIndex_crossFade); }