需求變更
我哩個天天,需求這東西就是你做完一個又回有新的一個喘先,做了個普通的钳吟,就會讓你做高級的。
這不之前做了循環(huán)長箭頭窘拯,領(lǐng)導(dǎo)就說要分段顯示红且,怎么個分段顯示咧?能夠顯示兩種顏色的箭頭涤姊,一種是你還沒有走完的路暇番,一種是已經(jīng)走完的。恩思喊,需求很簡單壁酬,容我思考下人生。
看來又要學(xué)習(xí)啦
對unity的shader一直沒有深入研究,到目前為止都是停留在能用就行的階段舆乔。復(fù)雜一點的shader基本也用可視化的編輯插件進行處理岳服,手打的也就能寫寫固定功能的shader∠A可視化的插件很方便吊宋,所見即所得,缺點是需要微調(diào)的時候就麻煩了颜武。固定著色器功能再多也有限璃搜,到頭來寫Shader還是離不開HLSL和CG語言直接寫。當(dāng)然在Unity中鳞上,unity為我們包裝了ShaderLab的殼子為我們方便的實現(xiàn)需要的功能这吻,同時不至于代碼過于的冗余和晦澀。
同樣的Unity提供了官方文檔篙议,內(nèi)容嘛橘原,老規(guī)矩全而不細,需要的朋友出門左轉(zhuǎn)涡上,可以翻閱一下:Unity ShaderLab 官方文檔
先想想問題趾断,別急著動手
當(dāng)前的需求是分段顯示兩種不同顏色的箭頭,用于區(qū)分哪一部分是已經(jīng)走過的路線吩愧,哪一部分是為走過的路線芋酌。在這個需求中需要處理兩個貼圖,用來表現(xiàn)不同的狀態(tài)雁佳。
方法一:
常規(guī)情況下可以直接制作兩個箭頭的組件脐帝,因為在第一版的基礎(chǔ)下已經(jīng)實現(xiàn)了從點A到點B的箭頭。分段顯示只要處理點A到中間點A'和A'到B兩段就行糖权。
這樣做表面上看起來沒有任何問題堵腹,實際上也沒有任何問題!就是有一點比較麻煩星澳,首先疚顷,你需要處理兩個箭頭,其次禁偎,A'點在實際游戲中是移動的腿堤,因為人是不斷移動的,你就需要不停的調(diào)整兩個箭頭的長度如暖,也就是需要控制兩個變量笆檀。這種雖然能有但是哪里又有點不對的感覺就好像...
方法二:
不就是顯示兩個材質(zhì)嘛盒至,直接shader處理酗洒,把中間點A'當(dāng)做屬性值傳入到shader中士修,然后就行判斷,未到A'點的顯示材質(zhì)一樱衷,A'點之后的顯示材質(zhì)二棋嘲,這樣就只需要維護一個箭頭,同時移動的時候只需要改shader中傳入的A'參數(shù)就可以了箫老。恩封字,很完美黔州,方便使用耍鬓,一般用起來方便懶的方法,寫起了都有些費勁流妻。別問我怎么知道的~~
想好了就動手做
目測原來會的固定功能shader無法實現(xiàn)判斷的功能牲蜀,需要直接寫頂點著色器和片段著色器,基礎(chǔ)有限就有惡補绅这。涉及到圖形圖像shader這方面的資料少之又少涣达,中文的就更不多了。推薦大家兩個不過的博客证薇,兩位大佬也都是出過書的度苔,大家也可以看看:
淺墨的Unity3D
candycat
Shader的實現(xiàn)代碼不算復(fù)雜,該有的東西也都有浑度,注釋也寫的很清楚寇窑,算是個不錯的入門作業(yè),需要的同學(xué)可以拿走箩张,記得順手點個贊哦
Shader "Custom/雙色Shader"
{
//屬性
Properties
{
_MainTex("MainTex(RGBA)", 2D) = "white" {} //材質(zhì)1
_GrayTex("GrayTex(RGBA)",2D) = "white" {} //材質(zhì)2
_CurrentPos("CurrentPos",Range(0,1)) = 1 //當(dāng)前位置
}
SubShader
{
LOD 100
Cull Off Lighting Off ZWrite Off ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Tags
{
"Queue" = "Overlay"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
}
Pass{
CGPROGRAM
#pragma vertex vert //定義頂點著色器處理單元
#pragma fragment frag //定義片段著色器處理單元
#include "UnityCG.cginc"
//變量定義
uniform sampler2D _MainTex;
uniform sampler2D _GrayTex;
uniform fixed _CurrentPos;
uniform fixed4 _MainTex_ST;
//頂點輸入結(jié)構(gòu)
struct vertexInput {
fixed4 vertex : POSITION;
fixed4 texcoord0 : TEXCOORD0;
};
//片段輸入結(jié)構(gòu)(頂點輸出)
struct fragmentInput {
fixed4 position : SV_POSITION;
fixed4 texcoord0 : TEXCOORD0;
fixed2 uv:_MainTex_ST;
};
//頂點著色器處理單元
fragmentInput vert(vertexInput i) {
fragmentInput o;
o.position = UnityObjectToClipPos(i.vertex); //轉(zhuǎn)換物體空間到相機空間
o.texcoord0 = i.texcoord0;
o.uv = TRANSFORM_TEX(i.texcoord0, _MainTex); //應(yīng)用材質(zhì)的Tilling和offset屬性
return o;
}
//片段著色器處理單元
fixed4 frag(fragmentInput i) : SV_Target{
//判斷
if(i.texcoord0.y >= _CurrentPos)
return tex2D(_GrayTex, i.uv);
else
return tex2D(_MainTex, i.uv);
}
ENDCG
}
}
}
為了優(yōu)化性能甩骏,同時游戲里的需求也不高,所有精度都為fixed先慷,具體項目中可以更具需要進行實際修改饮笛。
結(jié)語
該學(xué)的東西還是要學(xué),總是無法回避的论熙,誰讓選擇了程序員這條路福青,就是一條終生學(xué)習(xí)的路。路上的兄弟共勉之脓诡。加油素跺。