本文為原創(chuàng)文章,僅在簡書與CSDN發(fā)布,禁止一切形式的轉載
先上效果圖:

在這篇教程中我們用最簡單的方式,在Unity自帶的Quad上用Shader Graph展示一個彩虹。并且在下一篇博客中我會用純Shader代碼的方式再實現(xiàn)一遍。
首先在Hierarchy中通過3D Object > Quad創(chuàng)建一個正方形,然后放大放置在合適的位置上:

大小位置這些在后面可以慢慢調整,只要大到整個場景都能看到即可。
確保你的項目已經配置了渲染管線(URP或HDRP),然后創(chuàng)建一個UnLit Shader Graph以及相應的材質,然后打開Shader Graph編輯:
畫出一道彩虹很簡單,先畫出一條有厚度的曲線,然后在曲線內畫出色階漸變的顏色即可。帶厚度的曲線有幾種畫法:
第一種,直接偏移。畫出sin、拋物線等曲線,然后往y軸正方向偏移一段距離就是一條有厚度的曲線。然后把UV的坐標y值與曲線函數(shù)的差作為色階偏移的變量。不過經常再shader上畫畫的人應該很清楚,這樣得到的曲面在函數(shù)導數(shù)較陡的地方會被“拉扁”,效果如下圖:[圖片上傳失敗...(image-775232-1624004483994)]
-
方法二,變形網格。畫出sin、拋物線等曲線,然后往函數(shù)的導數(shù)方向膨脹。如果采用這個方法的話我建議在頂點著色器上操作。如果是在片段著色器的話你需要列出圓與曲線的方程判斷園與曲線是否相交,對于三角函數(shù)來說它最后是一個超越方程,只能求近似解并且你還拿不到沿法線方向的距離作為色階變換的變量。
操作扭曲頂點的話先用Unity的插件ProBuilder建造一個平面(沒有的話可以打開Package Manager搜索找到),高度不需要細分,細分寬度越大曲線越柔和:
然后編輯一下UV,不然你在像素(片元)著色器中會拿到十分迷惑的uv坐標,點擊ProBuilder面板中的UV Editor打開UV編輯器:創(chuàng)建PlaneuvEditor選擇編輯面模式,然后把UV殼縮放至UV坐標0-1的正方形區(qū)域內即可。
editing UV當然也可以直接調整Offset和Tilling:

然后創(chuàng)建一個ShaderGraph材質變形頂點。
由于我們使用的形狀是cos函數(shù),cos的導數(shù)是-sin,由于在z方向只有-0.5到0.5兩個方向,所以只要在曲線相應位置把z方向的上下兩個點往相應的法線方向平移就行了:

【法線的計算:切線是導數(shù)(1, sinX),用旋轉矩陣逆時針旋轉90度{-1, 0, 0, 1}就能得到(sinX, 1),這個值還需要normalize歸一化】
完整的Shader Graph如下:

最后扭曲出來的平面如下:(沒處理顏色)

你或許想說,有這精力還不如直接在Maya做一個彩虹的曲面模型。其實我也覺得做模型更快,但本著科學嚴謹?shù)木瘢€是把這種方法列出來了。
繪制彩虹
雖然說完了上面兩種方法,但這篇教程并不采用上面兩種方法。彩虹本身就是一個半截的圓環(huán),因此直接截取半截圓進行繪制即可。
顏色偏移我們采用Hue,把Range設置為Normalized,In輸入為一個純色(比如紅100、綠010、藍001),在Offset從0到1變化過程中顏色就會沿整個色相環(huán)走一圈。如果你覺得純紅色太辣眼睛的話,可以提高In的亮度,即提高其他RGB分量的值。如果你想讓彩虹的色相分布進行一些偏移,比如彩虹頂部的紅色多一些,可以提高B分量,反之提高G分量的值,或者在輸入Offset前再進行一次偏移。在這里我把輸入設置為了(1, 0.5, 0.5)

接下來我們在UV坐標(0.5, 0)的地方創(chuàng)建一個距離場,并縮放到我們想要的彩虹的寬度:

這里為了充分利用像素,我們把彩虹的外徑設置為0.5,寬度為0.05
畫出了顏色,接下來只要裁剪出半徑0.45到0.5之間的一段就行了。裁剪使用兩個Step即可完成:

最后將透明度下調就能看見一道完整的彩虹了:

但是作為虛景的彩虹這樣的效果仍然顯得有點突兀,我們可以通過透明度漸變來獲得一個比較好的效果。

完整的ShaderGraph如下:

最后的效果就是文章一開始的那張圖那樣。
下篇博客會有shader的版本,歡迎三連我的博客~~~


