Unite Beijing 2018: Part 1

This article contains AI-generated translation.

 Author
 Next

我们已经发布了Unite 2018 江毅冰的《发条乐师》、Hit-Point的《旅行青蛙》、育碧《Eagle Flight》演讲分享，不少开发者在后台留言希望小编尽快分享米哈游技术总监贺甲《崩坏3》的案例分享，因为这场是干货满满的爆场。我们非常感谢米哈游以及贺甲长期以来对Unite大会的支持，由于篇幅限制，本次演讲内容将拆分成上下二篇。
We have already released the presentations from Unite 2018, including Jiang Yibing's *Clockwork Maestro*, Hit-Point's *Traveling Frog*, and Ubisoft's *Eagle Flight*. Many developers backstage have left messages hoping that we can share the case study of miHoYo's Technical Director, He Jia, on *Honkai Impact 3rd* as soon as possible, as it is a highly informative and exciting session. We are very grateful for miHoYo's and He Jia's long-term support for the Unite conference. Due to space limitations, this presentation will be divided into two parts.

下面为演讲内容：
Now, let's move on to the content of the presentation:

大家好，欢迎来到Unite2018参加我们这次演讲。简单做一下自我介绍，我叫贺甲，目前在米哈游担任技术总监。我和我的团队主要关注在PBR和NPR方面的实时渲染，以及用于动画CG和游戏的过程动画和交互式物理的研究。目前，我们的一部分工作是利用Unity实现高品质的卡通渲染。
Hello, everyone. Welcome to Unite 2018 and our session. Let me briefly introduce myself. My name is He Jia, and I am currently serving as the Technical Director at miHoYo. My team and I focus on real-time rendering in PBR and NPR, as well as research on procedural animation and interactive physics for animation CG and games. Currently, a part of our work involves using Unity to achieve high-quality cartoon rendering.

这次演讲的主题是《在Unity上实现高品质卡通渲染的效果》，这些方法的实现针对各个平台的特性进行了优化，涵盖了从移动端，到高性能PC等不同等级的平台。
The theme of this presentation is "Achieving High-Quality Cartoon Rendering Effects in Unity." The implementation of these methods has been optimized for various platforms, covering different levels of devices, from mobile to high-performance PCs.

我们先来简要介绍一下本次演讲涉及到的主要方面。首先会介绍一些应用在移动端有关《崩坏3》的渲染特性。然后我会谈谈动画风格CG渲染中使用的一些技术，例如：插画风格的角色渲染、特殊材质的渲染、特效的渲染及与卡通渲染适配的后期处理等。最后一部分是关于一些杂项和对今后实现的一些展望。
Let's provide a brief overview of the main aspects covered in this presentation. First, we will introduce some rendering features related to *Honkai Impact 3rd* on mobile devices. Then, I will talk about some techniques used in animation-style CG rendering, such as rendering characters in an illustration style, rendering special materials, rendering effects, and post-processing for adapting to cartoon rendering. Finally, the last part will cover some miscellaneous topics and prospects for future implementations.

首先，我们来看看在《崩坏3》的场景中使用的一些渲染特性。
First, let's take a look at some of the rendering features used in the scenes of *Honkai Impact 3rd*.

从下图中我们可以看出，场景中使用了不少特效来提升表现力。例如：bloom后处理效果、动态粒子、平面反射、屏幕扭曲特效等。下面我们将会逐一对这些效果进行解析。
From the image below, we can see that various effects are employed in the scenes to enhance visual expression. These include bloom post-processing effects, dynamic particles, planar reflections, screen distortion effects, and more. Now, let's analyze each of these effects one by one.

下面展示了这些动态特效。
Below are demonstrations of these dynamic effects.

我们来看一下如何实现高品质的反射效果。
Next, let's explore how to achieve high-quality reflection effects.

在移动端实现高品质的反射，平面反射是一个综合了效果和性能因素较好的办法。通常做法是以地面为对称平面，将摄像机放置在对称位置后渲染场景得到反射结果。
On mobile devices, planar reflection is a well-balanced approach that combines both visual quality and performance factors. Typically, the ground is used as the reflective plane, and the scene is rendered from a symmetrical position with the camera to obtain the reflection result.

