zoukankan      html  css  js  c++  java
  • 效果比较好的头发shader

    效果如下:

    渲染头发时可能会遇到如下问题:

    1. 因为头发本质上是一个一个的透明的面片,理所当然会想到使用 blend 混合方式来渲染。

    但当由于用 blend 时,要关闭Z缓存写,即执行 Zwirte Off,不然透明的区域也会遮挡后面的像素。

    此时就会出现问题,头发之间的层级会完全混乱,因为头发是多个面片穿插在一起的。

    2. 因此不能使用blend的方式,就只能使用 Alpha Test 的方式来强制丢弃透明的像素。

    但 Alpha Test 的问题的边缘部分不够平滑,剧齿感明显。

    解决此问题的思路是,一个通道执行 Alpha Test,把透明区域直接丢弃掉。

    另一个通道执行 Blend 混合,把 Alpha Test 丢弃的像素再重新渲染一遍。

    示例代码如下:

      1 Shader "Character/Example-Diffuse-Hair"
      2 {
      3     Properties
      4     {
      5         _Color ("Main Color", Color) = (1,1,1,1)
      6         _MainTex ("Base (RGB)", 2D) = "white" {}
      7         _Cutoff( "Cutoff", Range (0,1)) = 0.5
      8     }
      9 
     10     SubShader
     11     {
     12         Tags 
     13         {
     14             "RenderType" = "Transparent"
     15             "IgnoreProjector" = "True"
     16             "Queue" = "Transparent+100"
     17         }
     18         LOD 200
     19 
     20         Pass
     21         {
     22             Tags
     23             {
     24                 "LightMode" = "ForwardBase"
     25             }
     26             Blend SrcAlpha OneMinusSrcAlpha
     27             Cull Off
     28 
     29             CGPROGRAM
     30             #pragma vertex vert
     31             #pragma fragment frag
     32             #pragma multi_compile_fwdbase
     33 
     34             #include "UnityCG.cginc"
     35             #include "AutoLight.cginc"
     36             #include "Lighting.cginc"
     37 
     38             fixed4 _Color;
     39             sampler2D _MainTex;
     40             float _Cutoff;
     41             
     42             struct appdata
     43             {
     44                 float4 vertex : POSITION;
     45                 float2 uv : TEXCOORD0;
     46                 float3 normal : NORMAL;
     47             };
     48 
     49             struct v2f
     50             {
     51                 float4 pos : SV_POSITION;
     52                 float2 uv : TEXCOORD0;
     53                 float3 worldPos : TEXCOORD1;
     54                 float3 worldNormal : TEXCOORD2;
     55             };
     56 
     57             v2f vert(appdata v)
     58             {
     59                 v2f o;
     60                 o.pos = UnityObjectToClipPos(v.vertex);
     61                 o.uv = v.uv;
     62                 o.worldPos = mul(unity_ObjectToWorld, v.vertex);
     63                 o.worldNormal = UnityObjectToWorldNormal(v.normal);
     64                 return o;
     65             }
     66 
     67             fixed4 frag(v2f i) : SV_TARGET
     68             {
     69                 fixed4 albedo = tex2D(_MainTex, i.uv) * _Color;
     70                 clip(albedo.a - _Cutoff);
     71 
     72                 fixed3 ambient = albedo.rgb * UNITY_LIGHTMODEL_AMBIENT.rgb;
     73 
     74                 fixed3 worldLight = UnityWorldSpaceLightDir(i.worldPos);
     75                 float d = dot(worldLight, i.worldNormal) * 0.5 + 0.5;
     76                 fixed3 diffuse = albedo.rgb * _LightColor0.rgb * d;
     77                 
     78                 fixed4 col = fixed4(ambient + diffuse * 2, albedo.a);
     79 
     80                 return col;
     81             }
     82 
     83             ENDCG
     84         }
     85 
     86         Pass
     87         {
     88             Tags
     89             {
     90                 "LightMode" = "ForwardBase"
     91             }
     92             Blend SrcAlpha OneMinusSrcAlpha
     93             ZWrite Off
     94 
     95             CGPROGRAM
     96             #pragma vertex vert
     97             #pragma fragment frag
     98             #pragma multi_compile_fwdbase
     99 
    100             #include "UnityCG.cginc"
    101             #include "AutoLight.cginc"
    102             #include "Lighting.cginc"
    103 
    104             fixed4 _Color;
    105             sampler2D _MainTex;
    106             float _Cutoff;
    107             
    108             struct appdata
    109             {
    110                 float4 vertex : POSITION;
    111                 float2 uv : TEXCOORD0;
    112                 float3 normal : NORMAL;
    113             };
    114 
    115             struct v2f
    116             {
    117                 float4 pos : SV_POSITION;
    118                 float2 uv : TEXCOORD0;
    119                 float3 worldPos : TEXCOORD1;
    120                 float3 worldNormal : TEXCOORD2;
    121             };
    122 
    123             v2f vert(appdata v)
    124             {
    125                 v2f o;
    126                 o.pos = UnityObjectToClipPos(v.vertex);
    127                 o.uv = v.uv;
    128                 o.worldPos = mul(unity_ObjectToWorld, v.vertex);
    129                 o.worldNormal = UnityObjectToWorldNormal(v.normal);
    130                 return o;
    131             }
    132 
    133             fixed4 frag(v2f i) : SV_TARGET
    134             {
    135                 fixed4 albedo = tex2D(_MainTex, i.uv) * _Color;
    136                 clip(_Cutoff - albedo.a);
    137 
    138                 fixed3 ambient = albedo.rgb * UNITY_LIGHTMODEL_AMBIENT.rgb;
    139 
    140                 fixed3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos));
    141                 float d = dot(worldLight, i.worldNormal) * 0.5 + 0.5;
    142                 fixed3 diffuse = albedo.rgb * _LightColor0.rgb * d;
    143                 
    144                 fixed4 col = fixed4(ambient + diffuse * 2, albedo.a);
    145 
    146                 return col;
    147             }
    148 
    149             ENDCG
    150         }
    151         
    152         
    153     } 
    154 
    155     Fallback "Diffuse"
    156 }

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

  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——94
    《那些年啊,那些事——一个程序员的奋斗史》——95
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》前言
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》资源汇总
    《那些年啊,那些事——一个程序员的奋斗史》——96
    《玩转.NET Micro Framework 移植基于STM32F10x处理器》微软中国.NET Micro Framework项目组工程师所作之序
    《那些年啊,那些事——一个程序员的奋斗史》——91
    《那些年啊,那些事——一个程序员的奋斗史》——93
    分享多年美工工作收集的小工具和经验
    C# 3.0的一些新特性
  • 原文地址:https://www.cnblogs.com/jietian331/p/12621455.html
Copyright © 2011-2022 走看看