https://xians.me Wed, 09 Sep 2020 09:19:53 +0000 zh-CN hourly 1 https://wordpress.org/?v=5.5.3 https://xians.me/img/avatar/avatar3_64x64.webp https://xians.me 32 32 Wordfence 安全插件专业版 https://xians.me/218 https://xians.me/218#respond Sat, 05 Sep 2020 06:03:44 +0000 https://xians.me/?p=218 逛博客时在WordPress 插件:Wordfence 安全插件专业版 _ 唯心寒辞发现看到这样一个破解 Wordfence 专业版的方法,试了一下,可用。

Wordfence 安全插件专业版插图

我使用的是7.3.*,修改后授权码时间会变成 18511 天

Wordfence 安全插件专业版插图1

教程

  1. 在插件中安装好Wordfence
  2. FTP连接你的服务器 ,并找到以下路径:wp-content/plugins/wordfence/lib
  3. 打开 wordfenceClass.php 文件
  4. 搜索if (!WFWAF_SUBDIRECTORY_INSTALL && $waf = wfWAF::getInstance()) {找到 $siteurl = wfUtils::wpSiteURL();这一行代码
  5. 在找到的代码下添加
wfConfig::set('isPaid', 1);
wfConfig::set('keyType', wfAPI::KEY_TYPE_PAID_CURRENT);
!!wfConfig::set('isPaid', 1);
!!wfConfig::set('keyType', wfAPI::KEY_TYPE_PAID_CURRENT);
  1. 修改后的的完整代码为
if (!WFWAF_SUBDIRECTORY_INSTALL && $waf = wfWAF::getInstance()) {
    $homeurl = wfUtils::wpHomeURL();
    $siteurl = wfUtils::wpSiteURL();

    wfConfig::set('isPaid', 1);
    wfConfig::set('keyType', wfAPI::KEY_TYPE_PAID_CURRENT);

    !!wfConfig::set('isPaid', 1);
    !!wfConfig::set('keyType', wfAPI::KEY_TYPE_PAID_CURRENT);
  1. 保存然后上传覆盖源文件,进入插件的仪表盘就 OK 了。
]]>
https://xians.me/218/feed/ 0
如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记 https://xians.me/105 https://xians.me/105#respond Fri, 05 Jun 2020 02:00:45 +0000 https://xians.me/?p=105

最近在虚幻中输出序列帧想与传统三维渲染输出带Alpha通道,在这记录下实现方式。

实现方法

虚幻设置

打开porject settings窗口在Rendering中找到Enable alpha channel support in post processing(experimental)Disabled改为Allow through tonemapper,修改后引擎提示重启。

如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图

重启与一段时间重新编译后,我们点击需要隐藏的模型,Details窗口上把Render下的Actor Hidden In Game勾上

如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图1

打开Sequencer窗口,点击Render图标打开Render Movie Setting,将Image Output Fprmat改为exr为输出文件,点击Capture Movie进行输出。

如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图2

如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图3

AE设置

打开AE,导入刚才输出序列帧,从下图看到导入的序列帧样子

如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图4

选择导入的序列帧右键Interpret Footage→Main(快捷键为Ctrl+Alt+G),Alpha设为Straight-Unmatted,勾选Invevt Alpha,点击Color Management选项卡勾选Preserve RGB点击OK,完成!

如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图5

下图为最终的样子
如何在虚幻Sequencer中输出带Alpha通道序列帧学习笔记插图6

]]>
https://xians.me/105/feed/ 0
[转载]Unity《Boat Attack》Demo幕后揭秘 https://xians.me/103 https://xians.me/103#respond Fri, 13 Mar 2020 07:48:39 +0000 https://xians.me/?p=103

作者:Andre McGrail,2020年2月10日

本文中,我们一起来看看使用通用渲染管线制作《Boat Attack》Demo的过程 。

通用渲染管线是一款强大的,包含一系列艺术创作工具的产品级图像制作解决方案。若希望制作出具有顶尖质量的图像,将项目发布到所有Unity支持平台上,通用渲染管线是一个不错的选择。我们在本博文中已经介绍过通用渲染管线的优势了。
我们最初制作《Boat Attack》演示项目是为了验证和测试通用渲染管线的性能(当时还叫轻量渲染管线)。在开发时制作的这个垂直切片式演示,也是一次生产流程实地操作的练习。

自第一版本的Demo发布以来,我们多次升级了《Boat Attack》演示项目。如今,项目中使用了许多新出的通用渲染管线图像功能,其中包括C# Job SystemBurst compilerShader GraphInput System等等。

《Boat Attack》Demo 介绍

《Boat Attack》演示项目展示了一款用Unity制作的赛艇游戏。游戏现可供游玩,并且还在不断优化,我们尽量让游戏能完全利用起最新的Unity功能。

Demo能够在大部分平台中顺畅运行,包括中高端移动设备,现世代主机和单独的游戏平台App。在2019年的哥本哈根Unite大会上,我们使用了一系列的设备来演示《Boat Attack》,包括iPhone 7、PlayStation 4等等。

您可从GitHub上下载该Demo,并在最新版本Unity 2019.3中运行。

Shader Graph

Shader Graph是一款对艺术家十分友好的着色器创作界面,在技术美术的手中,它是一个强大的原型构建工具。在《Boat Attack》中,我们使用了Shader Graph制作出了一些独特的着色器效果。

Shader Graph可以制作出超棒的着色器效果,还能方便开发者在各版本的轻量渲染管线和通用渲染管线中维护所有的着色器。

《Boat Attack》中展示的峭壁上的着色器通过采集网格元数据制作,Shader Graph可以轻易从网格中提取出各类数据。在峭壁较为平坦的位置、以及朝上的平面上,我们在网格的法线方向上绘制了杂草,同时限定了绘制时的场景空间高度,确保杂草不会被绘制到靠近水面的峭壁和岩块上。

自左向右:Y轴高度遮罩、Y轴法线遮罩、高度和法线遮罩重新映射后的效果、最终的着色器

自左向右:Y轴高度遮罩、Y轴法线遮罩、高度和法线遮罩重新映射后的效果、最终的着色器

植被着色

《Boat Attack》中的植被最初是使用特制的顶点/片元着色器(Vertex/Fragment shader)制作,但由于管线当时处于早期开发阶段,代码时常会更改,维护植被着色器让人非常头疼。在用Shader Graph重新制作着色器后,更新就变得轻松多了。

植被的Shader Graph效果是基于Crytek的Tiago Sousa介绍的技术制作的,该技术很好地利用了顶点色彩的通道,用顶点错位来形成植被的风吹动画。在《Boat Attack》里,我们创建了一个次级图表来囊括进所有风吹动画运算所需的节点。在次级图表中包含了许多嵌套的次级图表,都是用于执行重复性数学运算的图表。

单个通道上的顶点动画和遮罩。自左向右:自远到近的主要混合模式,顶点色彩红色通道上的叶片边缘,顶点色彩蓝色通道和绿色通道一起组成植被的相位偏移。
在制作逼真植被时,另一个重要的部分是次表面散射(subsurfaceScattering,SSS),遗憾的是通用渲染管线当前并不支持SSS。然而,我们可以使用Shader Graph的自定义功能节点从通用渲染管线中取得光照信息,制作出一种近似SSS的效果。

[转载]Unity《Boat Attack》Demo幕后揭秘插图1

以上是节点布局。SSS Mask部分使用了顶点颜色绿色通道(叶相)和反射率(Albedo)纹理贴图制作。

自定义功能节点可让我们有更多的创作自由。在《Unity通用渲染管线Universal RenderPipeline》中详细了解如何自定义渲染,或者直接从《Boat Attack》的代码库中迁出节点代码,尝试自己的光照设想。

[转载]Unity《Boat Attack》Demo幕后揭秘插图2

自左向右:无SSS,加入SSS,最终着色

自定义船体

船体有许许多多的色彩供选择。我们使用SubstancePainter绘制了两种船体遮罩,打包储存在了纹理中,它们由Metallic(红色通道)、Smoothness(绿色通道)、Livery 1(蓝色通道)和Livery 2(不透明度)组成。我们可以在Shader Graph中选择性地在遮罩位置应用上不同的颜色。

[转载]Unity《Boat Attack》Demo幕后揭秘插图3

这是船体上色方式的概览。使用覆盖混合可以让较不明显的色彩穿透反射率贴图。

[转载]Unity《Boat Attack》Demo幕后揭秘插图4

这是Shader Graph中的节点布局,全部包括在了一个次级图表中,便于在RaceBoats父图表中使用。

房屋

《Boat Attack》中有完整的日夜循环。为了增加景色的实感,我们为关卡中所有建筑的窗口制作了一个Shader Graph。该图表会在日暮时为窗口添加些许光照,在黎明时去除光照。
我们使用了一个简单的发光纹理,根据返回的日夜数值来确定是否要添加贴图。此外,还根据对象的位置加入了打乱纹理排序的效果,让房屋能以不同的顺序被点亮。

