1)对于 Camera.activeTexture 和 Camera.targetTexture 的疑难
2)如何升高动画文件的浮点数精度
3)应用 EasyMovieTexture 在 Android 播放视频失败
4)模型顶点色(Color)如何去除
5)多层 3D 场景寻路计划探讨
这是第 227 篇 UWA 技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫 10 分钟,认真读完必有播种。
UWA 问答社区:answer.uwa4d.com
UWA QQ 群 2:793972859(原群已满员)
Rendering
Q:始终有个纳闷,Camera.activeTexture 和 Camera.targetTexture 在 Get 的时候,Get 到的是一个 RenderTexture 吗?
我晓得这两个的区别是一个只能取得以后所正在渲染的 RenderTexture,一个是既能够取得也能够设置渲染指标,但这样 activeTexture 有什么必要性呢?
是我对这两个的了解有谬误吗?还有大家平时说的 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。
对于 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.cxxClearUVClr.exe
感激 Lim@UWA 问答社区提供了答复
Script
Q:目前面临一个寻路计划的需要,冀望有相干教训的敌人探讨一下各种实现计划的优劣和可行性,宽阔下思路。
需要形象之后大抵如下:
1. 3D 多层场景,然而场景不会很大,几百米乘以几百米以内吧;
2. 场景分层,高度上可能有多层重叠,层之间有高空阻挡,挖空的中央有各种穿梭形式;
3. 场景内有箱子、小巷之类的阻挡与路线;
4. 玩家可能会有相似轻功的航行挪动形式。
3D 方面可选的计划不多,比方 Navmesh、体素化、纯物理,目前比拟偏向于体素化的计划,纯物理的目前测试下来感觉性能耗费有点不能承受。当然需要方面也有一些能够取舍的,想看看各位有教训的敌人有什么好的想法和倡议。
A:最近看到一些 3D 寻路的解决方案想到这个问题,挂靠一下:
- SVON:基于八叉树场景划分 + A 星寻路的算法实现,有开源库(Native 源码 +Unity 工程)见链接。
- Mercuna 3D Navigation:看官网介绍相似 SVON,对 A 星算法进行了优化,有 UE 和 Unity 的插件,但没找到相干插件下载,须要分割官网。
感激羽飞 @UWA 问答社区提供了答复
封面图来源于网络
明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。
官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:793972859(原群已满员)