這幾天在搗鼓一個遊戲 騎馬與砍殺 不知道有沒有人玩過。官方出了個shader包,能夠自定義shader,因而就開始學起來了,學了一點,簡單的實現了一直想弄的動態世界。這期間一直在用RenderMonkey開發(貌似中止更新了,會不會有點落伍了),就記下一點過程,主要算是做爲給mod做者一個簡單教程,也方便剛開始搗鼓的朋友們,同時也方便本身長久不碰以後從新拾起來,。才接觸幾天,有問題還望指出。 app
這篇東西主要講述如何讓模型的頂點浮動來達到一種動畫效果,順便介紹下RenderMonkey。 函數
下載安裝RenderMonkey沒什麼好說的,就這麼安裝唄。HLSL語言本身去學習吧,其實我也是剛學起HLSL,不敢教你們,仍是本身找資料吧。 學習
打開RenderMonkey(吐槽下這個猩猩圖標真醜) 測試
嘛,這不是VC6嘛。(據說彷佛VC也能夠用來開發shader?)好吧,不吐槽這個界面了。 動畫
界面也沒什麼號解釋的,上面幾個圖標說一下吧,雖然英文也看得懂。 spa
從左到右爲:打開項目,保存項目,關閉側邊目錄欄,關閉下面輸出欄,打開渲染預覽效果,右邊的側邊欄(用處未知),三種編譯方式,各類鏡頭有關的操做(沒用過),最後一個未知。 翻譯
廢話很少說開始建立一個實例吧。 3d
能夠選擇add effect group或者add default effect, 前者更像一個項目包吧,裏面能夠包含不少effect, 咱們就直接add default effect吧。 code
這裏咱們建立一個最基本的DirectX effect。下面還有幾種能夠選帶貼圖的,帶高光的,帶凹凸的等等,這些也是很好的學習內容,能夠看到高光,凹凸是如何作成的。咱們只須要一個簡單的例子就好了。 教程
好,咱們看到了一個紅色的圓球,這個就是預覽界面。
主要來看左邊預覽界面咱們建立的是一個Default_DirectX_Effect,固然你能夠本身重命名。
其中包含了四個子節點matViewProjection,Stream Mapping,Model,Pass 0,固然咱們如今建立的是最基礎的effect,實際上節點數不定的,這些應該是必須的。
先說matViewProjection,這是一個float4x4的矩陣,這個其實不太好形容是什麼東西,這個矩陣用來將頂點座標轉化後輸出,有教程稱它爲世界、觀察、投影矩陣。而在以後的Vertex Shader的編寫中,最後必定要將輸入的座標與這個矩陣相乘,獲得轉化的座標,以後輸出。這是一個預約義變量。預約義變量有很多,我如今只會用第一個時間變量,這是作動態效果的基礎,其餘的不明其意。
而後是Stream Mapping, 字面翻譯是流映射,主要做用應該是將模型的信息傳遞給shader.
目前只有一個POSITION 頂點位置. 能夠自行添加,好比要運用貼圖時須要TEXCOORD 紋理座標。
Model很簡單,就是選用的模型,雙擊更換模型。
Pass 0一樣不知道怎麼翻譯好,每一個pass內有一對VertexShader與PixelShader, 而每一個Effect能夠有多個Pass. 忽然想起來準確的來講這個Effect應該叫作Technique..
好了,介紹到這了,咱們開始寫代碼吧。先選擇一個模型,我弄了一面旗幟來作飄動效果。
選完模型,請在預覽界面上右鍵Fit Model to Screen, 來調整好大小,否則可能看不見模型。因爲此次飄動效果只靠頂點來完成,因此咱們打開VertexShader,也就是頂點着色器。
看看代碼,第一個定義的變量就是一開始提到的float4x4的矩陣matViewProjection,注意名字必須是和節點那裏相同的才行。下面兩個結構體。一個輸入,一個輸出,都有一個float4的變量,是一個四維浮點數向量。結構體並非強制的,你能夠直接用其中變量做爲以後對的輸入參數,不過這樣應該不是很科學,嗯嗯。變量後面的:POSITION代表該變量表示頂點位置,若是還記得,上文在Stream Mapping理提到過這個。下面就是入口函數了,接受輸入後將頂點位置轉換後輸出。
好吧,真的要開始寫了。動畫嘛確定要有個時間變量啊,嗯嗯,上文提到過的預約義變量,咱們就增長這個變量,能夠爲它改個名,只要注意在代碼裏的聲明名字要和節點裏的同樣,咱們就改爲time. 而後在代碼裏聲明float time;,咱們把它放在float4x4 matViewProjection;下面一行。
好了,讓咱們來作飄動吧,來回的擺動是一個週期運動,因此咱們選擇一個周期函數,sin,cos隨便,咱們選一個sin(time)。飄動的本質就是每一個頂點在特定時間內移動一段距離。那咱們先設定一個基礎距離base爲0.5,固然也是float類型。可是不能每一個頂點移動同樣的距離啊,爲了飄動的比較和諧,咱們按照旗面上的每一個頂點離旗上邊和左邊的比例來縮小base。
Input.Position.x = Input.Position.x + offset_base*sin(time)*(Input.Position.y/y_length)*((z_length-Input.Position.z)/z_length);
固然移動哪一個軸的座標,移動多大的距離要看你的模型實際尺寸。
固然最後你要限制下只能旗面動,杆子什麼的不受影響。
float4x4 matViewProjection; float time; struct VS_INPUT { float4 Position : POSITION0; }; struct VS_OUTPUT { float4 Position : POSITION0; }; VS_OUTPUT vs_main( VS_INPUT Input ) { VS_OUTPUT Output; float offset_max=0.5f; float z_length=2.0f; float y_length=1.0f; if((Input.Position.z>0.6f)&&(Input.Position.z<2.0f)){ if (Input.Position.y>0.1f){ Input.Position.x = Input.Position.x + offset_max*sin(time*2)*(Input.Position.y/y_length)*((z_length-Input.Position.z)/z_length); } } Output.Position = mul( Input.Position, matViewProjection ); return( Output ); }
而後編譯下看看吧,動起來了吧。
幾點說明:在預覽界面右鍵show triad能夠顯示座標,可是這個座標是左手座標系,雖然model上右鍵能夠改左右手座標系,但貌似測試無效。因此座標系可能和你的建模軟件裏不一樣,好比我如今3dmax裏是右手座標系,因此這個要注意一下,能調成一致仍是最好了~
另外,你們以爲這樣精確到數值的控制選擇的頂點很2吧,並且要跑去建模軟件裏看到底這個頂點座標數值多少。其實也能夠經過貼圖座標來完成,研究完了下次再寫,包括這部分沒寫的如何加上貼圖也一併寫上。
終於寫完了,頭昏腦脹的,囉囉嗦嗦,感受像在寫日記,不是寫教程,你們將就看吧。。有錯誤歡迎指出,有遺漏歡迎補充。