[转载]Unity《Boat Attack》Demo幕后揭秘插图5

实现随机发光的节点图

云朵

既然在《Boat Attack》中有了光线的变换,简单的高动态范围成像(HDRI)天空盒似乎已不能满足需求。云朵应该动态地受场景光照影响。
但大块云朵的实时渲染性能要求太高,对移动端来说尤其如此。因为我们不需要从多个角度观看云朵,所以可以使用带纹理的卡片状云朵来节省性能。

[转载]Unity《Boat Attack》Demo幕后揭秘插图6

当前渲染云朵的图表

通过API渲染来实现无缝的平面反射

可编程渲染管线的目标是允许用户自定义渲染代码,将代码部分摆到用户的面前。我们并不会简单地打开使用现有的渲染代码,而是不停地添加新的API和硬件支持,将渲染技术带上新的台阶。

用户可以使用自己的C#脚本拓展通用渲染管线开箱即用的渲染功能。管线有4个与之相关的API:

  • RenderPipelineManager.beginFrameRendering
  • RenderPipelineManager.beginCameraRendering
  • RenderPipelineManager.endCameraRendering
  • RenderPipelineManager.endFrameRendering

你可以使用这些挂钩,在系统渲染场景和特定镜头之前,运行自己的代码。在《BoatAttack》中,我们使用了这些API,在主要帧被渲染之前,将场景渲染进纹理,实现了平面反射的效果。

private void OnEnable() {
   RenderPipelineManager.beginCameraRendering += ExecutePlanarReflections;
}

由于我们订阅了该API的回调,需要用OnDisable来取消订阅。
我们可以在平面反射脚本中看到入口点。这段代码可在每次通用渲染管线渲染镜头时调用一个自定义方法。这里调用的方法为ExecutePlanarReflections

public void ExecutePlanarReflections(ScriptableRenderContext context, Camera camera) {
    //rendering code....
}

由于使用的是beginCameraRendering回调,必须以一个ScriptableRenderContext和一个Camera作为参数。这些数据会随着回调一起被导入,方法还会告知渲染的是哪个镜头。
大部分情况下,这里的代码就是应用平面反射的范例了,它处理的是镜头和矩阵。唯一的区别在于,通用渲染管线有用于渲染镜头的新API。
应用平面反射的完整方法如下:

private void ExecutePlanarReflections(ScriptableRenderContext context, Camera camera)
{
   // we dont want to render planar reflections in reflections or previews
   if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview)
       return;

   UpdateReflectionCamera(camera); // create reflected camera
   PlanarReflectionTexture(camera); // create and assign RenderTexture

   var data = new PlanarReflectionSettingData(); // save quality settings and lower them for the planar reflections

   beginPlanarReflections?.Invoke(context, m_ReflectionCamera); // callback Action for PlanarReflection
   UniversalRenderPipeline.RenderSingleCamera(context, m_ReflectionCamera); // render planar reflections

   data.Restore(); // restore the quality settings
   Shader.SetGlobalTexture(planarReflectionTextureID, m_ReflectionTexture); // Assign texture to water shader
}

这里我们使用了下述新的方法来渲染了平面反射镜头。
这里我们使用了新的UniversalRenderPipeline.RenderSingleCamera()方法来渲染了平面反射镜头。
由于使用了一个纹理(通过Camera.targetTexture设定)来渲染镜头,我们还取得了可用于之后水体渲染的渲染纹理RenderTexture。你可以在Github页面上查看完整的PlanarReflection脚本。

[转载]Unity《Boat Attack》Demo幕后揭秘插图7

平面反射的构成。自左到右:原始平面反射镜头的输出,菲涅尔镜头调暗和法线偏移后的效果,最终水体着色,无平面反射的水体着色。

这里的回调主要是用于触发渲染,但它们也能有其他用处。比如,我们还能借其禁用平面反射镜头上的阴影。使用API可以让我们处理更加复杂的需求,有更全面的控制,若将行为硬编码进场景或预制件中,这是做不到的。

插入自定义渲染通道来实现特殊效果

在通用渲染管线中,渲染是基于ScriptableRenderPasses(可编程渲染通道)完成的,后者是设定渲染对象和方法的各种指令。许多的ScriptableRenderPasses排列起来后,便成为了ScriptableRenderer(可编程渲染器)。
另一部分是ScriptableRendererFeatures(可编程渲染器功能)。
这部分是用于储存自定义ScriptableRenderPasses数据的容器,可储存的数量不限,且支持任何类型的数据。
目前有两种ScriptableRenderer可开箱即用,ForwardRenderer(前向渲染器)和2DRenderer(2D渲染器)。ForwardRenderer支持插入不同的ScriptableRendererFeatures。
为了让ScriptableRendererFeatures的创建更加简便,我们加入了模板供用户使用,模板和C# MonoBehaviour脚本中的模板类似。你可以在项目视图中右击选择“Create→Rendering→Universal Pipeline→Renderer Feature”来创建模板。创建完成后,就可以在ForwardRendererData(前向渲染器数据)资源的Render Feature(渲染功能)列表中添加自己的ScriptableRendererFeature了。
在《Boat Attack》演示项目中,我们用ScriptableRendererFeatures为水体渲染添加了两种额外的渲染通道:一种用于焦散效果,另一种则是WaterEffects(水体效果)。

焦散效果

用于焦散的ScriptableRendererFeature为场景添加的渲染通道,可以在Opaque(不透明)和Transparent(透明)通道之间渲染一种自定义的焦散着色效果。通道会渲染一片与水面平行的大四边形,防止渲染到空中的像素。四边形随镜头移动,被固定在水面的高度上,然后着色器再叠加渲染屏幕中不透明通道的数据。

[转载]Unity《Boat Attack》Demo幕后揭秘插图8

焦散渲染通道的构成。从左到右:深度纹理,基于深度信息重建的场景空间位置,根据场景空间位置贴上的焦散纹理,与不透明通道混合起来的最终效果。

你可以使用CommandBuffer.DrawMesh来绘制四边形,组成矩阵用于放置网格(位置由水体和镜头的坐标决定),然后设置起焦散材质。代码如下:

<pre class="wp-block-code"><code>public class WaterCausticsPass : ScriptableRenderPass {
   const string k_RenderWaterCausticsTag = "Render Water Caustics";
   public Material m_WaterCausticMaterial;
   public Mesh m_mesh;

   public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
       var cam = renderingData.cameraData.camera;
       if(cam.cameraType == CameraType.Preview) // Stop the pass rendering in the preview
           return;

       // Create the matrix to position the caustics mesh.
       Vector3 position = cam.transform.position;
       position.y = 0; // TODO should read a global 'water height' variable.
       Matrix4x4 matrix = Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);

       // Setup the CommandBuffer and draw the mesh with the caustic material and matrix
       CommandBuffer cmd = CommandBufferPool.Get(k_RenderWaterCausticsTag);
       cmd.DrawMesh(m_mesh, matrix    , m_WaterCausticMaterial, 0, 0);
       context.ExecuteCommandBuffer(cmd);
       CommandBufferPool.Release(cmd);
   }
}

水体效果

WaterFXPass实际效果的分屏演示。左边,最终渲染效果;右边,调试视图,水体上只显示了该通道的效果。
WaterFXPass要稍微复杂一点。我们制作该效果的目的是让对象能影响到水体,制造出波浪和浮沫。为此,我们将部分对象渲染到了一个看不到的RenderTexture上,使用了一个自定义着色器将不同的渲染信息写入纹理的通道上:在红色通道中将浮沫遮到水面上,X和Z轴的法线偏移分别在绿色和蓝色通道上,最后将水体错位效果放在了不透明度通道上。

[转载]Unity《Boat Attack》Demo幕后揭秘插图9

首先,我们以一半的分辨率制作了渲染纹理。接着,创建一个过滤器,来过滤出含有WaterFX着色通道的透明对象。
然后,使用ScriptableRenderContext.DrawRenderers
将对象渲染进场景。最终代码如下:

