1. 程式人生 > >Unity Shader 效果學習

Unity Shader 效果學習

愛的 原理 transform ren 選擇 hit 能夠 int sharp

Unity上對於圖像的處理,假設單純使用代碼。那麽非常遺憾,程序基本會跑死,畢竟是直接對像素的操作,讀取寫入都是比較耗費CPU和內存的。

所以。這次由於項目須要想實現類似哈哈鏡的效果。想來想去,還是認為用unity的Shader比較好,畢竟不須要CPU做什麽,僅僅用GPU就能夠了。

話說GPU也是非常強大的。

以下簡單說一下Shader(事實上我也是新手,學習的話,參考http://blog.csdn.net/poem_qianmo/article/details/40723789

)這是位大牛,我的一些基礎知識是在裏面學習的。

這次我是來分享幾個Shader的,對於詳細的內容原理什麽的,我就不講了。也講不來技術分享

,僅僅能大致說一下。我也在學習。

1、哈哈鏡效果(放大)

Shader "Custom/MaxFace" {
	Properties {
		_MainTex("texture",2D)="white"{}
		_Radius("radius",float)=0.2
		_CenterX("centerX",float)=0.5
		_CenterY("centerY",float)=0.5
	}
	SubShader {
	tags{"Queue"="Transparent" "RenderType"="Transparent"}
	Pass{
	CGPROGRAM
	#pragma vertex vert
	#pragma fragment frag
	#include "UnityCG.cginc"
	float4 _Color;
	sampler2D _MainTex;
	float _CenterX;
	float _CenterY;
	struct v2f{
		float4 pos : SV_POSITION;
		float2 uv : TEXCOORD0;
	};
	float4 _MainTex_ST;
	v2f vert(appdata_base v){
	v2f o;
	o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
	o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
	return o;
	} ;
	float newX=0;
	float newY=0;

	float _Radius;
	half4 frag(v2f i):COLOR
	{
	float tx=i.uv.x-_CenterX;
	float ty=i.uv.y-_CenterY;
	float distan=tx*tx+ty*ty;
	float real_radius=_Radius/2;
	if(distan<_Radius*_Radius){
	newX=tx/2;
	newY=ty/2;
	newX=newX*(sqrt(distan)/real_radius);
	newY=newY*(sqrt(distan)/real_radius);
	newX=newX+_CenterX;
	newY=newY+_CenterY;	
	
	}else{
	newX=i.uv.x;
	newY=i.uv.y;
	}
	
	float u_x=newX;
	float u_y=newY;
	float2 uv_earth=float2(u_x,u_y);
	half4 texcolor_earth=tex2D(_MainTex,uv_earth);

	//
	return texcolor_earth;
	}
	ENDCG
	}
	}
	FallBack "Diffuse"
}

以下是解釋,將就著看一下

技術分享

編譯無誤的話。我們看一下在Unity中的效果

新建一個Plane,導入一張圖片。然後拖到Plane上面,在選擇我們剛才創建的Shader

技術分享

能夠看到,以下的三個參數就是我們創建的在Propertes裏面。隨便挑以下參數。以下是效果

技術分享技術分享

好吧,糟蹋了美女。。

算法是我從Java裏面改過來的,細節就不要問我了。我是代碼搬運工。。

2、哈哈鏡縮小模式

我直接上代碼咯,由於基本沒有變什麽

Shader "Custom/MinFace" {
	Properties {
		_MainTex("texture",2D)="white"{}
		_CenterX("centerX",float)=0.5
		_CenterY("centerY",float)=0.5
	}
	SubShader {
	tags{"Queue"="Transparent" "RenderType"="Transparent"}
	Pass{
	CGPROGRAM
	#pragma vertex vert
	#pragma fragment frag
	#include "UnityCG.cginc"
	float4 _Color;
	sampler2D _MainTex;
	float _CenterX;
	float _CenterY;
	struct v2f{
		float4 pos : SV_POSITION;
		float2 uv : TEXCOORD0;
	};
	float4 _MainTex_ST;
	v2f vert(appdata_base v){
	v2f o;
	o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
	o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
	return o;
	} ;
	float newX=0;
	float newY=0;
	float _Radius;
	float theta=0;
	half4 frag(v2f i):COLOR
	{
	float tx=i.uv.x-_CenterX;
	float ty=i.uv.y-_CenterY;
	
	 theta = atan2(ty, tx);  
	float radius=sqrt(tx * tx+ ty * ty);  
	 float newR=sqrt(radius)*0.5 ;

	newX=_CenterX+newR*cos(theta);
	newY=_CenterY+newR*sin(theta);
	if (newX<0) 
      {  
         newX=0;
      }  
      if (newX>1)  
      {  
         newX=1;
      }
       if (newY>1)  
      {  
         newY=1;
      }
       if (newY<0)  
      {  
         newX=0;
      }
     
	float2 uv_earth=float2(newX,newY);
	half4 texcolor_earth=tex2D(_MainTex,uv_earth);

	return texcolor_earth;
	}
	ENDCG
	}
	}
	FallBack "Diffuse"
}
看看效果(事實上第二個還蠻可愛的)

技術分享


技術分享

3、再來個對稱的

Shader "Custom/SymmertyFace" {
//對稱特效
	Properties {
		_MainTex("texture",2D)="white"{}
	}
	SubShader {
	tags{"Queue"="Transparent" "RenderType"="Transparent"}
	Pass{
	CGPROGRAM
	#pragma vertex vert
	#pragma fragment frag
	#include "UnityCG.cginc"
	float4 _Color;
	sampler2D _MainTex;
	float _CenterX;
	float _CenterY;
	struct v2f{
		float4 pos : SV_POSITION;
		float2 uv : TEXCOORD0;
	};
	float4 _MainTex_ST;
	v2f vert(appdata_base v){
	v2f o;
	o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
	o.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
	return o;
	} ;
	half4 frag(v2f i):COLOR
	{
	float uv_x;
	if(i.uv.x>0.5){
	uv_x=1-i.uv.x;
	}else{
	uv_x=i.uv.x;
	}
     
	float2 uv_earth=float2(uv_x,i.uv.y);
	half4 texcolor_earth=tex2D(_MainTex,uv_earth);

	return texcolor_earth;
	}
	ENDCG
	}
	}
	FallBack "Diffuse"
}
看效果

技術分享

額,這妹子即使對稱了。看著還是挺好看(花癡ing)附上原圖

技術分享

臨時就這麽多吧,還有其它特效,以後慢慢更新

Unity Shader 效果學習