为了能表现出地面的金属质感，首先我们对反射结果应用六边形采样模糊，然后使用金属纹理细节法线贴图来扰动反射结果，除此之外我们还使用了镜面反射贴图和菲涅尔效果来进一步增强反射质感。在一些远离地面高度或非水平的次要反射表面上，平面反射就不在适用，为此我们使用环境贴图反射作为替代方案。
To depict a metallic appearance on the ground, we first apply hexagonal sampling blurs to the reflection result. Then, we use metal texture detail normal maps to perturb the reflection result, enhancing the reflection quality. Additionally, mirror reflection maps and Fresnel effects are utilized to further enhance the reflective appearance. However, for surfaces located far from the ground or those with non-horizontal orientations, planar reflections might not be suitable. In such cases, we resort to using environment map reflections as an alternative solution.

为了尽量减少渲染反射场景所占用的开销，我们将反射分辨率限制在1/3以下，由于反射贴图会经过模糊处理， 即使降低了较多的分辨率也并不能明显看出区别，并且我们在渲染反射的过程中还使用简化版的材质，并忽略一些不是很重要的小物体。
To minimize the rendering cost of reflection scenes, we limit the reflection resolution to below 1/3. Since the reflection textures undergo blur processing, a significant reduction in resolution is not visibly distinguishable. During the rendering of reflections, we also use simplified versions of materials and ignore some less important small objects.

接下来让我们看看另一个效果：全屏扭曲特效的应用。
Next, let's take a look at another effect: the application of full-screen distortion.

我们在《崩坏3》的场景中较多的使用了屏幕扭曲效果，比如：刀剑的拖尾特效，时空断裂效果，水流瀑布及其它场景效果。
In "Honkai Impact 3rd," we make extensive use of screen distortion effects, such as trailing effects for swords, space-time ruptures, flowing waterfalls, and other scene effects.

在渲染扭曲效果的过程中，我们使用3个通道来存储扭曲的渲染结果，2个用于存储UV偏移，另一个用于存储扭曲强度Mask，扭曲强度Mask用于执行深度剪裁和基于距离的强度控制。
When rendering distortion effects, we use three channels to store the rendered results: two for storing UV offsets and one for storing the distortion intensity mask. The distortion intensity mask is used for depth clipping and distance-based intensity control.

使用单独的Pass渲染扭曲结果到帧缓冲纹理对于移动平台来说开销较大，所以我们在最终的后处理中整合应用了扭曲效果，相比前者要快很多。 但这种方法也可能导致靠前面的物体由于没有分层处理而混入后面扭曲材质的问题，不过考虑到移动平台的性能限制，相对于整体效果而言这种妥协是值得的。
Rendering distortion results to frame buffer textures in a separate pass would be too costly for mobile platforms. Therefore, we integrate and apply the distortion effect in the final post-processing, which is much faster compared to the former approach. However, this method may lead to an issue where objects closer to the camera get mixed with the distorted material in the background due to the lack of layering. Nevertheless, considering the performance limitations of mobile platforms, this compromise is worthwhile for the overall effect.

接下来让我们看看bloom的实现，整个场景如果开启HDR会使用 fp16格式的Render target，然后下采样到原始大小的1/4大小以便之后的后处理流程使用。
Now, let's take a look at the implementation of bloom. If the entire scene is set to HDR, we use the FP16 format for the render target and downsample it to 1/4 of the original size for subsequent post-processing steps.

首先，我们需要指定一个亮度阈值来提取图像中的高亮区域，实现方法也并不复杂，只需从源像素减去阈值，得到的结构就是提取后的高亮度区域，叠加这层内容能使结果看起来更具对比并且色彩鲜艳。接下来，我们产生4个大小依次递半的Render target，并将其内容应用半径逐渐增大的高斯模糊。最后我们将这些模糊后的结果合并起来，以获得最终的bloom效果。
Firstly, we need to specify a brightness threshold to extract the highlighted areas in the image. The method is not complex; we simply subtract the threshold value from the source pixel to obtain the extracted highlighted region. Overlaying this layer enhances the contrast and color vibrancy of the result. Next, we generate four Render targets of gradually halving sizes and apply Gaussian blur with increasing radii to each of them. Finally, we combine these blurred results to achieve the final bloom effect.