pre class="wp-block-code"><code>class WaterFXPass : ScriptableRenderPass
{
   const string k_RenderWaterFXTag = "Render Water FX";
   private readonly ShaderTagId m_WaterFXShaderTag = new ShaderTagId("WaterFX");
   private readonly Color m_ClearColor = new Color(0.0f, 0.5f, 0.5f, 0.5f); //r = foam mask, g = normal.x, b = normal.z, a = displacement
   private FilteringSettings m_FilteringSettings;
   RenderTargetHandle m_WaterFX = RenderTargetHandle.CameraTarget;

   public WaterFXPass()
   {
       m_WaterFX.Init("_WaterFXMap");
       // only wanting to render transparent objects
       m_FilteringSettings = new FilteringSettings(RenderQueueRange.transparent);
   }

   // Calling Configure since we are wanting to render into a RenderTexture and control cleat
   public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
   {
       // no need for a depth buffer
       cameraTextureDescriptor.depthBufferBits = 0;
       // Half resolution
       cameraTextureDescriptor.width /= 2;
       cameraTextureDescriptor.height /= 2;
       // default format TODO research usefulness of HDR format
       cameraTextureDescriptor.colorFormat = RenderTextureFormat.Default;
       // get a temp RT for rendering into
       cmd.GetTemporaryRT(m_WaterFX.id, cameraTextureDescriptor, FilterMode.Bilinear);
       ConfigureTarget(m_WaterFX.Identifier());
       // clear the screen with a specific color for the packed data
       ConfigureClear(ClearFlag.Color, m_ClearColor);
   }

   public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
   {
       CommandBuffer cmd = CommandBufferPool.Get(k_RenderWaterFXTag);
       using (new ProfilingSample(cmd, k_RenderWaterFXTag)) // makes sure we have profiling ability
       {
           context.ExecuteCommandBuffer(cmd);
           cmd.Clear();

           // here we choose renderers based off the "WaterFX" shader pass and also sort back to front
           var drawSettings = CreateDrawingSettings(m_WaterFXShaderTag, ref renderingData,
               SortingCriteria.CommonTransparent);

           // draw all the renderers matching the rules we setup
           context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref m_FilteringSettings);
       }
       context.ExecuteCommandBuffer(cmd);
       CommandBufferPool.Release(cmd);
   }

   public override void FrameCleanup(CommandBuffer cmd)
   {
       // since the texture is used within the single cameras use we need to cleanup the RT afterwards
       cmd.ReleaseTemporaryRT(m_WaterFX.id);
   }
}

这两个ScriptableRenderPasses通道全放在了一个ScriptableRendererFeature中。该功能包含了一个<code>Create()</code>函数,可用于设置资源,从UI传入设置信息。在渲染水体时,两个通道一般都一起使用,所以我们加入了将两个通道同时加进ForwardRendererData的功能。完整的代码在Github页面上。

未来计划

在整个Unity 2019版本周期中,包括19.4LTS版,我们将持续更新项目。而自Unity 2020.1起,我们将以维护项目为主,确保其能正常运行,但不会再添加新的内容。
计划包括:

  • 进一步完善日/夜循环(在通用渲染管线中整合进更多的功能,减少自定义的需要)。
  • 打磨水体部分的UX/UI
  • 应用“Imposter”假体
  • 修整代码、调试性能

常用链接

《Boat Attack》Github代码库
完整的2019.3项目链接(不使用GitHub)
通用渲染管线手册

通用渲染管线并不会取代或包揽高清渲染管线

通用渲染管线未来将成为Unity默认的渲染管线,“一次开发,到处部署”。它更具灵活性和可拓展性,产出比内置渲染管线性能更高,且图像质量非常出色。
HDRP则专为高端平台产出最顶级的图像。如果项目的目标是希望在高端硬件上突破图像的极限,展示性能强劲、高度清晰的图像,HDRP是最佳的选择。
请根据项目的功能特点和平台要求来选择使用两种渲染管线。

快来尝试通用渲染管线吧

快来体验管线所有成品级的功能和性能增益吧。你可以升级项目到通用渲染管线,或用Unity Hub中通用渲染管线的模板创建新项目。

版权所有:Unity官方社区
原文地址:Achieve beautiful, scalable, and performant graphics with the Universal Render Pipeline

]]>
https://xians.me/103/feed/ 0
[转载]Unity 2019.3地形工具–Paint Holes(坑洞绘制)功能介绍 https://xians.me/101 https://xians.me/101#respond Wed, 11 Mar 2020 10:31:36 +0000 https://xians.me/?p=101

作者:Ashley Alicea,2020年1月31日

在Unity 2019.3中,我们为地形制作系统加入了许多令人激动的更新,这其中包括了呼声最高的坑洞制作功能(当然你也可以直接称呼它为“挖坑”功能)。

我们可以使用新的Paint Holes笔刷工具遮出地形块图网格中的一部分,还可以使用代码来操纵这些遮出部分的属性。在遮出地形后,我们便能更轻松地使用ProBuilder、ProGrids和Polybrush这类编辑器内的工具来为地形加上坑洞、传送门,甚至是洞穴。一起来看看制作简单洞穴的流程吧。

[转载]Unity 2019.3地形工具–Paint Holes(坑洞绘制)功能介绍插图

设置、自定义地形块图

在场景中加入一个新地形块图,做一个大致像山的形状。如果你还没试过最新的Terrain Tools(地形制作工具)预览包,可以看看《使用全新Terrain Tools资源包快速创作地形》和《使用Unity 2019.2最新地形工具加速地形创作》。

使用Paint Holes工具制作洞穴的入口

在Terrain Tools下拉菜单中,选择Paint Holes笔刷。选中地形块图,在检视器中选择笔刷形状,将笔刷的不透明度设为100。在地形上画出一个圆作为洞穴的入口。

使用ProBuilder制作出洞穴形状

ProBuilder和Polybrush是两个编辑器内的3D建模工具,可用于制作简单的洞穴。你可以使用包管理器将两个工具加入到项目中。安装完成后,就能开始用ProBuilder制作洞穴了。
选择Tools→ProBuilder→ProBuilder Window来打开工具。在ProBuilder菜单中选择新建一个ProBuilder形状,然后选择Pipe(管道)预设。选择管道的一侧作为洞穴的入口。新建一个比管道半径稍大的Plane(平面)形状,用它封住洞穴的另一端。
在ProBuilder中同时选中两个对象,将它们合并成一个GameObject(游戏对象)。使用ProBuilder的表面选取工具,选中并删去超出洞穴大小的多余平面。调整对象的尺度,使其适应坑洞的大小,再将它放到正确的位置。

让洞穴网格接上地形坑洞

使用Polybush工具推/拉洞穴入口处的顶点,直到洞穴与地形坑洞完美衔接起来。同时,你还能给洞穴加上不同的地形变化,使其看起来更加自然。

[转载]Unity 2019.3地形工具–Paint Holes(坑洞绘制)功能介绍插图1

洞穴制作完成

到此为止,相信各位已经get了如何为地形添加更多细节。初次之外,如果你更喜欢用外部软件来建模,也可以使用Unity的DCC整合工具将制作出来的洞穴网格导入引擎。与此同时别忘了在洞穴中加入石头和光照来润色!

Unity DCC 整合工具

恭喜,现在你学会了为地形添加更多细节了。如果你更喜欢用外部软件来建模,也可以使用Unity的DCC整合工具将制作出来的洞穴网格导入引擎。别忘了在洞穴中加入石头和光照来润色!
想要学习如何制作具有丰富细节的地形吗?来看看我们的Paint Holes说明文档SIGGRAPH 2019上的Terrain工坊活动吧。“挖”得开心!


版权所有:unity官方社区 原文地址:Unity 2019.3地形工具--Paint Holes(坑洞绘制)功能介绍

]]>
https://xians.me/101/feed/ 0
[转载]如何使用Unity制作影院级的动漫影片 https://xians.me/98 https://xians.me/98#respond Thu, 19 Dec 2019 03:43:45 +0000 https://xians.me/?p=98

在最近的Unite东京2019上,许多动漫工作室都开始关注起Unity作为实时渲染方案在制作动漫时的可行性。本文我们将以动漫工作室Graphinica为例,详细了解动漫制作和实时渲染之间是如何连接在一起的。

作者:tamtam,2019年11月26日

原文链接:https://blogs.unity3d.com/2019/11/26/highlights-from-unite-tokyo-2019-achieving-theater-quality-anime-with-unity/

Graphinica, Inc.是一家致力于创作电视和电影动漫的日本工作室,而最近工作室开始探索使用实时渲染来制作影院级动漫的可能性。于是,我们与工作室进行了合作,证明了其想法的可行性,并在Unite东京上分享了结果。

Graphinica, Inc.已经在制作2D和3D动漫项目上有了十多年的经验,大部分项目都是在工作室内部完成的。在今年的9月,工作室发布了动漫电影《HELLO WORLD》,影片在各影院接连上映。

影片的大部分片段都使用了传统的预渲染技术制作,同时,工作室还使用了Unity创建了不同的背景场景,然后让人物走入这些虚拟空间表演。在使用Unity之后,制作团队得以更快地迭代,Graphinica的监制平沢直表示:“实时渲染软件带来的快速试错有不可替代的作用,制作时我们得以及时地满足顾客不断提高的影片质量要求。”

早在影片发布之前,团队其实就已经在思考,能否使用Unity的实时创作工具来制作包含极度复杂的骨架、影院级的高质量网格以及高度精确的阴影等一系列具有挑战性的场景,并在同时保持相同的影院级质量。

/

为了达到目的,Graphinica与Unity Technology的工程师们达成了合作。两方团队计划重建《HELLO WORLD》中的场景,在开发过程中使用实时渲染和动漫制作工具,来验证该方法的可行性。

