參考
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);
}
}