Unity3D 5.0+模型合并&灯光烘焙降低Draw Calls方案

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity3D 5.0+模型合并&灯光烘焙降低Draw Calls方案相关的知识,希望对你有一定的参考价值。

参考技术A 模型+灯光测试结果:
执行之前使用的Draw Calls和内存

执行之后使用的Draw Calls和内存

​模型合并规则:
1、非同样的静态模型才需要合并 同样模型(复制的)不用合并
2、UV无重复的模型可用Mesh Baker合并 重复的Mesh Baker会出错 有需要可以在制作软件里合并
3、使用同样材质模型可以合并 使用不同材质的模型不能合并
4、合并模型贴图大小必须为2的N次幂 需选择合适大小以免浪费空间或效果不理想 不要通过贴图设置另外更改大小

灯光烘焙优化场景效果和资源方法:
1、所有相同物体使用相同材质并使用一个Scale
2、所有能合并的同样节点的模型或者共用材质的模型一律合并
3、所有重复使用的模型 顶点上限为900除以贴图张数
4、Occlusion Bake需要根据模型大小来自定义尺寸以免效果不好或浪费时间
5、烘焙时候把环境灯光关闭 把烘焙灯光打开确认范围 根据需要开启或关闭全局照明(GI)如关闭GI则只烘焙AO 把阴影和烘焙灯光做成Lighting Data(多物体多灯光情况下 烘焙AO速度比烘焙GI快N倍)
6、打开环境灯光(如在移动设备上运行只能使用一盏主光)隐藏或者删除烘焙灯光如没有动态模型需要实时计算光影的话最好关闭shadow

其他注意:
1、移动设备上尽量少使用景深、反射、雾效等功能严重影响运行速度
2、移动设备上尽量少使用自定义shader 容易出现未知错误
3、移动设备上使用Light Probe、 Reflection Probe无效

具体操作步骤:
建模步骤:
1、顶点数尽量少 使用贴图来表现物体细节(Color、AO、Normal等)

2、整个场景所有模型的UV单元格大小基本一致
3、节点数量一样的模型(复制的)使用同一个材质
4、一个组合的模型(如整个机械)使用多张贴图需把所有贴图合并到一张上

5、无动画的共用材质的模型合并为一个模型(如机械上的两个或多个部件)
6、没有动画或者不会交互但是会重复利用的模型尽量合并合并后总顶点数不超过900除以贴图数(1张贴图900顶点上限 2张450 3张300 以此类推) 顶点数超出则拆分模型

u3d Mesh Baker步骤:
1、菜单栏>Game Object>Create Other>Mesh Baker>Multi-Mesh andMaterial Baker

2、Hierarchy中选择创建的Mesh Baker在Inspector中选择MB3_Texture Baker脚本使用Open Tools For Adding Objects添加需要合并贴图的object

3、弹出窗口选择目标模型 可使用静态或者激活选项来筛选 选择完毕后更改Using Lightmap Index为不过滤 使用Add SelectedMeshes命令添加到列表中

​4、检查添加模型无误后 使用CreateEmpty Assets For Combined Material创建一个合并贴图使用的新材质 指定路径 然后执行Bake Materials Into Combined Material

​5、选择MB3_Multi Mesh Baker脚本 使用Bake生成新的合成Mesh]

​6、原Mesh隐藏或删除(删除节省资源,但一定要确定该模型不会再被使用)

u3d烘焙步骤:
1、导入模型后做成Scale为1的预制体 被调用时尽量不要更改Scale

2、不需要动态载入资源的静态物体尽量不要用脚本载入
3、布置好场景后打开Occlusion 根据需要bake的场景空间大小和模型细节程度选择适当的bake尺寸

4、bake完后 打开Lighting 设置scene中关闭Skybox、Sun(设为None)

4.1、如使用Light Probe、 Reflection Probe 打开Precomputed Realtime GI 关闭Baked GI

4.2、如不使用Light Probe、 Reflection Probe 需要烘焙阴影则关闭Precomputed Realtime GI 打开 Baked GI 设定合适的 Baked Resolution、 Baked Padding(Unity3d 5.4.0.b18 勾选Ambient Occlusion)

5、如Auto Build选项被打开则需关闭(节省时间) 并点击Build下拉菜单执行Clear Baked Data

6、根据需求创建灯光(尽量减少Realtime灯光数量和shadow数量以及点光源数量以节省系统资源)
7、在Lighting 设置Object里筛选Renderers 设置静态物体合适的Scale inLightmap大小(地形为1或者更大 大建筑障碍物0.5-1树木石头等小障碍物0.1-0.5)