整个项目主要设计了两种技术:专用于动漫的实时光线追踪和阴影特效技术。最后使用的技术被称为Raytraced Hard Shadow,Graphinica使用该技术实现了实时渲染中的高质量、高精度、与预渲染动画画风相同的阴影效果。

此外,从数字创作工具(DCC)中导出的复杂多网格数据可以直接在Unity中的实时回放,对制作起了重要的作用。在MeshSync中添加的VertexCache(顶点缓存)功能可以与DCC工具保持实时链接,让DCC工具中制作的复杂骨架动画可以直接导入到Unity中。

请观看本展示片段,了解Graphinica如何使用Unity重新制作出影院级的动漫。

平沢表示:“Unity使得创作者和软件工程师之间合作变得更为平滑,在改善生产流程上有着不少的潜力。”

针对日本动漫风的实时方案

Unity日本的区域负责人御前浩紀表示:“这只是Unity向日本动漫制作进军的第一步,我们会继续开发这些工具。”
在本次Unite东京的Keynote演讲中,Graphinica大概介绍了整个实验、方案,以及制作的早期准备与最后完善。


版权所有:unity中文官方社区 原文地址:如何使用Unity制作影院级的动漫影片

]]>
https://xians.me/98/feed/ 0
Unity Pro 2019.2.0f1 Windows激活补丁 https://xians.me/96 https://xians.me/96#respond Thu, 05 Sep 2019 14:08:59 +0000 https://xians.me/?p=96

Unity Pro 2019.2.0f1 Windows安装破解教程,Unity Pro最新版 2019.2.0f1绿色安装版,附安装包和破解补丁(注册机)、破解证书、永久激活码。可以避开解决类似pattern not found的错误。

下载地址在文章底部,由于博主也是买回来,同时网站维护也要一定费用,所以收取少量费用,请见谅。

我提供的这种方式,绝对可以破解Unity Pro 2019.2.0f1,亲测可用。

本文方法优于UnityProUniversalPatcher,不会出现pattern not found错误Unity Pro 2019.2.0f1版本破解安装教程:

备注:如果要破解hub的话,直接用app.asar(在压缩包中)覆盖安装目录\Unity Hub\ resources\app.asar

下载与安装

下载与安装UnitySetup64-2019.2.0f1.exe程序

Unity Pro 2019.2.0f1 Windows激活补丁插图///## 破解

  • 使用破解补丁中的文件,覆盖Unity.exe文件,如下图所示:

Unity Pro 2019.2.0f1 Windows激活补丁插图4

/

复制破解证书到C:\ProgramData\Unity目录,一定是C:\ProgramData\Unity目录,如果在C盘下找不到ProgramData这个目录,一定是被隐藏了,请按照下图方法显示隐藏的文件夹:

Unity Pro 2019.2.0f1 Windows激活补丁插图6//

破解成功,如下图所示

Unity Pro 2019.2.0f1 Windows激活补丁插图9
Unity Pro 2019.2.0f1(包括Addons、Android Support For Editor、Support Files、Unity Prox64安装程序):

]]>
https://xians.me/96/feed/ 0
[转载]使用光照探针实现静态光照 https://xians.me/94 https://xians.me/94#respond Mon, 02 Sep 2019 06:28:38 +0000 https://xians.me/?p=94

在2019.2版本中,我们移除了光照贴图静态标识,用“Contribute to GI”(帮助全局光照)设置取而代之。同时,全局光照的光源现在可以在光照贴图和光照探针之间选择。这个看上去很小的改动会给场景光照性能与质量上的烘焙造成巨大影响。我们来一探究竟吧。

光照贴图和光照探针

全局光照通过一系列复杂的计算来模拟光从光源射出后在表面间的弹射。精确的模拟一般需要在运行时加上大量繁重的计算。为了达到最佳输出效果,这个问题常见的解决方案是预先将这些计算在编辑模式中完成。
要实现此种方法,首先得确保场景中的部分对象和光源位置、形状、角度和任何画面属性都相对固定。有了这些前提条件,此类光照便能以光照贴图技术来完成了。
为了标记这些对象,Unity使用了光照贴图静态标识。该功能在当时看来确实恰当,说明了只有静态对象会使用光照贴图。但静态贴图只是给场景添加全局光照的许多方法中的一种,且有一定的缺陷,我们稍后会继续讨论。
当使用光照贴图来实现全局光照时,非静态(动态)对象无法对全局光照起作用,因为它们违背了静态这个前提。如为移动对象添加全局光照,光照只会在起始位置上生效。这是传统光照贴图的主要局限。
动态对象仍然能通过光照探针接收到来自其他静态对象生成的全局光照。光照探针是空间中的一个个位置点,它能采样各个方向射来的光并进行储存。此种光照数据被编成叫做“球谐函数”的特殊值。在运行时,动态对象在世界中移动时便能从光照探针周围接收到光照数据。这项功能使动态对象能正确接收到局部光照,与四周光照环境相和谐。
技术上来说,静态对象完全能用光照探针取代光照贴图,所以它还有什么用呢?

纹素成本

需要光照的对象必须先展开,并在光照贴图中预留部分空间。根据分辨率,每个投射进光照贴图的对象会保留不同大小的纹素。
比如,在每空间单元一纹素的光照贴图分辨率中,一单元方块(1x1x1)每一面会留存一个纹素,总共会有6纹素。在每个纹素上,贴图将计算照射到纹素位置的光照数据。计算过程是先投射出几条射线,让其在场景中弹射,直到发现一处光源。纹素越多,结果的计算量越大。当场景中有许多小型对象时,计算量便会急剧增加。实际上,此类对象的展开、绘制及光照贴图的添加正是烘焙失败或耗时较长的罪魁祸首。

[转载]使用光照探针实现静态光照插图

光照贴图分辨率为1时一单元方块正好占据了一纹素。
较小的物体,如石子和小残骸,或细小的物体如电线和旗杆很容易造成“纹素浪费”。这些纹素并不会对整体外观有太大影响,但仍旧占据了部分运算时间和贴图空间。
细小物体常出现仅有一两个像素包裹住物体的情况,对整体外表影响较小。同样,小型对象(根据其在屏幕上的大小而定)经常产生许多对最终效果影响不大的纹素。结果就是许多我们难以察觉的纹素耗费了大量计算时间,增加了所需光照贴图的量。

[转载]使用光照探针实现静态光照插图1

可轻易用光照探针照亮的小型对象举例。
针对生成光照贴图时间的优化方法之一是将这些小型对象设置为非静态,将其移出光照贴图计算,以此来减少需要计算的贴图纹素数量。但是,在部分情况下这些对象对场景光照会有极大影响,比如一个非常明亮的带色对象,或者有发光材质的对象。当这些对象不属于静态光照贴图时,它们将不会为场景中加上全局光照效果,也就不会施加期望的光照影响了。
于是,在处理这类对象时,我们便面临两个抉择:为其添加光照贴图,使其能为场景添加效果,即使花上更长的烘焙时间及更多的贴图空间,或者舍弃它们,放弃其带来的整体和全局光照效果。如何解决这个两难境地呢?

使用光照探针

在2019.2版中,我们添加了一个功能,使得对象能在接收光照探针的全局光照的同时,给为场景施加光照效果。你可以在Mesh Renderer监视器中新加的下拉菜单中激活该功能。

[转载]使用光照探针实现静态光照插图2

新的Contribute和Receive Global Illumination选项。
在这,你能为Mesh Renderer选择从Lightmap(光照贴图,此前静态对象的唯一选择)或从Light Probes(光照探针,此前动态对象的唯一选择)Receive Global Illumination(接收全局光照)。
当Contribute Global Illumination激活时,该物体会被包括在光照贴图的全局光照计算中。虽然仍需要假定对象静止不动,但现在你可以根据具体的光照清晰度要求,指定使用光照探针或光照贴图。当对象Contribute Global Illumination的同时从光照探针Receive Global Illumination,它仍会对周遭施加影响。一杆路灯可以投下经由光照贴图计算的阴影,同时放射性的灯光材质仍会照亮周围场景。

使用本功能

有了这项新功能后,在Unity中优化这些麻烦的细小对象就简单直接了:只需将Mesh Renderer中Receive Global Illumination一栏选为Light Probes。设置完后,指定的对象便不会在光照贴图中占用空间了,而相应的纹素也不会再产生不必要的计算。
光照探针另一个较为关键的优点是它不需要UV来工作,能省去许多展开时间。如果你有一个不怎么移动、旋转或改变的动态对象,与光照探针相性较好,可以用Contribute Global Illumination来进行设置,该对象便能在不增加烘焙时间的前提下影响周围的对象。这样能极大地增加生产力,更有效地利用内存资源。

结论

