lightmap的渐变过渡,我使用的方法是自己写的

lightmap的渐变过渡,我使用的方法是自己写的

1、需要的东西:场景烘焙光照贴图、天空盒。

2、需要多少时间点,多少组光照贴图unity 天空盒动态变化,需要烘焙多少组天空盒。在我的示例中,一天中的时间分为早上、中午、晚上和晚上2d游戏素材,因此需要 4 组光照贴图和 4 个天空盒。

3、 即时切换很简单音乐,只需将想要的光照贴图数组分配给LightmapSettings.lightmaps,将想要的天空盒着色器分配给RenderSettings.skybox即可。

4、渐变转场开关不能直接赋值给设置,因为只有一个赋值位,无法实现转场效果。

5、lightmap的渐变过渡,我使用的方法是写shader实现lightmap叠加,获取当前MeshRenderer的Lightmap坐标,计算lightmap的uv:

o.uvLM = v.uv2.xyunity_LightmapST.xy + unity_LightmapST.zw;

然后通过当前MeshRenderer的lightmapIndex找到对应的Lightmap纹理,并赋值给shader。

最后,在正常颜色之上叠加一个光照贴图颜色:

fixed4 col = tex2D(_MainTex, i.uv);

fixed3 lm1 = DecodeLightmap(tex2D(_LightMap1,i.uvLM));

col.rgb=lm1;

做完之后,我们就可以自己控制Lightmap的显示了。由于它可以支持一个光照贴图,它也可以支持2个堆叠。然后在中间加一个插值让它变化,很简单。

6、天空盒的渐变过渡其实也差不多。虽然RenderSettings.skybox只能设置一个shader,但既然他是shader,我们可以想办法。

Unity自带的天空盒的shader,我们平时用的最多的是6 Sided和Cubemap。为了代码操作中赋值的方便,我觉得还是用Cubemap比较好。毕竟只需要设置一次,6Sided需要设置6张图片。

所以我们可以用内置的Skybox/Cubemap做一个小修改,多添加一个Cubemap贴图赋值,然后再添加一个插值变化值,然后将我们的shader赋值给RenderSettings.skybox来控制Cubemap的替换并且插值可以做过滤效果。

7、下一个考虑因素是性能。更换天空盒并没有消耗太多性能,但我还是做了两个shader,一个只支持一个天空球,一个支持两个天空球之间的切换。需要渐变过渡的时候,换成支持二的,做动画效果。过渡完成后,改回只支持一个的,避免GPU对第二个天空盒的采样进行不必要的计算。

8、Lightmap性能问题,我也做了两个shader,一个支持单个lightmap,另一个支持两个lightmap之间的切换。在没有渐变切换,且只支持一张光照贴图的情况下,此时的渲染压力理论上和光照贴图正常烘焙的时候是一样的。当需要渐变时,更换shader,这一步可能会有一定的消耗。这取决于场景中有多少物体需要像这样操作。

我视频中的场景是我在线运行的实际游戏的场景。人脸近30万,物体近1000个unity 天空盒动态变化,数量应该比较大。但是从性能分析的角度来看,也就是刚切换shader的时候读取shader参数的时候会稍微超过20毫秒,其他时候是