从下面最终的效果图我们可以看到，bloom效果不仅起到用来表达高亮区域的视觉效果，还对整个图像的色彩中起着明显的润色作用。
From the final result image below, we can see that the bloom effect not only visually represents the highlighted areas but also significantly enhances the overall color of the image.

当完成了反射渲染，扭曲效果的及bloom 的处理后，最终就可以将这些中间结果合成在一起。我们使用filmic tone mapping与曝光和对比度控制来将fp16 HDR的原图像转换为最终的LDR帧缓冲。由于这些合成操作都是在一个Pass中完成的，所以即使在移动设备上也可以满足性能方面的需求。
After completing the rendering of reflections, distortion effects, and bloom processing, the intermediate results can be composited together. We use filmic tone mapping, exposure, and contrast control to convert the FP16 HDR original image into the final LDR frame buffer. Since these compositing operations are done in a single pass, they meet the performance requirements even on mobile devices.

下面我们来介绍一下游戏中的天气和云海的实现。
Next, let's introduce the implementation of weather and cloud systems in the game.

我们想要创造一个能让玩家感受到纵深，具有各种丰富形态以及动态光照变化的云的渲染系统。而该系统也应该易于调整和使用，方便美术可以创造出不同类型的云层效果。这对我们来说也是一个有趣的挑战，接下来就让我们来谈谈这些功能。
We aim to create a rendering system for clouds that provides players with a sense of depth, rich morphological variations, and dynamic lighting changes. The system should also be easy to adjust and use, allowing artists to create different types of cloud effects. This presents an interesting challenge for us, so let's discuss these functionalities.

首先让我们看看渲染云所需要的资源，因为我们想要实现可以24小时动态变化的风格化云的光照效果，如果直接存储画好的贴图数量就会太大而且不方便调整，所以我们使用多层着色来实现这一点。
First, let's take a look at the resources required to render clouds. Since we want to achieve stylized clouds with dynamic lighting effects that change throughout the day, storing a large number of pre-rendered textures would be impractical and cumbersome to adjust. Therefore, we use a multi-layer shading approach to achieve this.

我们使用4个通道来表示云的光照及阴影：基础照明层，阴影1层，阴影2层，和边缘光层，通过为每个图层设置不同的颜色，我们就可以获得不同时刻的云的色彩方案。我们一共准备了8种形状不同的云的模板，用来构建各种不同的云海景观。
We use four channels to represent the lighting and shadows of the clouds: the base lighting layer, shadow layer 1, shadow layer 2, and edge light layer. By setting different colors for each layer, we can obtain various color schemes for the clouds at different times. We have prepared a total of 8 templates for clouds with different shapes to create various cloudscapes.

为了构建云海景观，我们使用了很多朝向屏幕发射云朵的粒子发射器，并且使用不同的云的模板以及发射模式来组合出不同的云海景观，我们实现了各种类型的云海以及暴风雨天气等，这些预设都保存在天气配置中。此外我们还使用关键帧来定义天空背景和云彩的颜色。随着时间的流逝，云的色彩就根据关键帧来变化。
To construct cloudscapes, we use multiple particle emitters that emit clouds towards the screen, combining different cloud templates and emission modes to create diverse cloudscapes, including various types of cloud seas and stormy weather. These presets are saved in the weather configurations. Additionally, we use keyframes to define the colors of the sky background and clouds. As time progresses, the colors of the clouds change based on the keyframes.

在性能方面主要的开销是Overdraw问题，如果我们按照固定控制的Pattern来发射云虽然可以以最小的Overdraw来获得较好的云海密度，但可能会看起来较为重复，加入产生位置的随机因素可以解决这个问题，但要想获得看起来不那么稀疏的云海效果就需要相比固定Pattern更多的粒子数量，我们对于粒子发射配置都有细致的参数可以调整，以便在二者之间可以找到较好的权衡点。
In terms of performance, the main concern is overdraw. If we emit clouds with a fixed pattern, we can achieve a better cloud density with minimal overdraw. However, it might look repetitive. Introducing random factors in the emission positions can solve this issue, but to achieve a less sparse-looking cloudscape, more particles are needed compared to a fixed pattern. We have detailed parameters to adjust the particle emission configuration, allowing us to find a good balance between these two approaches.

