Beispiel #1
0
    /// <summary>
    /// 在GPUSkinningPlayerMono脚本的Init函数中调用,完成PlayerMono使用的Player实例创建
    /// </summary>
    /// <param name="attachToThisGo">PlayerMono->Object索引</param>
    /// <param name="res"> Player使用的资源 </param>
    public GPUSkinningPlayer(GameObject attachToThisGo, GPUSkinningPlayerResources res)
    {
        //fzy add:
        visible = true;

        go        = attachToThisGo;
        transform = go.transform;
        this.res  = res;

        mr = go.GetComponent <MeshRenderer>();
        if (mr == null)
        {
            mr = go.AddComponent <MeshRenderer>();
        }
        mf = go.GetComponent <MeshFilter>();
        if (mf == null)
        {
            mf = go.AddComponent <MeshFilter>();
        }

        //初始化时未播放动画,返回Material:RootOff_BlendOff
        GPUSkinningMaterial mtrl = GetCurrentMaterial();

        mr.sharedMaterial = mtrl == null ? null : mtrl.material;
        mf.sharedMesh     = res.mesh;

        //初始化MaterialPropertyBlock(为何不在脚本创建时完成初始化?)
        mpb = new MaterialPropertyBlock();

        ConstructJoints();
    }
    public GPUSkinningPlayer(GameObject attachToThisGo, GPUSkinningPlayerResources res)
    {
        go        = attachToThisGo;
        transform = go.transform;
        this.res  = res;

        mr = go.GetComponent <MeshRenderer>();
        if (mr == null)
        {
            mr = go.AddComponent <MeshRenderer>();
        }
        mf = go.GetComponent <MeshFilter>();
        if (mf == null)
        {
            mf = go.AddComponent <MeshFilter>();
        }

        GPUSkinningMaterial mtrl = GetCurrentMaterial();

        mr.sharedMaterial = mtrl == null ? null : mtrl.material;
        mf.sharedMesh     = res.mesh;

        mpb = new MaterialPropertyBlock();

        ConstructJoints();
    }
 public void InitMaterial(Material originalMaterial, HideFlags hideFlags)
 {
     if (mtrls != null)
     {
         return;
     }
     mtrls = new GPUSkinningMaterial[(int)MaterialState.Count];
     for (int i = 0; i < mtrls.Length; ++i)
     {
         if (Application.isPlaying)
         {
             mtrls[i] = new GPUSkinningMaterial()
             {
                 material = originalMaterial
             };
         }
         else
         {
             mtrls[i] = new GPUSkinningMaterial()
             {
                 material = new Material(originalMaterial)
             };
             mtrls[i].material.name             = keywords[i];
             mtrls[i].material.hideFlags        = hideFlags;
             mtrls[i].material.enableInstancing = true; // enable instancing in Unity 5.6
         }
         EnableKeywords(i, mtrls[i]);
     }
 }
Beispiel #4
0
    //根据初始Material设置GPUSkinningMaterial数组
    public void InitMaterial(Material originalMaterial, HideFlags hideFlags)
    {
        if (mtrls != null)
        {
            return;
        }

        Debug.Log("InitMaterial");

        //6种,与Keywords[]数组对应
        mtrls = new GPUSkinningMaterial[(int)MaterialState.Count];

        for (int i = 0; i < mtrls.Length; ++i)
        {
            mtrls[i] = new GPUSkinningMaterial()
            {
                material = new Material(originalMaterial)
            };
            mtrls[i].material.name      = keywords[i];
            mtrls[i].material.hideFlags = hideFlags;

            //fzy add optimize:从SetTexture移动到这,没必要每帧调用SetTexture
            mtrls[i].material.SetTexture(shaderPropID_GPUSkinning_TextureMatrix, texture);
            mtrls[i].material.SetVector(shaderPropID_GPUSkinning_TextureSize_NumPixelsPerFrame,
                                        new Vector4(anim.textureWidth, anim.textureHeight, anim.bones.Length * 3 /*treat 3 pixels as a float3x4*/, 0));
            // GPU Instancing 开关
#if UNITY_5_6
            mtrls[i].material.enableInstancing = true; // enable instancing in Unity 5.6
#endif
            EnableKeywords(i, mtrls[i]);
        }
    }
