多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 【Unity Shaders】使用CgInclude讓你的Shader模塊化――創建CgInclude文件存儲光照模型

【Unity Shaders】使用CgInclude讓你的Shader模塊化――創建CgInclude文件存儲光照模型

來源:程序員人生   發布時間:2014-10-11 08:00:01 閱讀次數:3363次

本系列主要參考《Unity Shaders and Effects Cookbook》一書(感謝原書作者),同時會加上一點個人理解或拓展。

這里是本書所有的插圖。這里是本書所需的代碼和資源(當然你也可以從官網下載)。

========================================== 分割線 ==========================================



寫在前面


了解內置的CgInclude文件當然很好,但是如果我們想要創建自己的CgInclude文件來存儲光照模型和輔助函數又該怎么辦呢?


好消息是我們的確可以創建自己的CgInclude文件,壞消息是我們需要再了解一點代碼語法。好啦,那就開始吧!



準備工作


好消息是這次的準備工作終于有點不同了。。。壞消息是我不能再復制粘貼了。。。

  1. 首先,創建一個新的文本文件,例如MyCgInclude.txt。
  2. 然后,把文件后綴改為.cginc。當然,操作系統一般會給你一些警示信息,說這個文件將變得不可用,但相信我,我們這個是可用的。
  3. 將新的.cginc文件導入到我們的Unity項目中(注意,在我的項目里,它的位置在一個新的名為CgIncludes的文件夾下)。等編譯完成后,我們可以看到Unity把該文件當成一個CgInclude文件編譯好了。像下面這樣:

現在,我們已經做好準備可以創建自定義的CgInclude代碼啦。雙擊CgInclude文件,在MonoDevelop中打開它吧~


實現


打開CgInclude文件后,開始鍵入如下代碼。
  1. 首先,使用下面的預處理指令開始我們的CgInclude文件。這些聲明和#pragma、#include類似,在這里,我們想要去定義一個新的代碼集合,只要我們的Surface Shader在它的編譯指令里面包含了這個文件,這些代碼就可以執行了。在CgInclude文件的最開始鍵入如下代碼:
    #ifndef MY_CG_INCLUDE #define MY_CG_INCLUDE

  2. 然后,我們必須確保#ifndef或者#ifdef要有一個#endif來結束定義檢查。就和一個if語句需要兩個花括號一樣。在#define指令下面鍵入如下代碼:
    #endif

  3. 接下來,我們就可以填充剩余部分了。鍵入如下代碼:
    // Custom Build-in Variables fixed4 _MyColor; // Lighting models inline fixed4 LightingHalfLambert (SurfaceOutput s, fixed3 lightDir, fixed atten) { fixed diff = max (0, dot (s.Normal, lightDir)); diff = (diff + 0.5) * 0.5; fixed4 c; c.rgb = s.Albedo * _LightColor0.rgb * ((diff * _MyColor.rgb) * atten * 2); c.a = s.Alpha; return c; }

  4. 下面是完整的MyCgInlcude.cginc文件:
    #ifndef MY_CG_INCLUDE #define MY_CG_INCLUDE // Custom Build-in Variables fixed4 _MyColor; // Lighting models inline fixed4 LightingHalfLambert (SurfaceOutput s, fixed3 lightDir, fixed atten) { fixed diff = max (0, dot (s.Normal, lightDir)); diff = (diff + 0.5) * 0.5; fixed4 c; c.rgb = s.Albedo * _LightColor0.rgb * ((diff * _MyColor.rgb) * atten * 2); c.a = s.Alpha; return c; } #endif

    上面相當于一個頭文件,但想要完整利用它還需要一些其他的步驟。我們需要告訴當前的Shader,我們想要使用自己的文件和代碼。

  5. 返回上一節所用的Shader。我們需要在塊中包含我們自己的CgInclude文件,就像C++中需要在開頭添加頭文件引用一樣。同時,之前我們的Shader使用內置的Lambert光照模型,但現在我們想要使用自定義的Half Lambert光照模型。因為我們已經包含了該CgInclude文件,我們可以直接在#pragma指令中指明這一模型:
    CGPROGRAM #include "../CgIncludes/MyCgInclude.cginc" #pragma surface surf HalfLambert

    解釋:這里需要指明.cginc文件的相對與該Shader的路徑。也就是說,如果它和Shader放在同一個文件夾下,那么直接寫名稱即可。但在我的項目中,Shader放在了Shaders文件夾下,而.cginc放在了CgIncludes文件夾下,因此需要上述寫法。

  6. 最后,還記得我們在CgInclude文件中聲明了一個_MyColor變量嗎?我們還需要在Shader的Properties中添加該屬性:
    Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _DesatValue ("Desaturate", Range(0, 1)) = 0.5 _MyColor ("My Color", Color) = (1, 1, 1, 1) }