这是一个24小时昼夜变化的云海景观。
This is a cloudscape with a 24-hour day-night cycle.

这是另一种云海景观的昼夜变化。
Here is another cloudscape with a day-night cycle.

这是暴风云闪电的场景。
This scene showcases storm clouds and lightning.

现在让我们来看看游戏场景中使用的天气系统。
Now, let's take a look at the weather system used in the game.

我们主要通过全局雾效，Skybox颜色和方向光的设置来改变场景的天气和氛围。对于雾效同样有许多参数可以调整。我们给雾效基于深度划分为远近距离二个区间，远近区间都可以设置不同的颜色和强度值来创造各种各样的气氛。Skybox也可以控制天空颜色渐变，云的受光及阴影颜色等。综合上述调整选项，我们就可以创建 晴天，雨天和大雾，多云和夜间等天气。
We mainly change the weather and atmosphere of the scene through global fog, Skybox color, and directional light settings. There are also many parameters to adjust the fog effect. We divide the fog into two regions based on depth: the near and far distances. Both regions can have different colors and intensity values to create various atmospheres. The Skybox controls the sky color gradient, cloud lighting, and shadow colors. By combining these adjustment options, we can create weather conditions such as sunny, rainy, foggy, cloudy, and nighttime.

另外人物的光照也会受环境的影响，主要的光照颜色由方向光决定，局部区的阴影的变化，比如：角色走进阴影区域，由一些从关卡编辑器中手工放置的Lighting volume定义。
Furthermore, character lighting is also influenced by the environment. The main lighting color is determined by the directional light, and variations in local shadowing are defined, for example, when a character walks into a shadow area, by manually placed Lighting volumes in the level editor.

让我们再来看看游戏中使用景深的情况。
Now, let's take a look at the usage of depth of field in the game.

移动游戏中使用景深一般并不常见，因为常见的景深实现对于移动平台来讲还是开销较大，我们主要在人物选择界面和任务简报会话中使用景深效果来突出表现人物。
Depth of field is not commonly used in mobile games because typical depth of field implementations can be costly for mobile platforms. However, we use depth of field effects to highlight characters in the character selection interface and mission briefing conversations.

由于这些场景不需要景深的过度，我们使用一种特殊的方法来进提高移动性能。不使用depth buffer做COC混合，而是使用单独的相机直接绘制背景图层。在应用模糊通过后，通过将背景和前景人物组合在一起来获得最终图像。
To improve mobile performance, we use a special method that avoids using the depth buffer for CoC blending. Instead, we directly render the background layer using a separate camera. After applying the blur pass, we combine the background with the foreground characters to obtain the final image.

为了得到更好的视觉效果，我们使用六边形采样模式来获得更好的bokeh形状。除此之外还有bokeh强度调整参数，以使其看起来更清晰，我们使用亮度值作为增量因子，2通常是一个合适的值。
To achieve a better visual effect, we use hexagonal sampling to obtain improved bokeh shapes. Additionally, we have parameters to adjust the bokeh intensity, making it look clearer. We use the brightness value as an incremental factor, and 2 is often a suitable value.

性能方面为了保持性能的稳定，我们模糊背景的分辨率视模糊程度而定，更大的模糊尺寸使用更低的分辨率并且更不容易察觉，我们还使用Unity内置的曲线来描述它们之间的转换关系。
In terms of performance, to maintain stability, we adjust the resolution of the blurred background based on the blur intensity. Larger blur sizes use lower resolutions and are less noticeable. We also use Unity's built-in curves to describe the transition relationship between different blur sizes.

下图展示了动态调整模糊大小和焦散强度的结果。
The image below demonstrates the dynamic adjustment of blur size and defocus intensity.

在游戏场景中，我们还实现了一个看起来挺酷的效果，当给最后一个敌人致命一击的时候就会激发子弹时间，这时所有高速运动的物体都会慢下来，在下雨天我们就可以明确的看到雨滴的形状。
In the game scenes, we have also implemented a visually appealing effect where triggering a fatal blow on the last enemy activates bullet time. During bullet time, all fast-moving objects slow down, allowing us to clearly see the shape of raindrops on a rainy day.

