关于Camera.activeTexture和Camera.targetTexture的疑问

1)关于Camera.activeTexture和Camera.targetTexture的疑问
​2)如何下降动画文件的浮点数精度
3)使用EasyMovieTexture在Android播放视频失败
4)模型顶点色(Color)如何去除
5)多层3D场景寻路方案探讨java


UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)android

Rendering

Q:一直有个疑惑,Camera.activeTexture和Camera.targetTexture在Get的时候,Get到的是一个RenderTexture吗?git

我知道这两个的区别是一个只能得到当前所正在渲染的RenderTexture,一个是既能够得到也能够设置渲染目标,但这样activeTexture有什么必要性呢?github

是我对这两个的理解有错误吗?还有你们平时说的Backbuffer,在我渲染目标一直是屏幕的时候,这两个方法得到的都是Backbuffer吗?算法

A:第一个问题:Camera.targetTexture必须在相机指定Render Target才会非null,Camera.activeTexture获取到的值和调用的时机有关系。官方文档中写着能够在OnPostRender中获取到,好比使用了后处理,在OnPostRender中能够获取到后处理申请的RenderTexture,在Update中获取就是null。若是给相机设置了RenderTexture,那么targetTexture就是设置的RenderTexture。若是没有开启HDR,在OnPostRender中activeTexture获取到的也是这个RenderTexture。若是开启了HDR,则是一个另外申请的RenderTexture。网络

第二个问题:推荐使用RenderDoc查看渲染状态,分为两种状况,在安卓平台上开启了Always Blit和没开启会不同。开启了Always Blit,会在最后多一个Present的过程,在Present以前,会将全部的渲染渲染到一个叫tex的RenderTexture上(这里不考虑后处理以及HDR致使生成了额外的RenderTexture),在Present的时候将tex Copy到Backbuffer里面。若是没有开启AlwaysBlit,好比Blit Type是Never,那么全部的渲染都是直接渲染到Backbuffer的(这里一样不考虑RenderTexture的状况),Blit Type为Auto的时候没有遇到出现Present的状况,在线性空间也没出现Present 。Backbuffer和那个用来Present的tex这两个对象均可以理解为系统提供的,从C#脚本中是无法获取到的,并且从Profiler里面也是看不到这两个对象的大小的。编辑器

总结起来就是:大部分状况下Camera.targetTexture都是为null的,除非相机设置了RenderTarget。ide

对于Camera.activeTexture,这个须要看调用时机,在OnPostRender中调用,若是有使用后处理或者HDR,则能够获取到申请到的RenderTexture,在Update里面获取是null的,其余的函数阶段没有详细测试过。函数

对于Backbuffer,这个系统是提供的,C#脚本是获取不到的。并且不必定是直接绘制到Backbuffer,就算没有使用后处理或者HDR,若是开启了Always Blit,也是会多一个中间层,在最后阶段中间层会Copy到Backbuffer。工具

感谢Xuan@UWA问答社区提供了回答


Animation

Q:动画文件后处理能够作两件事,精度压缩,Scale曲线剔除。比起用工具修改原始FBX文件,这样比较灵活。

实际测试,在开启Optimal压缩的状况下,加上这个后处理,能再节省40%左右。

示例代码和测试结果见知乎专栏:
https://zhuanlan.zhihu.com/p/27378492

