2013年10月22日 星期二

Toon Shader

參考
http://u16hp.blog134.fc2.com/page-2.html
的Shader

原來的效果可以找TMX Editor來看


Shader Code:
 Shader "Outlined/Diffuse" {  
      Properties {  
           _Color ("Main Color", Color) = (.5,.5,.5,1)  
           _OutlineColor ("Outline Color", Color) = (0,0,0,1)  
           _Outline ("Outline width",Float) = .005  
         _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)  
         _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0  
           _MainTex ("Base (RGB)", 2D) = "white" { }  
           _SpecTex ("Specular (RGB)", 2D) = "white" { }  
           _RampTex ("Ramp (RGB)", 2D) = "white" { }  
      }  
 CGINCLUDE  
 #include "UnityCG.cginc"  
 struct appdata {  
      float4 vertex : POSITION;  
      float3 normal : NORMAL;  
 };  
 struct v2f {  
      float4 pos : POSITION;  
      float4 color : COLOR;  
 };  
 uniform float _Outline;  
 uniform float4 _OutlineColor;  
 v2f vert(appdata v) {       
      v2f o;  
      o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
      float3 norm  = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);  
      float2 offset = TransformViewToProjection(norm.xy);  
      float viewScaler = (o.pos.z + 1) *0.5;  
      o.pos.xy += offset * viewScaler * _Outline;  
      o.color = _OutlineColor;  
      return o;  
 }  
 ENDCG  
      SubShader {  
      Tags { "RenderType"="Opaque" }  
 CGPROGRAM  
 #pragma surface surf Ramp vertex:myvert  
 #pragma target 3.0  
 sampler2D _MainTex;  
 sampler2D _RampTex;  
 sampler2D _SpecTex;  
 fixed4 _Color;  
 float4 _RimColor;  
 float _RimPower;  
 struct Input {  
      float2 uv_MainTex;  
      float3 Vnormal;  
 };  
 half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten) {  
      half NdotL = dot (s.Normal, lightDir);  
      half diff = max(NdotL,0); 
      half3 ramp = tex2D (_RampTex, float2(0,diff)).rgb;  
      half4 c;  
      // c.rgb = _LightColor0.rgb * ramp * (atten * 2);  
      c.rgb = s.Albedo * ramp;  
      c.a = s.Alpha;  
      return c;  
 }  
 void myvert (inout appdata_full v, out Input o) {  
      UNITY_INITIALIZE_OUTPUT(Input,o);  
      o.Vnormal = normalize(mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal));
    }  
 void surf (Input IN, inout SurfaceOutput o) {  
      fixed4 c = tex2D(_MainTex, IN.uv_MainTex)* _Color;  
      float2 specUV = float2(IN.Vnormal.x *0.5 +0.5, IN.Vnormal.y * 0.5 + 0.5);  
      fixed4 spec = tex2D(_SpecTex, specUV);  
   o.Emission = spec * _RimColor.rgb;  
      o.Albedo = c.rgb;  
      o.Alpha = c.a;  
 }  
 ENDCG  
           Pass {  
                Name "OUTLINE"  
                Tags { "LightMode" = "Always" }  
                Cull Front  
                //Cull off  
                ZWrite On  
                //ZTest Off  
                ColorMask RGB  
                Blend SrcAlpha OneMinusSrcAlpha  
                //Offset 20,20  
                CGPROGRAM  
                #pragma vertex vert  
                #pragma fragment frag  
                half4 frag(v2f i) :COLOR   
                {  
                 i.color.a = 0.5;  
                 return i.color;   
                }  
                ENDCG  
           }  
      }  
      Fallback "Diffuse"  
 }  