Beispiel #5
0
    /// <summary>
    /// GPUSkinningPlayer.Update的真正实现
    /// </summary>
    /// <param name="timeDelta"> 本帧(本次调用) </param>
    private void Update_Internal(float timeDelta)
    {
        //Profiler.BeginSample("GPUSkinningPlayer.Update_Internal()");
        if (!isPlaying || playingClip == null)
        {
            return;
        }

        //Profiler.BeginSample("GPUSkinningPlayer.GetCurrentMaterial");
        //根据当前动画播放状态(RootMotion、CullingUpdate),获取当前帧使用的Material
        GPUSkinningMaterial currMtrl = GetCurrentMaterial();

        if (currMtrl == null)
        {
            return;
        }
        //Profiler.EndSample();
        //Material应用到MeshRenderer组件
        if (mr.sharedMaterial != currMtrl.material)
        {
            mr.sharedMaterial = currMtrl.material;
        }

        //Profiler.BeginSample("GPUSkinningPlayer.UpdateMaterial()");
        if (playingClip.wrapMode == GPUSkinningWrapMode.Loop)
        {
            UpdateMaterial(timeDelta, currMtrl);
        }
        else if (playingClip.wrapMode == GPUSkinningWrapMode.Once)
        {
            if (time >= playingClip.length)
            {
                time = playingClip.length;
                UpdateMaterial(timeDelta, currMtrl);
            }
            else
            {
                UpdateMaterial(timeDelta, currMtrl);
                time += timeDelta;
                if (time > playingClip.length)
                {
                    time = playingClip.length;
                }
            }
        }
        else
        {
            throw new System.NotImplementedException();
        }
        //Profiler.EndSample();

        // 更新动画播放时间相关
        //crossFade已经经历的时间
        crossFadeProgress += timeDelta;
        lastPlayedTime    += timeDelta;
        //Profiler.EndSample();
    }