为了实现这个效果，我们使用了4个代表雨滴不同速度下形态的关键帧，再根据时间快慢尺度对其进行垂直拉伸。 在正常的时间尺度下，雨滴看起来像一条直线，在时间变慢的时候逐渐缩短变成雨滴形状。在这里我们同样使用了动画曲线来控制拉伸，关键帧选择和时间快慢的关系，调整起来非常灵活方便。
To achieve this effect, we used four keyframes representing the different shapes of raindrops at various speeds. Then, based on the time scale, we vertically stretched the raindrop shapes. At normal time scale, the raindrops appear as straight lines, but as time slows down, they gradually shorten and transform into raindrop shapes. We also utilized animation curves to control the stretching, keyframe selection, and the relationship between time scale and stretching, making it flexible and convenient to adjust.

刚才我们谈到的都是一些针对移动端优化的渲染功能，下面我们来介绍一下用于动画风格real-time CG或次世代游戏的渲染方法。
So far, we have discussed various rendering optimizations for mobile platforms. Now, let's introduce rendering methods used for animation-style real-time CG or next-gen games.

在过去的二年中，我们陆续制作了二个短视频，其中体现了我们的新渲染风格。
In the past two years, we have produced two short videos showcasing our new rendering style.

B站视频地址：https://www.bilibili.com/video/av14260225
Bilibili video link: (link provided)

我们将它发布在了B站上，3天内获得了B站全站月榜排行第一的位置，至今已有超过300万的点击量。
We uploaded it to Bilibili and within three days, it secured the top position in Bilibili's monthly rankings, with over 3 million views to date.

B站视频地址：https://www.bilibili.com/video/av7244731
Bilibili video link: (link provided)

下面我们就来谈谈这些视频中应用到的一些实时渲染CG技术。
Now, let's discuss some real-time rendering CG techniques applied in these videos.

首先我们来看看角色的渲染，我们的目标是实现完全动态的光照和阴影，所有材质都对各种光照现象做出正确的反应，包括主光源和区域环境光。这就要求我们不能使用任何在纹理上画死的光照表现。
Firstly, let's take a look at character rendering. Our goal is to achieve fully dynamic lighting and shadows, where all materials respond correctly to various lighting phenomena, including the main light source and area ambient light. This means we cannot use any fixed lighting effects painted on textures.

用于角色渲染的主要特性有：多通道Ramp的材质Shading方法，眼睛，头发和其它各向异性材料等特殊材料的处理，以及PCSS角色软阴影和高品质的勾线。
The main features used for character rendering are: multi-channel Ramp material shading method, special materials for eyes, hair, and other anisotropic materials, PCSS character soft shadows, and high-quality outlines.

首先我们来看一下多通道Ramp的Shading方法。
Let's start by examining the multi-channel Ramp shading method.

我们希望角色的阴影和颜色的变化可以表现出更细腻的插画风格，所以我们使用2D ramp纹理来表示这些细微的变化，其中RGB通道分辨用于描述于不同阴影层的漫射阴影范围。每个层都可以制定不同的颜色，这样就能在明暗变化中做到精细的色彩变化控制。
We aim to present more delicate illustration-style shadows and color variations for characters. To achieve this, we use 2D ramp textures to represent these subtle changes. The RGB channels are used to describe the diffuse shadow range at different shadow layers. Each layer can have different colors, allowing precise color variation control in light and dark areas.

对于卡通风格的画面，如果上色只是纯明暗变化，阴影处就会显得比较脏，缺乏表现力，而如果提升暗处的饱和度和色相变化，整体色彩看起来就会比较鲜活。而且通过调整垂直纹理采样坐标，我们可以实现动态的软硬风格转换。 从另一角度来看这种方法还间接表现了皮肤的次表面散射效果。
For a cartoon-style image, if coloring is solely based on brightness variations, shadows can appear dirty and lack expressiveness. By increasing the saturation and hue variations in the shadows, the overall colors look more vibrant. Additionally, by adjusting the vertical texture sampling coordinates, we can achieve dynamic transitions between soft and hard styles. From another perspective, this method indirectly simulates the subsurface scattering effect of the skin.