8、在Lighting 设置Object里筛选Lights把所有Realtime光源隐藏 所有Bake光源打开执行Build 等候执行读条完成 期间勿对场景进行操作
9、Build完成后 把所有Realtime光源打开 所有Bake光源隐藏或删除(删除节省资源,但一定要确定该光源不会再被使用)
10、主光源打开shadow其余光源按情况决定是否打开shadow 按需求决定是否开启Skybox和Sun

js window.opener 子页面 父页面 传值

JSP 中 A 页面打开B, A,B中有两个table,形式一样,怎么把子页面B中的table内容传给父页面A?
最好不要在父页面A中操作。B页面用 $("#List").append("xxx")添加到了页面中。

1、建立父级页面,首先建立一个父级页面parent.html,代码如图,一个pop函数方法,一个链接到child.html的iframe标签;

2、建立子页面,再新建一个child.html页面,如图,展示一个id=link的div标签,和link的点击事件,因为是调用父级方法,所以需要用到window.parent.pop()方法。

3、预览页面,预览页面,可明显看到parent.html里面的iframe框架,指向的就是child子页面

4、错误提示,点击页面中“调用父级pop方法”的文字链,会提示错误,这是因为没配置好域名等相关设置。

5、站点配置,打开iis,右键iframe文件夹——“管理文件夹”——“浏览”;即可打开本地测试地址;(如小伙伴没配置iis,需要先配置iis建立站点)

6、成功调用父级方法,再次点击“调用父级pop方法”的文字链,即可成功弹出提示。

参考技术A

1、新建一个子页面,页面演示代码如图所示,定义了一个testChild方法,放置一个按钮,用来触发调用父页面定义的js方法。

2、再建一个父页面,页面演示代码如图所示,定义了一个testParent方法,也放置一个按钮,用来触发调用子页面定义的js方法,父页面还需要使用<iframe name="myFrame" src="child.html"></iframe>引入子页面。

3、打开浏览器访问父页面,页面打开效果如图所示,父页面里面嵌套了一个子页面,父子页面都有一个按钮。

4、在父页面中,点击调用子页面中的函数按钮,显示“我是子页面”,这个信息是子页面方法里的,说明父页面已经成功调用了子页面定义的js方法。

5、在子页面中,点击调用子页面中的函数按钮,显示“我是父页面”,这个信息是父页面方法里的,说明子页面已经成功调用了父页面定义的js方法

6、从上面的例子代码和测试的效果,可以总结。

参考技术B

  子页面要向父页面传值,只要在document前面加window.opener即可

  window.opener 的用法

  window.opener 返回的是创建当前窗口的那个父窗口的引用,比如点击了a.htm上的一个链接而打开了b.htm,然后我们打算在b.htm上输入一个值然后赋予a.htm上的一个id为“name”的textbox中,就可以写为:indow.opener.document.getElementById("name").value = "输入的数据";

  1.页面代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档title>
head>
<script language="javascript">
function tanchu()

    window.open("Untitled-5.html");   

script>
<body>
    <form id="form1" name="form1" method="post" action="">
        <label> <input type="submit" name="button" id="button" value="提交"
            onclick="tanchu()" />
        label> <label> <input type="text" name="textfield" id="textfield" />
        label>
    form>
</body>
</html>

  2.子页面代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档title>
head>
<script language="javascript">
function aaa()

    window.opener.document.getElementByIdx('textfield').value='123123123';

script>
<body>
    <form id="form1" name="form1" method="post" action="">
        <label> <input type="submit" name="button" id="button" value="提交"
            onclick="aaa()" />
        label>
    form>
</body>
</html>

参考技术C 举个例子:
在B页面中 window.opener.document.getElementById("A页面的id").innerHTML="<table>html</table>";

具体自己写吧本回答被提问者和网友采纳
参考技术D 在你子页面中., window.parent.document.getElementById("##");这样你可以得到指定的父层对象,拿到对象之后后面怎么处理应该会了吧

以上是关于Unity3D 5.0+模型合并&灯光烘焙降低Draw Calls方案的主要内容,如果未能解决你的问题,请参考以下文章

unity如何更改烘焙灯光阴影的颜色

unity3d 怎么做场景烘培

Unity3D纯白(Pure White)烘焙【2021】

Unity灯光烘焙

Unity3d_Light Probe使用方法

unity3d 为什么要烘焙?烘焙作用是为了什么?