Beispiel #6
0
    /// <summary>
    /// fzy add/remark:
    /// 每帧调用次数与网格个数相关,已将该实现代码移至初始化时赋值(作者为何要每帧调用)
    /// </summary>
    public void SetTexture(GPUSkinningMaterial currMtrl)
    {
        //Profiler.BeginSample("Res.SetTexture");
        //currMtrl.material.SetTexture(shaderPropID_GPUSkinning_TextureMatrix, texture);

        // 设置当前动画片段帧对应的动画Texture信息

        //currMtrl.material.SetVector(shaderPropID_GPUSkinning_TextureSize_NumPixelsPerFrame,
        //    new Vector4(anim.textureWidth, anim.textureHeight, anim.bones.Length * 3/*treat 3 pixels as a float3x4*/, 0));
        //Profiler.EndSample();
    }
 /// <summary>
 /// 获取并赋值Material
 /// </summary>
 public void SetMaterial(GPUSkinningPlayerResources.MaterialState ms)
 {
     if (myRes == null)
     {
         Debug.LogWarning("myRes is null");
     }
     currMtrl = myRes.GetMaterial(ms);
     if (mr.sharedMaterial != currMtrl.material)
     {
         mr.sharedMaterial = currMtrl.material;
     }
 }
 private void EnableKeywords(int ki, GPUSkinningMaterial mtrl)
 {
     for (int i = 0; i < mtrls.Length; ++i)
     {
         if (i == ki)
         {
             mtrl.material.EnableKeyword(keywords[i]);
         }
         else
         {
             mtrl.material.DisableKeyword(keywords[i]);
         }
     }
 }
    private void UpdateMaterial(float deltaTime, GPUSkinningMaterial currMtrl)
    {
        int frameIndex = GetFrameIndex();

        if (lastPlayingClip == playingClip && lastPlayingFrameIndex == frameIndex)
        {
            res.Update(deltaTime, currMtrl);
            return;
        }
        lastPlayingClip       = playingClip;
        lastPlayingFrameIndex = frameIndex;

        float            blend_crossFade      = 1;
        int              frameIndex_crossFade = -1;
        GPUSkinningFrame frame_crossFade      = null;

        if (res.IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress))
        {
            frameIndex_crossFade = GetCrossFadeFrameIndex();
            frame_crossFade      = lastPlayedClip.frames[frameIndex_crossFade];
            blend_crossFade      = res.CrossFadeBlendFactor(crossFadeProgress, crossFadeTime);
        }

        GPUSkinningFrame frame = playingClip.frames[frameIndex];

        if (Visible ||
            CullingMode == GPUSKinningCullingMode.AlwaysAnimate)
        {
            res.Update(deltaTime, currMtrl);
            res.UpdatePlayingData(
                mpb, playingClip, frameIndex, frame, playingClip.rootMotionEnabled && rootMotionEnabled,
                lastPlayedClip, GetCrossFadeFrameIndex(), crossFadeTime, crossFadeProgress
                );
            mr.SetPropertyBlock(mpb);
            UpdateJoints(frame);
        }

        if (playingClip.rootMotionEnabled && rootMotionEnabled && frameIndex != rootMotionFrameIndex)
        {
            if (CullingMode != GPUSKinningCullingMode.CullCompletely)
            {
                rootMotionFrameIndex = frameIndex;
                DoRootMotion(frame_crossFade, 1 - blend_crossFade, false);
                DoRootMotion(frame, blend_crossFade, true);
            }
        }

        UpdateEvents(playingClip, frameIndex, frame_crossFade == null ? null : lastPlayedClip, frameIndex_crossFade);
    }
    private void Update_Internal(float timeDelta)
    {
        if (!isPlaying || playingClip == null)
        {
            return;
        }

        GPUSkinningMaterial currMtrl = GetCurrentMaterial();

        if (currMtrl == null)
        {
            return;
        }

        if (mr.sharedMaterial != currMtrl.material)
        {
            mr.sharedMaterial = currMtrl.material;
        }

        if (playingClip.wrapMode == GPUSkinningWrapMode.Loop)
        {
            UpdateMaterial(timeDelta, currMtrl);
        }
        else if (playingClip.wrapMode == GPUSkinningWrapMode.Once)
        {
            if (time >= playingClip.length)
            {
                time = playingClip.length;
                UpdateMaterial(timeDelta, currMtrl);
            }
            else
            {
                UpdateMaterial(timeDelta, currMtrl);
                time += timeDelta;
                if (time > playingClip.length)
                {
                    time = playingClip.length;
                }
            }
        }
        else
        {
            throw new System.NotImplementedException();
        }

        crossFadeProgress += timeDelta;
        lastPlayedTime    += timeDelta;
    }
    public void Update(float deltaTime, GPUSkinningMaterial mtrl)
    {
        if (executeOncePerFrame.CanBeExecute())
        {
            executeOncePerFrame.MarkAsExecuted();
            Time += deltaTime;
            UpdateCullingBounds();
        }

        if (mtrl.executeOncePerFrame.CanBeExecute())
        {
            mtrl.executeOncePerFrame.MarkAsExecuted();
            mtrl.material.SetTexture(shaderPropID_GPUSkinning_TextureMatrix, texture);
            mtrl.material.SetVector(shaderPropID_GPUSkinning_TextureSize_NumPixelsPerFrame,
                                    new Vector4(anim.textureWidth, anim.textureHeight, anim.bones.Length * 3 /*treat 3 pixels as a float3x4*/, 0));
        }
    }
