过程式几何轮廓线渲染
这种方法的核心是使用两个Pass渲染,第一个Pass渲染背面的面片,第二个Pass正常渲染正面的面片.
在第一个Pass中,我们使用轮廓线颜色渲染整个背面的图片,并把模型顶点沿着法线方向向外扩张一段距离:
v.vertex.xyz += v.normal * _Outline;
首先创建着色器,添加必要的属性:
_MainTex ("Texture", 2D) = "white" {}_Diffuse ("Color",Color) = (1,1,1,1)_Outline("Outline",Range(0,1)) = 0.1_OutlineColor("OutlineColor",Color) = (0,0,0,0)
然后在第一个Pass通道里面添加对应属性的变量:
float _Outline;fixed4 _OutlineColor;
第一个Pass通道完整代码如下:
Pass{Name "Outline"Cull FrontCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"float _Outline;fixed4 _OutlineColor;struct v2f{float4 vertex:SV_POSITION;};v2f vert(appdata_base v){v2f o;//物体空间法线外拓v.vertex.xyz += v.normal * _Outline;o.vertex = UnityObjectToClipPos(v.vertex);//视角空间法线外拓//fixed4 pos = mul(UNITY_MATRIX_V,mul(unity_ObjectToWorld,v.vertex));//fixed3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV,v.normal));//pos = pos + fixed4(normal,0) * _Outline;//o.vertex = mul(UNITY_MATRIX_P,pos);//裁剪空间法线外拓 //o.vertex = UnityObjectToClipPos(v.vertex);//fixed3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV,v.normal));//float2 viewNormal = TransformViewToProjection(normal.xy);//o.vertex.xy += viewNormal * _Outline;return o;}fixed4 frag(v2f i) :SV_TARGET{return _OutlineColor;}ENDCG}
第二个Pass通道如下:
Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"struct v2f{float4 vertex: SV_POSITION;float2 uv : TEXCOORD0;fixed3 worldNormal:TEXCOORD1;float3 worldPos: TEXCOORD2;};sampler2D _MainTex;float4 _MainTex_ST;float4 _Diffuse;v2f vert (appdata_base v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld,v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Diffuse.rgb;fixed3 worldNormal = normalize(i.worldNormal);//漫反射fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);fixed halfLambert = dot(worldNormal,worldLightDir) * 0.5 + 0.5;fixed3 diffuse =_LightColor0.rgb * albedo * rampColor;//halfLambert;return fixed4(ambient + diffuse + rimColor,1);}ENDCG}
效果如下: