从半透明模型的描边到URP Multipass Rendering
请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com
卡通渲染技术中,描边的实现的有多种做法,有基于后处理实现,也有基于非后处理,通过多次绘制模型的方法实现。
通过多次绘制模型的实现,方法无非就是:
绘制模型本体,同时写入深度值。 让模型顶点沿着法线外扩一定的偏移量,即让模型膨胀一些 全用描边的颜色绘制膨胀过的模型,且,在绘制时,使用cull front,即只绘制模型的背向摄像机面。在第1步中因为绘制模型本体时已经写入深度值。在本步骤中只要不改变深度测试函数的方式,那么除了膨胀部分之外,是无法写入像素的,能写入的部分,便形成了边缘。 上述的方式,一般应用于不透明的材质上。如果是半透明的材质的话就有问题,因为在第1步绘制半透明材质时,一般是不写入深度值的。那么第3步在绘制膨胀模型时,模型背部的地方就会被绘制上去。
解决这个问题有很多,可以利用stencil test的方式。也可以在第一步绘制,不绘制任何颜色,只写入深度,然后再绘制模型,最后再绘制描边。后一种方法,如果用Unity内置管线,大约就是这个样子:
Shader "Unlit/半透明" { Properties { _Diffuse("Diffuse",Color) = (1,1,1,1) // 漫反射 _MainTex("MainTex",2D) = "white"{} // 2D纹理贴图 _AlphaScale("Alpha Scale",Range(0,1)) = 1 // 控制Alpha参数 } SubShader { Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } //渲染顺序设置Transparent LOD 100 // 用两个pass通道来处理,防止出现渲染错误,第一个pass通道 // 每个pass通道都会渲染一次 Pass { ZWrite On // 注意这里:写入深度 为了确认渲染顺序 ColorMask 0 // 掩码遮罩代表这个pass通道不写入任何颜色值 } Pass // 第二个pass通道 { Tags{"LightMode" = "ForwardBase"} ZWrite Off // 注意这里:关闭ZWrite(深度写入) Blend SrcAlpha OneMinusSrcAlpha // 源颜色因子 正常透明混合 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.