void OnPostprocessModel(GameObject g) 
{
    // for skeleton animations.

        List<AnimationClip> animationClipList = new List<AnimationClip>(AnimationUtility.GetAnimationClips(g));
        if (animationClipList.Count == 0) {
            AnimationClip[] objectList = UnityEngine.Object.FindObjectsOfType (typeof(AnimationClip)) as AnimationClip[];
            animationClipList.AddRange(objectList);
        }

        foreach (AnimationClip theAnimation in animationClipList)
        {

            try 
            {
                //去除scale曲线
                foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(theAnimation))
                {
                    string name = theCurveBinding.propertyName.ToLower();
                    if (name.Contains("scale"))
                    {
                        AnimationUtility.SetEditorCurve(theAnimation, theCurveBinding, null);
                    }
                } 

                //浮点数精度压缩到f3
                AnimationClipCurveData[] curves = null;
                curves = AnimationUtility.GetAllCurves(theAnimation);
                Keyframe key;
                Keyframe[] keyFrames;
                for (int ii = 0; ii < curves.Length; ++ii)
                {
                    AnimationClipCurveData curveDate = curves[ii];
                    if (curveDate.curve == null || curveDate.curve.keys == null)
                    {
                        //Debug.LogWarning(string.Format("AnimationClipCurveData {0} don't have curve; Animation name {1} ", curveDate, animationPath));
                        continue;
                    }
                    keyFrames = curveDate.curve.keys;
                    for (int i = 0; i < keyFrames.Length; i++)
                    {
                        key = keyFrames[i];
                        key.value = float.Parse(key.value.ToString("f3"));
                        key.inTangent = float.Parse(key.inTangent.ToString("f3"));
                        key.outTangent = float.Parse(key.outTangent.ToString("f3"));
                        keyFrames[i] = key;
                    }
                    curveDate.curve.keys = keyFrames;
                    theAnimation.SetCurve(curveDate.path, curveDate.type, curveDate.propertyName, curveDate.curve);
                }
            }
            catch (System.Exception e)
            {
                Debug.LogError(string.Format("CompressAnimationClip Failed !!! animationPath : {0} error: {1}", assetPath, e));
            }
        }

}

A1:压的是文本文件的大小,只是编辑器下更快,不论怎么处理,内存仍是一个Float。

感谢海的味道@UWA问答社区提供了回答

A2:Mecanim的动画系统的压缩确实不是靠改变Float类型来达到的,而是经过下降数值位数后,能够产生更多的Const曲线,从而让引擎达到更高效存储的效果,进而达到所谓的“压缩”结果。

该问答由UWA提供

A3:裁剪精度产生更多Const Curve,达到缩小体积的目的,这个能够理解。但除非动画曲线是动捕出来的,有大量抖动的细节,不然这样下降的内存颇有限。并且统一暴力降精度在不少时候并不可取。

Unity官方的减帧算法是一套参数针对全部骨骼的,比较低效。推荐细化处理:针对不一样关节,设置不一样的偏差阈值,手动作Linear Key Reduction。越靠近根骨骼,所需精度越高,容许的偏差阈值越小。越靠近末端骨骼,偏差阈值越大。对Position和Rotation Curve,使用不一样的偏差度量方式,面部、手指等关键骨骼再加额外配置。

这样能够有效大幅减少Clip内存和包体大小,尤为对于动捕产生的动画。脚本处理方法仅适用于.anim文件,且因为会产生额外的EditorCurve,在处理完后资产大小可能会不减反增。但最终EditorCurve会合并入Curve,AssetBundle和运行时内存是会减少的。

CompressAnimationClips.cs

感谢zhangji@UWA问答社区提供了回答


Video

Q:使用EasyMovieTexture在Android播放视频失败,报错信息以下:

AndroidJavaException: java.lang.IllegalStateException: Unable to update texture contents (see logcat for details)
java.lang.IllegalStateException: Unable to update texture contents (see logcat for details)
android.graphics.SurfaceTexture.nativeUpdateTexImage(Native Method)
android.graphics.SurfaceTexture.updateTexImage(SurfaceTexture.java:248)
com.EasyMovieTexture.EasyMovieTexture.UpdateVideoTexture(EasyMovieTexture.java:331)
com.unity3d.player.UnityPlayer.nativeRender(Native Method)
com.unity3d.player.UnityPlayer.access600(Unknown Source:0)
com.unity3d.player.UnityPlayer600(UnknownSource:0)com.unity3d.player.UnityPlayerf1.handleMessage(Unknown Source:150) android.os.Handler.dispatchMessage(Handler.java:106) android.os.Looper.loop(Looper.java:219)
com.unity3d.player.UnityPlayer1.handleMessage(UnknownSource:150)android.os.Handler.dispatchMessage(Handler.java:106)android.os.Looper.loop(Looper.java:219)com.unity3d.player.UnityPlayerf.run(Unknown Source:20)
UnityEngine.AndroidJNISafe.CheckException () (at <3c22a197ab60454cb70124c69f2248be>:0)
UnityEngine.AndroidJNISafe.CallVoidMethod (System.IntPtr obj, System.IntPtr methodID, UnityEngine.jvalue[] args) (at <3c22a197ab60454cb70124c69f2248be>:0)
UnityEngine.AndroidJavaObject._Call (System.String methodName, System.Object[] args) (at <3c22a197ab60454cb70124c69f2248be>:0)
UnityEngine.AndroidJavaObject.Call (System.String methodName, System.Object[] args) (at <3c22a197ab60454cb70124c69f2248be>:0)
MediaPlayerCtrl.Call_UpdateVideoTexture () (at :0)
MediaPlayerCtrl.Update () (at :0)

A1:视频播放建议使用AssetStore中的AVProVideo,功能更强且兼容性更好一些。

感谢范君@UWA问答社区提供了回答

A2:建议使用自带的视频播放,兼容性更好。

感谢Robot.Huang@UWA问答社区提供了回答

A3:我以前遇到过一个EasyMovieTexture的问题,并且只出如今某个小米手机上,咱们最后把视频格式改成mp4,码率我记得也改的跟EasyMovieTexture示例的视频同样而后就行了。

ps:你能够先用示例的视频测试一下,若是一样播放不了,那就是其余缘由了。

感谢lanyt@UWA问答社区提供了回答

A4:直接用官方本身的VideoPlayer,以下图:

感谢小辉辉-177865@UWA问答社区提供了回答


Mesh

Q:在UWA中的模型分析页面中有关于模型顶点色的信息,得知若是不须要此数据,最好在Max中不要导出此属性,那么若是清除此属性呢?

我尝试过新建一个新的模型,这时此模型是不带顶点色属性的,一旦修改顶点色后就没法再清除此属性了,求解。

A1:感谢kent的回答,可是他提供的Demo内的exe我这里打开会报错,本身尝试从FBXSDK导出了一个exe。

FbxSDK官网下载,根据VS的使用版原本下载就能够,不影响下面的教程。

FbxSDK与VisualStudio环境搭建

这个教程会教你打开一个Samples,随便打开一个Sample,而后把Kent提供的main.cxx内容替换到同名文件内,编译出exe就好。

这里提供一个本身编译的,须要配合Kent提供的Demo使用:

ClearUVClr.exe

感谢高松@UWA问答社区提供了回答

A2:我在使用的时候发现有的Fbx文件替换无效,经查是main文件中

只获取了第一个节点,因此我改为遍历获取

这里提供main文件和exe文件:
main.cxx

ClearUVClr.exe

感谢Lim@UWA问答社区提供了回答


Script

Q:目前面临一个寻路方案的需求,指望有相关经验的朋友探讨一下各类实现方案的优劣和可行性,开阔下思路。

需求抽象以后大体以下:
1. 3D多层场景,可是场景不会很大,几百米乘以几百米之内吧;
2. 场景分层,高度上可能有多层重叠,层之间有地面阻挡,挖空的地方有各类穿梭方式;
3. 场景内有箱子、小巷之类的阻挡与道路;
4. 玩家可能会有相似轻功的飞行移动方式。

3D方面可选的方案很少,好比Navmesh、体素化、纯物理,目前比较倾向于体素化的方案,纯物理的目前测试下来感受性能消耗有点不能接受。固然需求方面也有一些能够取舍的,想看看各位有经验的朋友有什么好的想法和建议。

A:最近看到一些3D寻路的解决方案想到这个问题,挂靠一下:

  1. SVON:基于八叉树场景划分+A星寻路的算法实现,有开源库(Native源码+Unity工程)见连接。

  2. Mercuna 3D Navigation:看官方介绍相似SVON,对A星算法进行了优化,有UE和Unity的插件,但没找到相关插件下载,须要联系官方。

感谢羽飞@UWA问答社区提供了回答

封面图来源于网络


今天的分享就到这里。固然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,咱们早已在UWA问答网站上准备了更多的技术话题等你一块儿来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com 官方技术QQ群:793972859(原群已满员)

相关文章
相关标签/搜索