對描邊的效果還不大滿意
比較特別的是拿View Space的Normal x, y 當uv查一張貼圖做Rim Light的效果,這樣可以自己決定有漸層的顏色和Rim的範圍
For 3dsMax的(聽美術說有點問題,但還沒問是什麼問題 XD)
 // 3ds max effect file  
 // Simple Lighting Model  
 // This is used by 3dsmax to load the correct parser  
 string ParamID = "0x0000";  
 //DxMaterial specific   
 // light direction (view space)  
 float3 lightDir : Direction <   
      string UIName = "Light Direction";   
      string Object = "TargetLight";  
   string Space = "World";  
      //int refID = 0;  
      >;  
 // light intensity  
 float4 I_a = { 0.1f, 0.1f, 0.1f, 1.0f };  // ambient  
 float4 I_d = { 1.0f, 1.0f, 1.0f, 1.0f };  // diffuse  
 float4 I_s = { 1.0f, 1.0f, 1.0f, 1.0f };  // specular  
 // material reflectivity  
 float4 k_d <  
      string UIName = "Diffuse";  
      > = float4( 0.47f, 0.47f, 0.47f, 1.0f );  // diffuse  
 float outline <  
   string UIName = "outline";  
      > = float(0.005f);  
 float4 rimColor<  
      string UIName = "Rim Color";  
      > = float4( 1.0f, 1.0f, 1.0f, 1.0f );   
 float4 outlineColor<  
      string UIName = "Outline Color";  
      > = float4( 0.0f,0.0f, 0.0f, 0.0f );   
 texture diffuseTexture : DiffuseMap<   
      //string name = "seafloor.dds";   
      string UIName = "Diffuse Texture";  
 //     int Texcoord = 0;  
 //     int MapChannel = 3;       
      >;  
 texture specularTexture : SpecularMap<   
      //string name = "seafloor.dds";   
      string UIName = "Specular Texture";  
 //     int Texcoord = 0;  
 //     int MapChannel = 3;       
      >;       
 texture rampMap : RampMap <   
 //     string name = "NMP_Ripples2_512.dds";   
      string UIName = "Ramp Texture";  
 //     int Texcoord = 0;  
 //     int MapChannel = 3;       
      >;  
 //vertex color       
 int texcoord0 : Texcoord  
 <  
      int Texcoord = 0;  
      int MapChannel = 0;  
 >;  
 //uv 1  
 int texcoord1 : Texcoord  
 <  
      int Texcoord = 1;  
      int MapChannel = 1;  
 >;       
 // transformations  
 float4x4 World   :           WORLD;  
 float4x4 View    :           VIEW;  
 float4x4 Projection :           PROJECTION;  
 float4x4 WorldViewProj :      WORLDVIEWPROJ;  
 float4x4 WorldView :           WORLDVIEW;  
 struct VS_OUTPUT  
 {  
   float4 Pos : POSITION;  
      float2 TexCoord0 : TEXCOORD0;  
      float3 Normal : TEXCOORD1;  
      float3 LightVector : TEXCOORD2;  
      float3 Vnormal : TEXCOORD3;  
   float4 col : COLOR0;  
 };  
 struct VS_OUTPUT2  
 {  
   float4 Pos : POSITION;  
   float4 col : COLOR0;  
 };  
 VS_OUTPUT VS(  
   float3 Pos : POSITION,   
   float4 col     : TEXCOORD0,  
   float3 Norm : NORMAL,   
   float2 Tex : TEXCOORD1)  
 {  
   VS_OUTPUT Out = (VS_OUTPUT)0;  
   float3 L = lightDir;  
   float3 P = mul(float4(Pos, 1),(float4x4)World); // position (view space)  
   float3 N = normalize(mul(Norm,(float3x3)World)); // normal (view space)  
   float3 R = normalize(2 * dot(N, L) * N - L);     // reflection vector (view space)  
   float3 V = normalize(P);               // view direction (view space)  
   Out.Pos = mul(float4(Pos,1),WorldViewProj);  // position (projected)  
   Out.col = col;  
      Out.Normal = N;  
      Out.Vnormal = normalize(mul(Norm,(float3x3)WorldViewProj));  
   Out.TexCoord0 = Tex;  
      Out.LightVector = normalize(lightDir);  
      //Out.LightVector = normalize(mul(lightDir,(float3x3)World));;  
   return Out;  
 }  
 sampler2D diffuseSampler = sampler_state  
 {  
      Texture = <diffuseTexture>;  
      MinFilter = Linear;  
      MagFilter = Linear;  
      MipFilter = Linear;  
      ADDRESSU = Wrap;  
      ADDRESSV = Wrap;  
 };  
 sampler2D specularSampler = sampler_state  
 {  
      Texture = <specularTexture>;  
      MinFilter = Linear;  
      MagFilter = Linear;  
      MipFilter = Linear;  
      ADDRESSU = CLAMP;  
      ADDRESSV = CLAMP;  
 };  
 sampler2D rampSampler = sampler_state   
 {  
      Texture = <rampMap>;  
      MinFilter = Linear;  
      MagFilter = Linear;  
      MipFilter = Linear;  
      ADDRESSU = CLAMP;  
      ADDRESSV = CLAMP;  
 };  
 float4 PS(VS_OUTPUT IN,   
            uniform sampler2D DiffuseMap,  
            uniform sampler2D RampMap,  
            uniform sampler2D SpecularMap) : COLOR  
 {  
      float4 color = tex2D(DiffuseMap, IN.TexCoord0);  
      float2 specUV = float2(IN.Vnormal.x *0.5 +0.5, IN.Vnormal.y * 0.5 + 0.5);  
      half NdotL = max(0,dot (IN.Normal, IN.LightVector));  
      NdotL = clamp(NdotL, 0, 1);  
      half3 ramp = tex2D (RampMap, float2(0,1.0-NdotL)).rgb;  
      ramp = ramp* (IN.col.r) + 1.0 * (1.0- IN.col.r);  
      float4 spec = tex2D(SpecularMap, specUV);  
   color.rgb = color.rgb * ramp* (1.0 - IN.col.r) + color.rgb * ramp* (IN.col.r) + spec * rimColor;  
      //color.rgb = color*k_d;  
      //color.rgb = tex2D(DiffuseMap, IN.TexCoord0).rgb;  
      //color.a = 1;  
   return color ;  
 }  
 VS_OUTPUT2 VS_Outline(  
   float3 Pos : POSITION,   
   float3 Norm : NORMAL )  
 {  
      VS_OUTPUT2 Out;  
      Out.Pos = mul(float4(Pos,1),WorldViewProj);   
      float3 norm = (mul(Norm,(float3x3)WorldViewProj));  
      float viewScaler = (Out.Pos.z + 1) *0.5;  
      //float viewScaler = Out.Pos.z;  
      Out.Pos.xy += norm.xy * viewScaler * outline;  
      Out.col = outlineColor;  
      return Out;  
 }  
 float4 PS_Outline(  
      VS_OUTPUT IN  
 ) : COLOR  
 {  
  float4 color = IN.col;  
  color.a = 0.5;  
  return color;  
 }  
 technique DefaultTechnique  
 {  
   pass P1  
   {  
     // shaders  
           ZEnable = true;  
           ZWriteEnable = true;  
     CullMode = cw;  
           AlphaBlendEnable = true;  
           SrcBlend = srcalpha;  
           DestBlend = zero;  
     VertexShader = compile vs_2_0 VS_Outline();  
     PixelShader = compile ps_2_0 PS_Outline();  
   }   
    pass P0  
   {  
     // shaders  
           ZEnable = true;  
           ZWriteEnable = true;  
     CullMode = ccw;  
     // ShadeMode = Gouraud;  
     VertexShader = compile vs_2_0 VS();  
     PixelShader = compile ps_2_0 PS(diffuseSampler, rampSampler, specularSampler);  
   }   
 }  

沒有留言 :

張貼留言