有了这次更新,动态(非静态)对象就能用光照探针来照射了。你可以决定全局光照计算中的对象从光照探针或光照贴图中接收非直射光照,降低光照贴图中的纹素使用。总之,这次改动将大幅减少光照贴图的计算时间、降低内存使用、提升运行时的性能


版权所有:unity中文官方社区 原文地址:使用光照探针实现静态光照

]]>
https://xians.me/94/feed/ 0
[转载]Unity的光照烘焙技术(下) https://xians.me/92 https://xians.me/92#respond Fri, 30 Aug 2019 01:40:02 +0000 https://xians.me/?p=92

本文将介绍如何使用Unity的Progressive工具去正确的烘焙光照以及设置一些光照。

Unity的光照烘焙技术(上)中,Unity技术美术李万里介绍了Unity的光照系统。本文将介绍如何使用Unity的Progressive工具去正确的烘焙光照以及设置一些光照。

演讲内容

我们谈了很多光照烘培的内容,但也要考虑到烘培的代价是非常高的。
如果我们烘培一个地图,整个场景不可能都是Box垒起来的,还有大量的物体。如果这些物体全部都要烘培,需要有很强的电脑和集群服务器进行渲染。
我们还面临一个问题:烘培贴图的数量和体积非常的大,因为它是RGB通道的一些彩色图片,所以是无法改变的。
我们只能通过格式压缩,但压缩会出现质量下降的情况。贴图加载会占用大量的显存,所以优化整个光照很重要。
Unity提供了两个非常重要的功能:Light Probe和Light Probe Proxy Volume,二者可以配合使用。Light Probe是球形光照,提供比较简单的间接照明,可以为小物体提供间接光。
如果游戏场景在室外,像一些植被,草和小型岩石可以不用烘培。因为它们虽然很小,但是整体的数量是很庞大的。尤其是一些小的细节,如果精度不够,烘培的效果会非常差。

[转载]Unity的光照烘焙技术(下)插图

如上图所示,Light Probe Proxy Volume用来给这个小火车进行间接照明,它上面的这些点可以吸取左侧Light Probe上离它最近的值,它会在几个球之间进行颜色的混合,混合出一个符合小火车形状的间接光的体积。尽管本身小火车没有进行光照计算,但它也拥有了间接光。
Light Probe Proxy Volume目前不支持移动平台,它只支持一些PC或主机平台,之后我们可能改进,支持移动平台。

[转载]Unity的光照烘焙技术(下)插图1

大家可以按照项目的情况,正确的使用可以缩减Lightmap的数量和烘焙时间,提高效率。人物和车辆这类动态物体,一定是使用Light Probe进行照明。
用于结构复杂的小物体,满足下列需求即可:

  • 结构复杂,单体部件表面起伏过大,UV复杂的物体。尤其在Enlighten中计算的时候,因为复杂性是难以逾越的障碍。
  • 体积小,不显眼的。例如:镜框和电线杆。
  • 不重要的,并非游戏场景的重要部件。例如:一块80%埋在地下的岩石。

树和植被也使用Light Probe照明,因为Enlighten对树和植被也非常的不友好。
Lightmap优化方面,可以大量使用Light Probe,从而优化掉1/3到1/5的Lightmap数量,加速烘焙时间,使烘焙测试的时候更加流畅,不必等待太长时间。

[转载]Unity的光照烘焙技术(下)插图2

如下图所示,这张图是用Enlighten烘焙的。说到Enlighten,不得不提Enlighten最核心的三个概念:Systems、Clustering、UV Charts。
我们可以把Systems作为Unity让Enlighten把场景中的部件按照光照和它的距离关系来构建出来一个承接光照的最大单元。我们会看到它的颜色不同,代表是不同的System,这种依存关系决定Enlighten构建的复杂度。
Enlighten会根据使用什么材质,哪个光照对它有影响,它和哪个物体位置比较近,自动构建System。构建得越复杂,计算量也会越多。
Clustering是最核心的Enlighten概念。Enlighten本身光照进行照明是不需要计算的,它计算的是光照环境。所以构建光照环境时,才可以创造这些Clustering。
UV Chart是Lightmap光照贴图的UV,而构建光照环境最核心的东西是UV Chart,如果没有UV Chart,它就没有空间可以存储Clustering作为计算单元。

[转载]Unity的光照烘焙技术(下)插图3

为什么我们此前说过Enlighten不适合用于植被和树呢?
因为我们制作了一个树,有多少片树叶,就有多少UV Charts,每个UV Chart都要进行光照计算,光照计算最低代价是4x4,即4个像素乘4个像素的代价去生成整个计算UV Chart的光照空间。
计算Clustering时,每个至少保留16个像素。如果一棵树还好,如果有500片叶子,还可以接受。如果有一片树林,那就使用Enlighten计算不动了,所以不建议使用Enlighten对树木进行间接光照计算。
我们需要尽可能的缩减单个物体的Lightmap的UV区块来降低UV Charts,在分Lightmap UV时一定要注意,尽可能将UV连在一起,这样会让Enlighten计算量降低。
Clustering基本上用每个色块作为一个计算单元,它可以发射低频光对周围进行影响,精度越高,块越小,整体的计算量就会加大,整个计算间接光的时间就会更长一些。

[转载]Unity的光照烘焙技术(下)插图4

我们自动生成的一些UV可以使用Unity的功能,在物体上有UV Charting Control,进行动态合并。在合并完成后,我们进行预计算,看看合并上有没有问题。
合并UV的时候可能会出现扭曲现象,这种扭曲现象在烘焙Lightmap时是非常有问题的。

[转载]Unity的光照烘焙技术(下)插图5

上图中的两个示例,UV Charts等于6的情况下,如果Box分成左边是比较合理的,右边这么分在Enlighten的计算量最起码要增加3倍。

[转载]Unity的光照烘焙技术(下)插图6

我们来了解一下Unity的光照贴图设置。

  • Resolution:控制Clustering的分辨率,会和Lightmapping Settings的Indirect Resolution相乘获得最终的Resolution。
  • Cluster Resolution:控制Clustering,结果会和Resolution相乘。我们可以通过对这些参数进行搭配,调出不同的Resolution。
  • Lightmap parameters:我们可以为关卡中每一类物体都设置不同的Lightmap parameters,来控制不同物体的Clustering Resolution,从而提高lightmap烘焙效率。例如:一些不需要计算的植被可以设置一个新的Lightmap parameters组,让它只接受别的物体的间接光,自己不再产生间接光,降低计算时间。
[转载]Unity的光照烘焙技术(下)插图7

如上图所示,从左到右依次是Cluster Resolution是3米、1.2米、0.72米的效果。我们可以看出,只有在Cluster Resolution=0.72米的时候,在室内的效果基本才是合格的。

[转载]Unity的光照烘焙技术(下)插图8

下面是我们给出的一个计算单元的建议,大家可以根据这个建议来设置游戏中的一些精度。

  • 常见的物体Cluster Resolution 参考(每单元大小):
  • 室内墙壁精度为0.5-1米
  • 室内重要道具精度0.5米
  • 室外建筑精度1-2米
  • 室外地面精度2-4米
  • 室外重要游戏道具精度1-2米
[转载]Unity的光照烘焙技术(下)插图9

简单介绍一下Progressive Baking,它的情况非常的暴力,就是你有多少光子,直接光的Samples,有多少间接光的Samples,最终可以获得怎样的精度,最终取决于你的电脑有多强。
值越高效果就越好,但是不要特别高。我们建议在室外,Direct Samples为50,室内最少要80-100。Indirect Samples在室外大概用400,室内800,不然会出现黑斑问题,弹射次数建议为4次。

[转载]Unity的光照烘焙技术(下)插图10

现在提供给大家一些光照经验总结,基本上代表了现在光照技术,使用Unity制作移动平台光照时最重要的建议。

  • 首选线性空间作为项目的开发环境,Gamma空间适合Opengl3.0之前时代的项目。
  • 在线性空间下,Direction light(主光源)白天强度在1.5-1.8之间,夜间月光在0.4-0.7之间。
  • 在Gamma空间下,Direction light(主光源)白天强度在0.5-1之间,夜间月光在0.2-0.5之间。
  • 光照的Indirect强度不能高过直接光的强度,在线性空间下间接光一般小于1。
  • 在Englighten渲染模式下,尽可能的降低植被的Cluster Resolution,提高渲染效率。
  • 静态物体尽可能优化掉不需要烘焙的部分,提高重要物体的Lightmap精度。不参与烘焙的物体使用Light Probe照明。
  • 优化UV Chart,单个物体UV Chart越少越好。
  • 优化不同种类的Cluster Resolution,保证不同种类的物体都有合理的计算分辨率。
  • 混合光照手机平台建议实时阴影距离控制在不超过20米。
  • 使用Unity提供的Procudral Skybox进行烘焙光照贴图。可以获得更真实的Lightmap。
  • 不轻易的调整Unity的Albedo boost和Indirect intensity强度。尽可能的保证Albedo boost =1, indirect intensity=1。