下面四幅图展示了多通道逐层上色叠加的效果。 大家可以看到通过一层层的上色叠加，皮肤层次细节会变得更加丰富。
The following four images showcase the effect of layer-by-layer color overlay using multi-channel shading. As you can see, with each layer of color overlay, the skin's level of detail becomes more enriched.

上下二副图分别展示了采样不同位置的ramp texture所对应的渲染效果，不同的ramp可以获得各种不同的上色风格。使用hard ramp比较接近Cel-shading，soft ramp则是类似与插画柔和的阴影层次变化。
The top and bottom two images display the rendering results corresponding to different positions of the sampled ramp texture. Different ramps can achieve various coloring styles. Using a hard ramp produces an effect similar to Cel-shading, while a soft ramp creates a smooth and subtle shading transition, akin to illustrations.

由于我们使用了2D的ramp纹理，它们之间的变化是可以动态调整的，我们可以使用ramp mask纹理来选择每像素的ramp软硬以实现插画的手绘风格。这个ramp mask纹理可以由美术直接在模型上进行绘制。我们在Unity下有一个3D paint工具，使用起来较为直观。
Since we use 2D ramp textures, their variations can be dynamically adjusted. We can employ a ramp mask texture to choose the softness or hardness of each pixel's ramp, achieving a hand-painted illustration style. Artists can directly paint on the model using this ramp mask texture. In Unity, we have a 3D paint tool that is relatively intuitive to use.

插画风格渲染的另一个重要因素是使用纹理笔触。我们可以使用不同的笔触纹理图案以获得不同的着色风格。对于每个笔刷纹理，我们有4个通道可以存储代表不同方向的笔刷图案，混合使用这些笔刷可以获得更丰富的笔刷变化。右边的二张对比图中，使用笔触纹理的有着更多手绘的感觉。
Another crucial element in illustration-style rendering is using texture brushes. Different brush texture patterns can yield diverse coloring styles. For each brush texture, we have four channels to store patterns representing different directions, and combining these brushes allows for richer brush variations. In the comparison images on the right, the use of texture brushes provides a more hand-drawn feeling.

下图显示了应用了带有笔触风格的皮肤材质对不同光照角度的渲染结果。
The following image displays the rendering results of the skin material with brush style under different lighting angles.

接下来让我们看看如何实现高质量的边缘光。
Next, let's explore how to achieve high-quality rim lighting.

同样是基于菲涅尔方法，我们有参数来控制它，比如：边缘宽度和平滑度；除了这些全局控制参数之外，我们也使用笔刷纹理来增加一些局部变化。我们定义边缘光既可以来自于方向光源也可以来自于环境贴图，使用方向光我们可以按需求定义边缘光，使用环境贴图，我们可以根据环境光照来获得边缘光以显得更真实，二者都比较有用，可以结合使用。
Similarly, based on the Phong shading model, we have parameters to control it, such as edge width and smoothness. In addition to these global control parameters, we also use brush textures to introduce some local variations. We define that rim lighting can come from either the directional light source or the environment map. Using the directional light, we can define rim lighting as needed, while using the environment map allows us to obtain rim lighting based on ambient lighting for a more realistic effect. Both methods are valuable and can be combined.

为避免边边缘光出现在不需要的区域，我们使用AO纹理和shadowmap来频闭掉遮挡区域。我们可以看到，对比图中左边带有边缘光的形状显得效果更突出。
To prevent rim lighting from appearing in undesired areas, we use the Ambient Occlusion (AO) texture and shadow map to occlude the blocking areas. As seen in the comparison images, the shape with rim lighting on the left appears more prominent.

卡通风格对于面部一般不会有太多阴影层次的变化，如果我们直接套用之前的ramp方法应用在脸部，效果就会像右侧的图看起来一样不自然，为了改善这种情况我们使用顶点色的一个通道作为mask来控制脸部的上色层的强弱，通过压低漫反射表现来达到想要的卡通效果。
For cartoon-style faces, there are generally not many variations in shading levels. If we directly apply the previous ramp method to the face, the result might look unnatural, as seen in the image on the right. To improve this, we use one channel of vertex color as a mask to control the strength of the coloring layer on the face. This helps achieve the desired cartoon effect by reducing the diffuse reflection representation.

