1. 程式人生 > >[shader]邊緣自定角度高光,描邊,閃爍

[shader]邊緣自定角度高光,描邊,閃爍

Shader "QQ/RimLight" {
	Properties{
		_Color("Color", Color) = (1,1,1,1)
		_MainTex("紋理", 2D) = "white" {}
	<span style="white-space:pre">	</span>_LightColor("燈顏色",Color) = (1,1,1,1)
		_LightDir("燈方向",Vector) = (0,1,0,1)
		_OutLine("描邊顏色",Color) = (1,1,1,1)
		_EdgeChange("描邊大小",Range(0,.1)) = .05
		_FlickerTime("閃爍時間,0為關閉",Range(0,2)) = 1
	}
	CGINCLUDE
	#include "UnityCG.cginc"
	#pragma vertex vert
	#pragma fragment frag
	#pragma target 3.0
	ENDCG
	SubShader{
	Tags{ "RenderType" = "Transparent"
	"Queue" = "Transparent"
	"LightMode" = "ForwardBase" }
	LOD 200
	Pass
	{
		Cull Front
		ZWrite Off
		Blend SrcAlpha OneMinusSrcAlpha
		CGPROGRAM
		fixed4 _OutLine;
		float _EdgeChange;
		float _FlickerTime;
	struct a2v
	{
		float4 vertex:POSITION;
		float3 normal : NORMAL;
	};
	struct v2f
	{
		float4 pos : POSITION;
	};
	v2f vert(a2v v)
	{
		v2f o;
		//參考部落格 http://blog.csdn.net/candycat1992/article/details/45577749
		o.pos = mul(UNITY_MATRIX_MV,v.vertex);
		v.normal = mul((float3x3)UNITY_MATRIX_MV,v.normal);
		v.normal.z = -.5;
		o.pos.xyz += v.normal*_EdgeChange;
		o.pos = mul(UNITY_MATRIX_P,o.pos);
		//參考官方教程
		//v.vertex.xyz += v.normal*_EdgeChange;
		//o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
		return o;
	}
	fixed4 frag(v2f i) :COLOR
	{
		//閃爍的乒乓的速度,如果指令碼傳值可以把這段刪掉
		_OutLine.a = abs(cos(_Time.x*_FlickerTime));
		return _OutLine;
	}
	ENDCG
	}
	Pass
	{
	CGPROGRAM
	fixed4 _Color;
	sampler2D _MainTex;
	fixed4 _MainTex_ST;
	fixed4 _LightColor;
	fixed4 _LightDir;


	struct a2v
	{
		float4 vertex:POSITION;
		float3 normal : NORMAL;
		float4 texcoord : TEXCOORD0;
	};
	struct v2f {
		float4 pos : POSITION;
		float2 uv:TEXCOORD0;
		float3 normal:TEXCOORD1;
		float3 viewDir:TEXCOORD2;
		UNITY_FOG_COORDS(3)
	};


	v2f vert(a2v v)
	{
		v2f o;
		o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
		float4 wPos = mul(_Object2World, v.vertex);
		o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
		//不過分追求效果的情況下在這裡normalize,如果追求效果,請在frag內normalize,否則插值會被歸一。
		o.normal = normalize(mul(v.normal, _World2Object).xyz);
		//我們希望光是從攝像機對面過來的,所以就反減
		o.viewDir = normalize(wPos.xyz - _WorldSpaceCameraPos);
		//旋轉矩陣
		float3x3 rotaX = { 1,0,0,0,cos(_LightDir.x),sin(_LightDir.x),0,-sin(_LightDir.x),cos(_LightDir.x) };
		float3x3 rotaY = { cos(_LightDir.y),0,sin(_LightDir.y),0,1,0,-sin(_LightDir.y),0,cos(_LightDir.y) };
		float3x3 rotaZ = { cos(_LightDir.z),sin(_LightDir.z),0,-sin(_LightDir.z),cos(_LightDir.z),0,0,0,1 };
		o.viewDir = mul(rotaX, o.viewDir);
		o.viewDir = mul(rotaY, o.viewDir);
		o.viewDir = mul(rotaZ, o.viewDir);
		//矩陣相乘後結果不太對,可能寫錯了。
		//float3x3 rota = { sin(_LightDir.y)*sin(_LightDir.z),sin(_LightDir.y)*cos(_LightDir.z),cos(_LightDir.y),
		// -sin(_LightDir.y)*cos(_LightDir.x)*sin(_LightDir.z) - sin(_LightDir.x)*sin(_LightDir.z),-sin(_LightDir.y)*cos(_LightDir.x)*cos(_LightDir.z) + sin(_LightDir.x)*cos(_LightDir.z),cos(_LightDir.x)*cos(_LightDir.y),
		// -sin(_LightDir.y)*cos(_LightDir.x)*sin(_LightDir.z) + sin(_LightDir.x)*sin(_LightDir.z),-sin(_LightDir.y)*cos(_LightDir.x)*cos(_LightDir.z) - sin(_LightDir.x)*cos(_LightDir.z),cos(_LightDir.x)*cos(_LightDir.y)
		//};
		//o.viewDir = mul(rota, o.viewDir);
		return o;
	}
	fixed4 frag(v2f i) :COLOR
	{
		fixed4 col;
		fixed4 tex = tex2D(_MainTex,i.uv);
		//點乘normal和視線,判斷相似度
		float diff = max(0,dot(i.normal, i.viewDir));
		col = tex*_Color + _LightColor*diff*_LightDir.w;
		return col;
	}
	ENDCG
	}
	}
	FallBack "Diffuse"
}