下面是烘培的一些效果,这是可以在移动平台上运行的效果。

[转载]Unity的光照烘焙技术(下)插图11
[转载]Unity的光照烘焙技术(下)插图12
[转载]Unity的光照烘焙技术(下)插图13

现在我们来进行一个演示。
如下图所示,这是一个火车的场景,我们刚刚看到它的预览效果。那么场景进行了哪些优化呢?

[转载]Unity的光照烘焙技术(下)插图14

我们可以看到,火车和铁轨都是没有烘培的,为什么呢?因为这些东西又小又不显眼,而且扁平化一块一块的,我们不需要对它进行烘培。
如果把这些内容全部使用Enlighten进行烘培,大概需要花2个小时。如果优化后,大概是3-5分钟就可以烘培完了。

[转载]Unity的光照烘焙技术(下)插图15

如下图所示,我们对小火车做了一个Light Probe Proxy Volume,这样就可以控制接受间接光的情况。

[转载]Unity的光照烘焙技术(下)插图16

我们可以控制它的精度,然后可以获得更高的纵向的采样值,如果认为它太多了,可以优化掉一部分。如果侧面需要更多的细节,可以通过这种方式对间接光进行采样,但是需要注意这种方式目前不支持移动平台。
但是如果不使用这种方式,我们可以使用Blend Probes进行融合,切换为Blend Probes时,效果会有一些差异,光照精度上是有一些损失的。
如下图所示,项目中的整体地面,都是使用的Blend Probes模式的混合。

[转载]Unity的光照烘焙技术(下)插图17

这种方式是完全支持移动平台的,比较小或者不显眼的物体,并非游戏重要物体的都可以使用Blend Probes进行照明。
我们需要勾选Static类型,它们一定在Static批次中,后面把它Lightmap Static去掉就可以了,去掉后就不会生成Lightmap,但是会接收Light Probe的影响。
在这个项目中像栏杆和一些根本不重要的内部物体,都可以使用Blend Probes进行照明,这些东西烘培下来,整体代价和贴图容量都要大大的超标的。
我们再来看看另一个场景。

[转载]Unity的光照烘焙技术(下)插图18

如上图所示,在整个光照当中,我们加了一些面光源,这是为了提高场景的窗户透光的光亮。如果不加,就没法按窗户形成面光源,向内部进行照明的。
需要注意,面光源在移动平台上,如果不是HDRP的话,就只支持静态的,只支持烘培,不是烘培的模型它是不支持的。
下图是场景的光照贴图大概是这样的,比较符合白天的光照效果。

[转载]Unity的光照烘焙技术(下)插图19

我们可以看看它的设置。
首先Procedural Skybox在这里加进来。在Enlighten当中,千万不要使用渐变和颜色进行烘焙,两者烘焙出来的东西会比较风格化,并不写实。有很多人选择用某个颜色烘渐变,但效果会非常不理想,所以一般选择Skybox进行烘焙,而Skybox一般使用Procedural Skybox。
烘焙完后,再替换为自己场景的风格化Skybox作为最终显示效果。Procedural Skybox是仅用于烘焙的,不是用于制作最终的Skybox效果。
我们再举一个简单的例子。如果要形成一个特别颓废和压抑的环境,我们可以将大气密度提到很高,然后将染色降一下,或者偏向一个色彩。
我们可以将整个曝光度调低,把大气密度调高,实现让人很压抑的环境,这种环境烘焙出来的Lightmap比较接近于比较邪恶的地方,从而获得更加压抑的光照效果。

[转载]Unity的光照烘焙技术(下)插图20

还有一点,当Atmosphere Thickness提高了以后,它作为偏光的可照明区域会缩减。缩减的意思是:黑色区域基本上不贡献光线了,整个Skybox变为不是半球形了,变得没有原来的光照面积大,所以烘焙出来的图就不那么剔透了。
因为它的周围存在染色问题,导致它控制在偏红,偏压抑的环境,就能烘托出来。我们可以通过对一些染色以后,对光线的反映来调出适合的视觉效果。
我们不建议在室内的时候使用Light Probes进行照明,因为它的物体要求精度很高,遮挡关系全靠需要低频光进行影响,没法做出很多变化。

[转载]Unity的光照烘焙技术(下)插图21

尤其是一些非常小的物体,如果想要表现出好的效果,一定要对Lightmap大小进行放大。例如:铅笔在Scale In Lightmap里要放大一倍,不然烘出来基本上没效果。但对于有的物体,我们要保证统一性,如果能保证统一性,有的地方会出现一些色斑。
在示例场景中,我们优化掉了一部分的东西,整个Lightmap的照明还可以,但是你会看到这些东西都浮起来了,靠屏幕空间的AO是控制不住的,效果会产生大量的损失。所以这样的东西只在室外有用,室内的话是不建议这么用。
Enlighten烘焙在示例场景中的效率,代价是非常大的,因为场景中的物体非常的多,它的UV Charts基本上没办法看到,非常碎,所以烘焙时间也非常长。
在小火车的场景中,使用Enlighten大概烘焙4分钟。在这个教室场景,因为物体非常多而杂,大概是小火车场景的5倍左右时间,大概20分钟。
使用Progressive烘培则很稳定,它只看场景有多大的精度,不管场景有多少物体,这就是Progressive和Enlighten之间的差异。

[转载]Unity的光照烘焙技术(下)插图22

我的演讲到此结束,谢谢大家。

小结

我们希望通过本次演讲内容,让你熟练掌握Unity光照系统以及烘培技术。


版权所有:Unity China 原文地址:Unity的光照烘焙技术(下)

]]>
https://xians.me/92/feed/ 0
[转载]Unity的光照烘焙技术(上) https://xians.me/90 https://xians.me/90#respond Mon, 26 Aug 2019 07:35:00 +0000 https://xians.me/?p=90

本文将分享Unity的技术美术李万里在Unite Shanghai 2019大会的演讲内容,他将深入浅出的带领你了解Unity的光照烘焙技术。

演讲内容

今天很高兴和大家分享我工作这么多年来对Unity光照的理解和认识。

首先我将介绍一些概念,然后慢慢的深入给大家讲解,如何使用Unity的Progressive工具去正确的烘焙光照以及设置一些光照。

为什么谈谈Unity光照呢?

因为我发现很多客户对Unity的光照烘焙技术了解都存在问题。他们认为Unity的光照不好,没有别的引擎效果好,或者存在其它的问题。但大家通过参加Unite 2019大会,看到了不少Unity高品质的一些画质。

本次演讲,我将主要给大家分享在Unity的内置渲染管线和轻量级渲染管线LWRP下,如何正确烘焙光照。

[转载]Unity的光照烘焙技术(上)插图

Unity的光照和烘焙是每个制作游戏的人都非常重视的,因为它的效果决定了游戏品质。

前些年,由于受困于性能限制,很多使用Unity开发的游戏是没有光照的,主要是靠手绘贴图。由于计算性能的提高和移动平台的高性能,现在我们可以制作出前几年主机平台上的游戏品质。

所以光照烘焙在游戏开发者领域是一个越来越重要的问题,这也是越来越多公司通过招聘技术美术来提升画质的重要原因。

[转载]Unity的光照烘焙技术(上)插图1

Unity的光照基本上就是分三种:从早期的Enlighten到Progressive CPU ,再到Progressive GPU,从发展轨迹可以看出,大家对光照还是偏向光线追踪算法,认为这是未来的发展方向。

因为Enlighten本身不是光线追踪算法,它是一种非常复杂的数学模型算法,而且对美术制作非常不友好,导致很多人使用Enlighten烘焙都效果不佳。

[转载]Unity的光照烘焙技术(上)插图2

我们说了Unity光照,就不得不说Unity的光照技术。

主光源是:Directional Light、Area Light、Spot Light、Point Light。基本上是目前游戏开发的主流光照,Directional Light和Area Light是使用得最多的,其次是Spot Light常常用于人造光源和特效光源。

SkyLight是Unity很重要的一个功能,这也是很多人烘焙Unity光照最容易出问题的部分。Unity提供Procedural Skybox,这个Skybox基本上会贡献整体光照烘焙Lightmap的80%左右,所以如果不会使用SkyLight,烘培出来的贴图将效果很差。

最后是Light Probe和Reflection Probe,它们是用来提升一些特殊效果和优化性能的。

[转载]Unity的光照烘焙技术(上)插图3

说到Unity的光照,我们不得不提到一点:Unity从Gamma空间过渡到线性空间,以及现在一直保留的Gamma空间的支持,是为了一些老的项目有版本升级的可持续性,但未来Gamma空间将被淘汰掉。

线性空间的优点是能够容纳更多亮度细节,不需要压缩亮部来提高暗部的效果,亮部的表现力更强,更接近真实的光照效果。由于当年OpenGL ES 2.0时代的整个计算能力有限,所以Gamma空间进行了一些压缩。

[转载]Unity的光照烘焙技术(上)插图4

我们看一下上面这张图,这就是Procedural Skybox,它重要在哪儿呢?

因为它提供了光照。我们自然界中光照有两个非常重要的概念,一个概念是它有大气的厚度,大气厚度决定色散的情况,对光线的反映。

Sky Tint主要用来计算天空的染色情况,如果空气密度很高,整个天空又染上一些色,它对光线的反应情况。正常情况下,对地球的Sky Tint,只有沙尘暴时才会出现比较奇怪的效果,如果没有沙尘暴的情况下,地球的Sky Tint值比较接近灰度的颜色。

如果在制作异星题材的游戏的话,情况就不太一样,你可能要根据颜色的调整,让大气做一些吸收,这样折算出来的Sky Light会发生一些改变。

Ground基本上是Skybox在模拟地面对物体的影响,如果值很强会让地面失去立体感,计算时底部的光照会很强,导致天花板的区域变亮。所以这个值不要调得特别的高,基本上以灰度为主。

Exposure曝光度的值非常重要,它是天光的强度,基本上可以达到8或更高的倍数,它可以让整个天光变得更强,更强的结果是整个Skybox会非常强。好处是带来更多间接光的强度,但也会带来让受光比较多的地方产生过曝的问题,这是大家需要控制的。

关于Exposure曝光度,建议大家可以跟Atmosphere厚度的值一起调整。如果曝光度增强的时候,可以将大气密度提高,它会形成比较奇怪的现象。在大气足够密的情况下,曝光度很强,大气密度底部会对光线的吸收特别的强,会发生右侧图片发红的情况,这样会计算出一些接近于早晨、晚上的效果。

像左侧这张图,基本上它的大气密度值在1,Exposure值在3,而值在2是另一种效果,它的厚度值在2时,产生了色彩上的变化,这个变化是在模拟物理的效果。

[转载]Unity的光照烘焙技术(上)插图5

Directional Light在移动游戏开发中常常用作太阳和月亮的首选光源,因为它能够覆盖整个场景,计算的时候非常节省性能。

直接光强度在线性空间下,我们建议白天为1.5-2.0,夜晚为0.4-1.0。Indirect Multiplier值,白天为0.6-1.0,夜晚为0.3-0.7。白天获得的直接光照比晚上的要强,这样白天会产生更好的间接光亮度。

[转载]Unity的光照烘焙技术(上)插图6

我们看一看烘焙的效果。如上图所示,在白天的设置下,Intensity是1.8,Indirect Multiplier是1,Atmosphere Thickness是1,Exposure是3,这样我们获得了白天光照很好的房间。

如果设置正确,它应该会出现很好的GI效果,而且不会之前认为,在Unity光照中,有些暗部和间接光不是很好,缺乏全局照明的层次感。

[转载]Unity的光照烘焙技术(上)插图7

上图就是夜晚的设置效果。在设置中,Intensity是0.4,Indirect Multiplier是0.25,Atmosphere Thickness是1,Exposure是0.1,基本上设置的数值都会往下降。特别是降低曝光度后,我们会得到月光的效果,但是它也有间接照明。

[转载]Unity的光照烘焙技术(上)插图8

上图是人造光源的效果。Unity提供的除了常用的Point Light、Spot Light,还有一个就是Emissive自照明。Unity支持物体的像素照明,可以将物体的Emissve HDR值提高,提高以后就形成一个光源。

像灯管基本上就是一个Emissve照明的效果,它对房间进行了增强和补亮。为了体现夜晚效果的叠加,上图设置没有调得特别强,如果你希望更亮一些,可以在上面增加Area Light,进行补光。

如下图所示,我们可以看到Area Light关掉和开启的效果对比。

[转载]Unity的光照烘焙技术(上)插图9

Area Light主要用途是什么呢?

如果大家比较观察细节,可以发现窗户的采光,除了太阳光照,有可能窗户外面世界亮的东西,都会发射光线进入房间。但是在计算机不会这样计算。因此,我们需要在窗户边上做一个同样大小的Area Light,往房间里面补光。

在补光之后,你会看到,尤其是在光照贴图的一侧,Area Light关掉和开启会有明显的视觉效果差异。这是因为右侧的区域没有Area Light,它不是非常仿真物理效果,如果加了Area Light,它会很仿真物理。

[转载]Unity的光照烘焙技术(上)插图10

光照贴图的一个问题是,它们做的都是间接光,间接光一定不能将光照贴图曝掉,或者曝光度严重不足。所以我们需要一个间接光的空间去存储这些间接光信息。

如上图所示,如果间接光非常的亮,会导致我们看到的最右侧的图像效果。曝光那么多的时候,间接光贴图就损失掉了。

我们建议把Light Intensity设为1.8,HDR Exposure为16,或者Intensity等于3,HDR Exposure为16的曝光度效果。这样既能保证场景的亮度,又能让整体光照没什么问题。

[转载]Unity的光照烘焙技术(上)插图11

了解一些Unity光照概念后,我们应该如何烘培呢?
如果你设置了很多烘培,但基于性能考虑可能不需要那么多物体需要烘培,不优化会导致场景中很多不需要烘培的物体烘培了光照贴图。

烘培完成后,光照贴图可能会非常大,特别对于一些移动游戏,没办法使用那么多贴图,所以正确的烘培也是非常重要的。

[转载]Unity的光照烘焙技术(上)插图12

首先说一下Unity的Enlighten系统,它的一个优点是支持实时光GI。在构建过程中,构建光照条件后,我们可以调节光照的强度和方向,还可以移动光源。

但是它不能移动物体。如果静态模型要移动,Enlighten实时GI是不支持的,因为它需要构建光照环境,这就限制了Enlighten不是一个纯实时的GI,它是半实时的。

如果Enlighten使用不好,烘培速度会非常慢,我们通常会发现烘培卡在一个地方不动,慢到都想把电脑砸了,这种情况非常常见。所以大家必须按照Enlighten正确的方法去烘培才会比较快。

Enlighten好处是噪点控制非常好,如上图所示,画面的边缘没有太多的噪点,因为Enlighten的计算方式是不太会出现噪点的,它不是光线追踪算法,也不依赖于光子弹射。

Unity 5开始集成Enlighten,但Unity 2020 LTS版将是在内置渲染器包含Enlighten系统的最后一个版本,Unity 2021.1将完全移除Enlighten。

[转载]Unity的光照烘焙技术(上)插图13

Progressive烘焙基于光线追踪,发射的一个光子弹射了多少次,弹射时分裂多少光子,再进行弹射。

Progressive的优点是:真实、GPU烘焙、烘培速度快。在同等的模型数量下,Progressive的计算速度比Enlighten快很多。Progressive的缺点是噪点控制比较差,当光子发射量不够时,它无法充满整个场景,因此无法计算出正确的光照。

[转载]Unity的光照烘焙技术(上)插图14

如上图所示,我们来看看Progressive和Enlighten的烘培的差异。

Progressive和Enlighten的烘培时间基本上是相等的。Progressive会有一些斑点,Enlighten几乎没有斑点。但Enlighten的问题的缺乏细节,效果过于程序化。如果这是一个深邃的洞穴,过渡到最后面画面会变成黑色,几乎没有了。

[转载]Unity的光照烘焙技术(上)插图15

如上图所示,这是我们提高Progressive的计算光子时烘培效果对比。Progressive会更加立体,更真实一些,Enlighten比较轻一些,或者说立体感不是那么足。

[转载]Unity的光照烘焙技术(上)插图16

如上图所示,这是Progressive和Enlighten烘培后整体的预览效果,差异还是比较明显的。

[转载]Unity的光照烘焙技术(上)插图17

如上图所示,这是一些烘培参数,当Direct Samples=40和Indirect Samples=400,对比Direct Samples=100和Indirect Samples=800,我们可以看到效果差异明显。

Direct Samples和Indirect Samples等同于直接光的采样数量和间接光的采样数量。如果采样越多,光子出现得越多,它就会将整个环境填得更加均匀,更加符合真实的世界。

真实世界的光子是无限的,在计算机模拟的时候是靠光子的数量来模拟的,所以我们尽可能在烘培的时候要把光子数量提高,这样会得到较好的效果。

使用Progressive时最大的问题是:在室内的情况下,要尽可能把整个烘培的精度提高,因为室内低频光比较多,间接光受到的影响比较多,室外可以稍微降低该值,提高烘焙效率。

现在谈谈Unity的光照方案。

[转载]Unity的光照烘焙技术(上)插图18

移动游戏方面,建议大家使用混合光照技术,效率更高和更为逼真。近景可以使用动态阴影,远景使用Shadow Mask,这样可以降低Shadow Pass的压力。

例如:5-20米是使用动态阴影,远景全部使用Shadow Mask,这样手机平台上既可以获得动态阴影,又可以获得高的性能,不至于手机玩一会儿就会很烫的情况发生。

