1. 程式人生 > >Unity Shader 表面著色器邊緣光(Rim Lighting)二

Unity Shader 表面著色器邊緣光(Rim Lighting)二

這一節我們要實現下面的效果


(圖一)


(圖二)

首先針對圖一我們建立一個材質,並把顏色改成紅色的,然後我們就得到了一個很普通的紅色小球。


我們只需要在滑鼠進入的時候把材質的Shader換成帶邊緣光的Shader就行了。

我們新建一個c#檔案取名為ShowSelected.cs.然後把這個指令碼檔案賦值給小球。

我們來看一下ShowSelected.cs中的程式碼,幾乎每一句都有註釋:

using UnityEngine;
using System.Collections;

public class ShowSelected : MonoBehaviour {
	
	public Shader selectedShader;
	public Color outterColor;

	
	private Color myColor ;
	private Shader myShader;
	private bool Selected = false;
	
	// Use this for initialization
	void Start () {
		//儲存原來的顏色值和shader,以便滑鼠移出時恢復
		myColor = GetComponent<Renderer>().material.color;
		myShader = GetComponent<Renderer>().material.shader;
		//滑鼠移入時要使用的shader
		selectedShader = Shader.Find("Custom/Rim Lighting2");
		if(!selectedShader)
		{
			enabled = false;
			return;
		}
	}
	//滑鼠進入
	 void OnMouseEnter() {
		//替換Shader
		GetComponent<Renderer>().material.shader = selectedShader;
		//設定邊緣光顏色值
		GetComponent<Renderer>().material.SetColor("_RimColor",outterColor);
		//設定紋理顏色值
		GetComponent<Renderer>().material.SetColor("_MainColor",myColor);
    }
	//滑鼠移出
	void OnMouseExit(){
		//恢復顏色值
		GetComponent<Renderer>().material.color = myColor;
		//恢復shader
		GetComponent<Renderer>().material.shader = myShader;
	}
}


我們來看一下帶邊緣光的Shader的程式碼:

Shader "Custom/Rim Lighting2" {
		 //屬性域
		Properties {
			//紋理顏色
			 _MainColor ("Main Color", Color) = (1,1,1,1)
			  //主紋理屬性
			  _MainTex ("Texture", 2D) = "white" {}
			  //法線貼圖紋理屬性
			  _BumpMap ("Bumpmap", 2D) = "bump" {}
			  //邊緣光顏色值
			  _RimColor ("Rim Color", Color) = (1,1,1,1)
			  //邊緣光強度值
			  _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
	    }
		SubShader {
			  //標明渲染型別是不透明的物體
			  Tags { "RenderType" = "Opaque" }
			  //標明CG程式的開始
			  CGPROGRAM
			  //宣告表面著色器函式
			  #pragma surface surf Lambert
			  //定義著色器函式輸入的引數Input
			  struct Input {
			  	  //主紋理座標值
			      float2 uv_MainTex;
			      //法線貼圖座標值
			      float2 uv_BumpMap;
			      //檢視方向
			      float3 viewDir;
			  };
			  //宣告對屬性的引用
			  float4 _MainColor;
			  sampler2D _MainTex;
			  sampler2D _BumpMap;
			  float4 _RimColor;
			  float _RimPower;
			  //表面著色器函式
			  void surf (Input IN, inout SurfaceOutput o) {
			  	  fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
			  	  
			  	  //賦值顏色資訊
				  o.Albedo = tex.rgb * _MainColor.rgb;
			      //賦值法線資訊
			      o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
			      half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
			      //賦值自發光顏色資訊
			      o.Emission = _RimColor.rgb * pow (rim, _RimPower);
			  }
			  //標明CG程式的結束
			  ENDCG
		} 
	    Fallback "Diffuse"
}

這樣就可以實現圖一中的效果了

我們來看看圖二的效果是怎麼實現的

同樣我們新建一個C#檔案,取名為ShowSelectedBump.cs,我們來看一下這個CS檔案中的程式碼,同樣每一句都有註釋

using UnityEngine;
using System.Collections;

public class ShowSelectedBump : MonoBehaviour {

	public Shader selectedShader;
	public Color outterColor;

	
	private Color myColor ;
	private Shader myShader;
	private SkinnedMeshRenderer sRenderer;
	private bool Selected = false;

	// Use this for initialization
	void Start () {
		sRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
		//儲存原來的顏色值和shader,以便滑鼠移出時恢復
		myColor = sRenderer.material.color;
		myShader = sRenderer.material.shader;
		//滑鼠移入時要使用的shader
		selectedShader = Shader.Find("Custom/RimLightSpecBump");
		if(!selectedShader)
		{
			enabled = false;
			return;
		}
	}

	//滑鼠進入
	void OnMouseEnter() {
		//替換Shader
		sRenderer.material.shader = selectedShader;
		//設定邊緣光顏色值
		sRenderer.material.SetColor("_RimColor",outterColor);
		//設定紋理顏色值
		sRenderer.material.SetColor("_MainColor",myColor);
    }
	//滑鼠移出
	void OnMouseExit(){
		//恢復顏色值
		sRenderer.material.color = myColor;
		//恢復shader
		sRenderer.material.shader = myShader;
	}
	
}
我們看到處理動畫模型的ShowSelectedBump.cs和ShowSelected.cs唯一不同的是這一句程式碼
sRenderer = GetComponentInChildren<SkinnedMeshRenderer>();

只是獲取模型的渲染元件不同而已,我們的shader檔案用的是同一個。

這樣就可以很方便的實現圖二的效果了。