Beispiel #12
0
    // fzy remark:CPU资源消耗过多
    public void Update(float deltaTime, GPUSkinningMaterial mtrl)
    {
        //Profiler.BeginSample("GPUSkinningPlayerResources.Update()_Internal");

        //Profiler.BeginSample("GPUSkinningPlayerResources.UpdateCullingBounds");

        //多个Player可能共享同一个Resources,保证每个Resources在同一帧内只执行一次
        if (executeOncePerFrame.CanBeExecute())
        {
            executeOncePerFrame.MarkAsExecuted();
            time += deltaTime;
            //fzy delete:注释以后不播放动画(猜测:未更新CullingBounds信息,默认判断模型动画出了Camera视锥区域)
            //更新CullingBounds信息(与LOD、Camera Culling相关)
            //UpdateCullingBounds();

            //fzy log
            //Debug.Log(cullingBounds.size);
            //if (cullingBounds.size != 0)
            //{
            //    for (int i = 0; i < cullingBounds.size; ++i)
            //    {
            //        Debug.Log(cullingBounds[i]);
            //    }
            //}
        }
        //Profiler.EndSample();

        //Profiler.BeginSample("GPUSkinningPlayerResources.executeOncePerFrame");

        //Material的更新可能在一帧内调用多次?
        if (mtrl.executeOncePerFrame.CanBeExecute())
        {
            mtrl.executeOncePerFrame.MarkAsExecuted();
            // texture在PlayerMono或PlayerMonoManager中赋值,该帧对应的Material属性是新创建的,未赋值?
            // 初始化时赋值
            // mtrl.material.SetTexture(shaderPropID_GPUSkinning_TextureMatrix, texture);
            // 设置当前动画片段帧对应的动画Texture信息
            //mtrl.material.SetVector(shaderPropID_GPUSkinning_TextureSize_NumPixelsPerFrame,
            //    new Vector4(anim.textureWidth, anim.textureHeight, anim.bones.Length * 3/*treat 3 pixels as a float3x4*/, 0));
        }
        //Profiler.EndSample();

        //Profiler.EndSample();
    }
Beispiel #13
0
    /// <summary>
    /// 根据当前动画片段播放状态设置Material
    /// fzy remak:CPU资源消耗过多
    /// </summary>
    /// <param name="deltaTime">本帧Update消耗的时间</param>
    /// <param name="currMtrl">当前使用的Material</param>
    private void UpdateMaterial(float deltaTime, GPUSkinningMaterial currMtrl)
    {
        int frameIndex = GetFrameIndex();

        //Profiler.BeginSample("PlayerResources.Update");
        //动画片段(WrapMode.Once)播放完毕
        if (lastPlayingClip == playingClip && lastPlayingFrameIndex == frameIndex)
        {
            res.Update(deltaTime, currMtrl);
            return;
        }
        //Profiler.EndSample();
        //记录上一帧播放的动画片段
        lastPlayingClip = playingClip;
        //记录上一次播放的动画片段帧数(有可能跳帧)
        lastPlayingFrameIndex = frameIndex;

        float blend_crossFade      = 1;
        int   frameIndex_crossFade = -1;
        // 新建动画帧,用于crossFade
        GPUSkinningFrame frame_crossFade = null;

        //Profiler.BeginSample("PlayerResources.CrossFadeBlending");
        if (res.IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress))
        {
            frameIndex_crossFade = GetCrossFadeFrameIndex();
            frame_crossFade      = lastPlayedClip.frames[frameIndex_crossFade];
            blend_crossFade      = res.CrossFadeBlendFactor(crossFadeProgress, crossFadeTime);
        }
        //Profiler.EndSample();

        //Profiler.BeginSample("PlayerResources.Update");
        GPUSkinningFrame frame = playingClip.frames[frameIndex];

        //模型可以被看见(Culling)或者CullingMode为AlwaysAnimate
        if (Visible ||
            CullingMode == GPUSKinningCullingMode.AlwaysAnimate)
        {
            res.Update(deltaTime, currMtrl);
            res.UpdatePlayingData(
                mpb, playingClip, frameIndex, frame, playingClip.rootMotionEnabled && rootMotionEnabled,
                lastPlayedClip, GetCrossFadeFrameIndex(), crossFadeTime, crossFadeProgress
                );
            mr.SetPropertyBlock(mpb);
            //bone.isExposed
            UpdateJoints(frame);
        }
        //Profiler.EndSample();

        //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);
    }