zoukankan      html  css  js  c++  java
  • Unity shader学习之卡通渲染,轮廓线

    效果如下(头部无轮廓):

    原理:使用2个pass来渲染。

    第一个pass中,使用轮廓线颜色渲染整个背面,并在视角空间下把模型顶点沿着法线方法向外扩张一段距离,来让轮廓线可见,公式为:

    viewPos += viewNormal * _Outline;

    注意:如果直接使用顶点法线进行扩展,对于一些内凹的模型,就可能发生背面面片遮挡正面面片的情况。为了尽可能防止出现这样的情况,在扩张背面顶点之前,我们首先对顶点法线的z分量进行处理,使它们等于一个定值,然后把法线归一化后再对顶点进行扩张。这样的好处在于,扩展后的背面更加扁平化,从而降低了遮挡正面面片的可能性。代码如下:

    viewNormal.z = -0.5;

    viewNormal = normalize(viewNormal);

    viewPos += viewNormal * _Outline;

    第二个pass中,正常渲染物体。

    参考shader代码如下:

      1 Shader "America/Character/America-Diffuse-AlphaTest-Face"
      2 {
      3     Properties
      4     {
      5         _Color ("Main Color", Color) = (1,1,1,1)
      6         _MainTex ("Base (RGB)", 2D) = "white" {}
      7         _NormalMap("Normal Map", 2D) = "bump" {}
      8 
      9         _DiffuseRate ("Diffuse Rate", float) = 2
     10         _Ramp ("Toon Ramp (RGB)", 2D) = "gray" {}
     11         _RampRate ("Ramp Rate", float) = 1
     12 
     13         _OverlyingColor("Overlying Color", Color) = (0.5, 0.5, 0.5, 1)
     14 
     15     }
     16 
     17     SubShader
     18     {
     19         Tags 
     20         {
     21             "RenderType" = "Transparent"
     22             "IgnoreProjector" = "True"
     23             "Queue" = "Transparent+100"
     24         }
     25         LOD 200
     26         
     27         
     28         Pass
     29         {
     30             NAME "OUTLINE"
     31 
     32             Cull Front
     33 
     34             CGPROGRAM
     35             #pragma vertex vert
     36             #pragma fragment frag
     37 
     38             struct appdata
     39             {
     40                 float4 vertex : POSITION;
     41                 float4 normal : NORMAL;
     42             };
     43 
     44             struct v2f
     45             {
     46                 float4 pos : SV_POSITION;
     47             };
     48 
     49             v2f vert(appdata v)
     50             {
     51                 v2f o;
     52 
     53                 float4 viewPos = mul(UNITY_MATRIX_MV, v.vertex);
     54                 float4 viewNormal = mul(UNITY_MATRIX_IT_MV, v.normal);
     55 
     56                 viewNormal.z = -0.5;
     57                 o.pos = mul(UNITY_MATRIX_P, viewPos + normalize(viewNormal) * 0.01);
     58 
     59                 return o;
     60             };
     61 
     62             float4 frag(v2f i) : SV_TARGET
     63             {
     64                 return float4(0, 0, 0, 1);
     65             };
     66 
     67             ENDCG
     68         }
     69 
     70         Pass
     71         {
     72             Tags
     73             {
     74                 "LightMode" = "ForwardBase"
     75             }
     76             Cull Off
     77 
     78             CGPROGRAM
     79             #pragma vertex vert
     80             #pragma fragment frag
     81             #pragma multi_compile_fwdbase
     82 
     83             #include "UnityCG.cginc"
     84             #include "AutoLight.cginc"
     85             #include "Lighting.cginc"
     86 
     87             #include "../AmericaCG.cginc"
     88 
     89             fixed4 _Color;
     90             sampler2D _MainTex;
     91             sampler2D _NormalMap;
     92             float _DiffuseRate;
     93             sampler2D _Ramp;
     94             float _RampRate;
     95             fixed4 _OverlyingColor;
     96 
     97             struct appdata
     98             {
     99                 float4 vertex : POSITION;
    100                 float2 uv : TEXCOORD0;
    101                 float3 normal : NORMAL;
    102                 float4 tangent : TANGENT;
    103             };
    104 
    105             struct v2f
    106             {
    107                 float4 pos : SV_POSITION;
    108                 float2 uv : TEXCOORD0;
    109                 float4 T2W1 : TEXCOORD1;
    110                 float4 T2W2 : TEXCOORD2;
    111                 float4 T2W3 : TEXCOORD3;
    112             };
    113 
    114             v2f vert(appdata v)
    115             {
    116                 v2f o;
    117                 o.pos = UnityObjectToClipPos(v.vertex);
    118                 o.uv = v.uv;
    119                 
    120                 float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
    121                 float3 worldNormal = UnityObjectToWorldNormal(v.normal);
    122                 float3 binormal = cross(normalize(worldNormal), normalize(worldTangent)) * v.tangent.w;
    123                 float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    124                 o.T2W1 = float4(worldTangent.x, binormal.x, worldNormal.x, worldPos.x);
    125                 o.T2W2 = float4(worldTangent.y, binormal.y, worldNormal.y, worldPos.y);
    126                 o.T2W3 = float4(worldTangent.z, binormal.z, worldNormal.z, worldPos.z);
    127                 return o;
    128             }
    129 
    130             fixed4 frag(v2f i) : SV_TARGET
    131             {
    132                 float3 worldPos = float3(i.T2W1.w, i.T2W2.w, i.T2W3.w);
    133                 float3 worldLight = normalize(UnityWorldSpaceLightDir(worldPos));
    134                 //float3 worldView = normalize(UnityWorldSpaceViewDir(worldPos));
    135                 float3 tangentNormal = UnpackNormal(tex2D(_NormalMap, i.uv));
    136                 float3x3 tanToWorld = float3x3(i.T2W1.xyz, i.T2W2.xyz, i.T2W3.xyz);
    137                 float3 worldNormal = mul(tanToWorld, tangentNormal);
    138                 
    139                 fixed4 albedo = tex2D(_MainTex, i.uv) * _Color;
    140                 fixed3 diffuse = CalcDiffuse(albedo, worldLight, worldNormal, _Ramp, _RampRate);
    141                 
    142                 fixed4 col = fixed4(diffuse * _DiffuseRate, albedo.a);
    143                 col.rgb = Overlay(col, _OverlyingColor);
    144 
    145                 return col;
    146             }
    147 
    148             ENDCG
    149         }
    150 
    151     } 
    152 
    153     Fallback "Diffuse"
    154 }

    转载请注明出处:https://www.cnblogs.com/jietian331/p/13633051.html

  • 相关阅读:
    《必须知道的.net》读后感 转
    Web Service
    设计模式
    对做“互联网产品”的一些想法
    四大发明之活字印刷——面向对象思想的胜利
    每个IT人都应当拥有的30条技能
    面向对象的本质是什么?
    数据库设计规范 zhuan
    翻动100万级的数据 —— 只需几十毫秒 转
    程序员发展十分重要的12条日常习惯
  • 原文地址:https://www.cnblogs.com/jietian331/p/13633051.html
Copyright © 2011-2022 走看看