接下来我们来说一下高质量角色软阴影的实现。
Next, let's discuss the implementation of high-quality soft shadows for characters.

如果我们直接使用Unity内置的CSM阴影，在镜头靠近角色的时候阴影品质并不能满足需求，所以我们就为角色单独渲染了一张shadowmap，以确保恒定的阴影品质。为此我们还实现了基于视锥的shadowmap，根据角色的boundingbox和视锥求交集部分，以此作为渲染区域。就可以最大化阴影贴图的使用率，
If we directly use Unity's built-in Cascaded Shadow Maps (CSM), the shadow quality might not meet our needs when the camera is close to the character. Therefore, we render a separate shadow map specifically for the character to ensure consistent shadow quality. For this purpose, we have implemented a view frustum-based shadow map that calculates the intersection between the character's bounding box and the view frustum, using it as the rendering area. This maximizes the utilization of the shadow map.

此外还使用了Variance shadow map以及PCSS来减少阴影瑕疵以及获得自然的软阴影效果。另外，如果要实现正确的透明材质阴影，还需要额外的通道根据材质的透明度来存储阴影强度。我们可以从实例图片中看到半透明的裙子可以投射出自然的阴影。
Additionally, we use Variance Shadow Maps and Percentage Closer Soft Shadows (PCSS) to reduce shadow artifacts and achieve natural soft shadow effects. Moreover, to achieve correct shadowing for transparent materials, we need additional channels to store shadow intensity based on the material's transparency. From the example images, we can see that the semi-transparent skirt can cast natural shadows.

眼睛的处理我们使用了基于物理的折射计算。普通卡通模型处理眼部的做法通常是把眼白留空，瞳孔凹陷下去，这样在侧面的时候也不会鼓出来显得比较自然，然而如果要做眼部近距离特写，这种做法看上去就不能令人信服。使用真实折射算法，眼球本身还是按照球面来做，然后根据视线角度算出折射系数去偏移查找贴图对应点 。
For the eyes, we used physics-based refraction calculations. The conventional approach for cartoon eye modeling is to leave the sclera empty and sink the pupils, which looks natural from the side. However, this method might not be convincing for close-up shots of the eyes. By using real refraction algorithms, the eyeball is still modeled as a sphere, and the refraction index is calculated based on the viewing angle to offset and look up the corresponding points in the texture.

下面对比图显示了有无折射的实际效果， 我们可以看到，如果没有折射效果，眼部侧面看上去较为奇怪。
The comparison images below show the actual effect with and without refraction. As we can see, without refraction, the eyes look odd from the side.

此外我们还加入了光线折射后的焦散光效果，使得眼睛的质感得到进一步增强。对于非写实风格渲染，物理正确并不是要考虑的因素，由于卡通渲染的特殊情况，我们希望的焦散效果出现在入射光线的另一侧，并且入射角度越平行看起来越明显。
Additionally, we added the effect of caustics after light refraction, further enhancing the eye's texture. For non-photorealistic rendering, physical accuracy is not a consideration. Due to the special nature of cartoon rendering, we wanted the caustic effect to appear on the opposite side of the incident light and become more apparent as the incident angle approaches parallel.

实现方法是通过入射光和眼球前向的夹角算出入射光强度，这里我们使用inverse diffuse来模拟，再辅助fresnel公式做亮度变化，最后乘上eye caustic纹理得到最终效果。
The implementation method calculates the incident light intensity based on the angle between the incident light and the forward direction of the eyeball. We use inverse diffuse to simulate this, followed by adjusting the brightness using the Fresnel equation, and finally multiplying it with the eye caustic texture to achieve the desired effect.

通过下面对比图我们可以看到如果没有焦散效果眼睛就显得暗淡无光缺乏质感。
From the comparison images below, we can see that without the caustic effect, the eyes appear dull and lack luster.

下图展示了眼睛的折射以及头发的各向异性高光效果。
The image displays the eye's refraction and the anisotropic specular highlight effect on the hair.