最后,返回Unity。如果出現編譯錯誤,說找不到.cginc文件,那么就是你的位置寫的有問題,重新看上面的解釋更改一下就可以嘍。

最后的結果如下所示。注意到,這里Unity已經使用了我們新的Half Lambert光照模型(和原來相比,就是提亮了背光面的亮度),并且添加了一個新的樣色樣本。左側為上一篇結果,右側為本篇結果。
 



解釋


當編寫Shader的時候,我們可以像使用C++中的頭文件一樣,使用#include預處理指令來包含其他代碼集合。這告訴Unity我們想要當前的Shader使用包含的這些文件中的代碼。我們這樣做實際上是在相應位置包含了Cg代碼片段。

一旦我們聲明了#include指令,Unity就可以在項目中找到該文件,然后Unity會在文件中查找定義的代碼片段。也就是指,我們使用#ifndef指令和#ifndef指令的地方。當我們聲明#ifndef指令時,我們就是在告訴Unity,如果沒有定義這個名字,那么就使用這個名字去定義一些東西!在本節中,我們是想要去#define MY_CG_INCLUDE。因此,如果Unity沒有找到一個名為MY_CG_INCLUDE的定義,它就會在編譯該CgInclude文件時創建它。而#ifndef就是告訴Unity,這是該定義在這里結束啦,下面的不用再找啦!

現在,你看到了自定義的CgInclude文件是多么強大(和C++中的頭文件類似),我們可以使用它們來存儲所有的自定義光照模型,以減少代碼的重復。其他好處,像靈活性等,你可以聯想C++頭文件來得出啦~



生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 日韩影院在线观看 | 最近中文字幕更新免费 | 精品视频69v精品视频 | 亚洲一区二区三区四区五区六区 | 性激烈的欧美三级视频中文字幕 | 成 人国产在线观看高清不卡 | 国产视频日本 | 国产精品久久久久久久久免费 | 成人国产网站v片免费观看 成人国产亚洲 | 欧美久久久久欧美一区 | 欧美一级欧美一级高清 | 精品国产毛片 | 亚洲黄色在线看 | 亚洲一级毛片 | 九色国产 | 91精品国产福利在线观看性色 | 免费高清不卡毛片在线看 | 男人和女人全黄一级毛片 | 黄色片网站在线播放 | 亚洲国产成人久久综合一 | 欧美综合成人网 | www.欧美黄色 | 在线精品亚洲欧洲第一页 | 欧美成成人免费 | 在线亚洲小视频 | 一本毛片 | h小视频在线| 在线免费看a爱片 | 国产极品粉嫩交性大片 | 欧美淫| 加勒比精品久久一区二区三区 | 高清性欧美 | 国产精品一区二区三区四区 | 亚洲精品一区二区三区在线观看 | 叼嘿视频在线观看 | 亚洲观看视频 | 成人久久精品一区二区三区 | 精品国产一区二区三区久 | 欧美孕交videosfree巨大 | 全黄大全大色全免费大片 | 午夜视频高清在线aaa |