我们看一看混合光照的拆分情况。

[转载]Unity的光照烘焙技术(上)插图19

如上图所示,Baked Lightmap和Shadow Mask在烘培后,一个是RGB通道的图,另一个是单通道。如果大家有能力修改,我们可以将单通道的图变成四通道来进行变化。

我们烘焙一个Lightmap的时候,Shadow Mask可以烘培四个时间段,例如:8点、11点、15点、17点。烘培完成后,我就可以通过Lit的方式把它Lit成变化,使它有间接光照。

Lightmap只使用一套,但我们可以对它进行扩展。Shadow Mask根据昼夜变化的时间,做成四套带有间接光照的,这样便可以根据项目进行深度的改进。

小结

受篇幅限制,我们将本次演讲内容分为上下二篇。在下一篇中,我们将分享不同的场景案例如何进行光照烘培的优化。


版权所有:Unity China 原文地址:Unity的光照烘焙技术(上)

]]>
https://xians.me/90/feed/ 0
[转载]Unity中的阴影优化 https://xians.me/88 https://xians.me/88#respond Sun, 18 Aug 2019 03:42:41 +0000 https://xians.me/?p=88

本文将由游戏开发者Michael Short分享Unity中的阴影优化。

我们在开发游戏的过程中使用了一个投影式阴影系统,它类似阴影贴图,会从光源的角度渲染对象,然后把阴影从光源投射到场景。

在开发游戏的过程中,使用功能丰富的Unity阴影贴图解决方案会显得有些浪费。因为我们不希望为所有内容渲染动态阴影,而只打算对场景的较小物体渲染动态阴影。我们想更好控制对阴影的过滤,通过添加模糊效果,使阴影更加柔和。

我们在对游戏进行性能分析时,发现生成这类阴影贴图需要总体帧时间中大约12%,因此我们仔细研究如何减少这项开销,以及系统消耗的内存量。

优化工具

首先是启动性能分析工具,对Android系统进行分析时,使用RenderDoc,对iOS系统进行分析时,使用XCode。
如下图所示,RenderDoc是一款免费的性能分析和调试工具,可以连接到托管Android设备,获取帧的跟踪信息。

[转载]Unity中的阴影优化插图

如下图所示,XCode是MacOS上的首选开发应用程序,我们可以通过在调试菜单选择选项,随时获取GPU帧信息。

[转载]Unity中的阴影优化插图1

充分利用空间

通过对两个平台使用渲染目标查看器,我们发现阴影贴图渲染目标的内容只是整个纹理的一小部分。渲染目标中大概有超过50%的像素未被使用,这是对空间的极大浪费。

我们使用了投射阴影和定向光,正交投影模式往往更容易控制和调整。使用该模式可能会丢失一些方向,但这不算什么问题。我们把投影模式改为正交模式并调整好光源位置,从而更好地使用可用的渲染目标空间。

最后,我们可以把阴影贴图纹理的分辨率从128×128减少为64×64,即原始大小的1/4。移动设备的最大瓶颈之一是带宽,移动设备具有小型总线。在总线上减少75%的数据量会节省很多带宽,而且同时会减少75%的着色片段后,因此我们可以实现很大的性能增益效果。

[转载]Unity中的阴影优化插图

多重采样抗锯齿

由于我们使用了较小渲染目标,在对象开始在渲染目标中移动时,我们会注意到大量锯齿现象。由于移动端GPU的工作方式,多重采样抗锯齿效果MSAA的开销很小。

移动端GPU使用了基于平铺的架构,所有抗锯齿工作都在芯片上完成,额外内存都在平铺内存上。通过使用4x MSAA和较小渲染纹理可以获得更好的结果,只需稍微增加处理开销。

[转载]Unity中的阴影优化插图2

渲染目标格式

我们的阴影贴图渲染纹理使用R8G8B8A8格式,而且仅使用了两个通道。第一个通道是R通道,用于存储阴影本身,第二个通道是G通道,用于存储线性衰减。我们的美术要求阴影强度随距离而衰减。

通过进一步研究发现,实际上并不需要存储这两个信息,我们只需要阴影值或衰减值,具体取决于为阴影投影对象启用的功能。我们把渲染目标格式改为8位单通道格式即R8格式,这样进一步减少1/4的纹理大小,而且大大降低带宽。

模糊方法

在给阴影贴图填充渲染纹理后,我们要使阴影贴图变得模糊。这样可以减少使用较小纹理时出现的瑕疵,同时呈现出柔和的阴影效果。

我们使用了3×3方块模糊,在每个像素有9个纹理采样。此外,我们之前没有使用带有半像素偏移的双线性滤镜。我们添加了该选项,使其仅采样周围边缘的像素和半像素偏移,这样使采样数量从9降低到5。

如下图所示,由左至右分别是原图、采样5模糊、采样9模糊。

[转载]Unity中的阴影优化插图3

通过使用纹理坐标,我们会从纹理采样体素。启用点过滤时,在两个体素之间采样会导致只有其中一个体素被采样。

由于启用了双线性过滤,GPU会线性混合两个体素,返回两个体素的平均值。如果我们添加额外的半像素偏移,我们能够以一个像素的开销采样两个像素。

减少算术逻辑单元指令

Unity不支持通用边界纹理包装模式,因此我们必须给模糊着色器添加逻辑,使它检查当前体素是否是边界体素,如果是的话,使它保持清晰效果。这样可以避免阴影在接收平面上变得模糊不清。

着色器代码使用内在函数Step来计算当前体素是否是边界体素。固有函数Step类似if语句,我通过调整这部分代码,使它改为使用floor函数,这样使算术逻辑单元数量从13减少为9。虽然看似不多,但在渲染纹理中对每个像素这样做时,优化效果会逐渐积累。

在编写着色器时,我们可以观察Unity的检视窗口。在检视窗口中,选中着色器时,单击“Compile and show code”按钮。这样会编译着色器代码,并在文本编辑器中打开它。

在编译后的着色器代码顶部,我们会看到着色器使用了多少算术逻辑单元和Tex指令。

// 统计:5次数学运算,5个纹理
Shader Disassembly:
#version 100

#ifdef VERTEX

如果想要更多信息,我们可以下载并使用Mali Offline Shader Compiler。只需复制编译后的着色器代码,即#if VERTEX或#if FRAGMENT下的代码,把它保存到.vert或.frag格式的文件中即可。

我们可以通过编译器运行文件,它会展示我们着色器的统计信息。

malisc --vertex myshader.vert malisc --fragment myshader.frag
[转载]Unity中的阴影优化插图4

从上图中,我们发现名为5Tap的模糊着色器使用了:

  • 2个算术逻辑单元指令
  • 3个读取/存储指令
  • 5个纹理指令

OnRenderImage函数

在模糊通道的结尾,我们发现还有一个额外的Blit函数,它会复制模糊纹理到另一个渲染目标。经过研究发现,即使我们指定模糊的渲染纹理为R8格式,它的格式依旧为R8G8B8A8,其实这是一个Bug。

OnRenderImage会传递32位的目标纹理,然后它的数值会复制到最终目标格式。这样是无法接受的,因此我们对管线进行了修改。

我们现在会手动分配渲染纹理,在OnPostRender函数中执行模糊过程。

private void OnPostRender()
{
    if (shadowQuality != ShadowQuality.Hard)
    {
        SetupBlurMaterial();
        blurTex.DiscardContents();
        Graphics.Blit(shadowTex, blurTex, blurMat, 0);
    }
}

深度缓冲区

如果我们非常希望节省内存,可以禁用深度缓冲区,但这意味着色调的Overdraw增多。

如果我们清楚这对阴影贴图渲染目标产生什么影响,而且知道这不会产生过多Overdraw,那么可以考虑禁用深度缓冲区。

但是一定记得进行性能分析,并在禁用前确定自己是否真的很想要这些额外的几千字节空间。

性能指标

我们可以看到本文示例项目中渲染单个阴影贴图的开销。通过使用XCode GPU Frame Debugger对iPhone 6s进行测试,我们得到了下面的数据。

[转载]Unity中的阴影优化插图5

我们发现,渲染该阴影贴图的开销和原始开销相比,减少了50%。由于减少渲染目标的大小,使用较小纹理格式,去掉不必要的Blit函数,并且可以不使用深度缓冲区。

我们的内存消耗量从320kb减少为8kb,使用16位深度缓冲区会使内存消耗量变为16kb,节省了大量带宽。

小结

在最佳情况下,我们可以减少超过40倍的内存消耗和带宽使用量,还可以将阴影系统的整体开销降低50%以上。

这样的优化效果不意味着我们可以拥有两倍数量的阴影。所以我们花了2~3天进行性能分析,优化和修改,这些时间都是值得的。


版权所有:Unity China 原文地址:Unity中的阴影优化

]]>
https://xians.me/88/feed/ 0