UnityShader快速上手指南(一)

簡介

引言

其實網上有不少shader教程,可是大概看了下,也不知是網上各位大神已經脫離了代碼層面的高度仍是啥緣由。貌似沒有找到從代碼方面做爲入門講解的,致使了shader對於苦逼程序員入門有必定要求,鄙人不才,來寫個比較低級的從代碼入門的shader教程吧。

寫在前面的話

瞭解過unityshader的人都知道,unityshader分三種,固定管線、表面着色器、頂點和片斷着色器,具體區別書面上以及網上大神已經解釋的很清楚了,我就很少作贅述了,我這一系列教程只從頂點和片斷着色器教程開始,跟其餘教程可能也有些區別(一來就上比較坑爹的部分),若是您沒聽過頂點和片斷着色器的,請止步於此。

寫Shader的工具

若是已經習慣了本身的IDE請直接跳過,只是推薦一下
1.下載安裝sublime text
2.下載該插件https://github.com/cjsjy123/Unity-Shader
3.將文件夾更名爲Unity-Shader(就是去掉後面的-master)而後複製到sublime的packages路徑下
4.在sublime下設置unity的shader include路徑
    preferences ->Packages settting -> Unity-Shader - >setting - Default
    路徑是:D:/Program Files/Unity/Editor/Data/CGIncludes(自行類比)
5.愉快的用sublime編寫shader吧(支持代碼跳轉及基本自動完成功能)

20行的Shader

效果:

這裏寫圖片描述

Shader "LT/Lesson1"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            float4  vert ( float4 position : POSITION ) : SV_POSITION
            {
                return mul( UNITY_MATRIX_MVP, position );
            }

            fixed4 frag ( void ) : COLOR
            {
                return float4 (1,0,0,1);
            }
            
            ENDCG
        }
    }
}
這裏咱們大概解釋一下咱們要用的shader的代碼結構:
Shader的語法是
Shader "名字" // 這個名字本身隨便取,相似於類名,不須要與文件名相同
    {
        Properties {} // 能夠從unity中設置的外接屬性,後面具體講怎麼設置
        SubShader {
            // 執行的渲染PASS,能夠有多個Pass,都會被執行
            Pass{
            // 具體代碼
            }
        }
        .
        . // 能夠有不少個,gpu執行的時候從上往下,找到第一個能夠執行的SubShader執行
        .
        SubShader {
            // 執行的渲染
        }
        // 備胎,在沒有任何Subshader能夠執行時,用該shader代替
        Fallback "Diffuse"
    }
以上就是咱們大概要用的代碼結構,其實還有其餘的,可是爲了快速上手,後續要擴展再引入
其中除了SubShader不能刪,其餘的不用的均可以刪掉
因此精簡出咱們的第一個shader的結構:
Shader "名字"
{
    SubShader
    {
        Pass
        {
            // 代碼
        }
    }
}
下面講代碼部分:
咱們要用的CG語言,先後必須用CGPROGRAM和ENDCG包起來,
而後中間的部分就是咱們真正的cg代碼了
#pragma vertex vert 
// 這一行是定義處理頂點信息的函數名
// 模型中每個頂點會調用一次該函數,GPU執行運算,注意性能
// 格式是: #pragma vertex 函數名,函數名字能夠本身隨意取

#pragma fragment frag
// 這一行是定義處理片面信息的函數名
// 具體調用時機不是很肯定,應該是跟面數相關
// 格式是: #pragma fragment 函數名,函數名字能夠本身隨意取

float4  vert ( float4 position : POSITION ) : SV_POSITION
// 對應的上面頂點處理的函數,傳入對象是一個float4
// 實際上是一個頂點的詳細信息,只是咱們這裏經過: POSITION單獨選取了位置信息而已
// 後面的: SV_POSITION表示return的float4做爲SV_POSITION(不可變頂點)
// 其實傳出爲POSITION也是能夠的,DX10以後纔有區別,SV_POSITION性能更高
{
    return mul( UNITY_MATRIX_MVP, position );
    // 這裏作了一個與UNITY的矩陣世界作了一個乘法操做
    // 用於將模型座標換算成世界座標,若是須要經過shader更改頂點位置,須要在這裏進行操做
}

fixed4 frag ( void ) : COLOR
// 對應上面的面片處理的函數,這裏爲了簡單,不處理任何數據
// : COLOR 表示返回的fixed4類型做爲COLOR處理
{
    return float4 (1,0,0,1);
    // 直接返回一個固定顏色(float4能夠強轉成fixed4,這裏爲了教程演示強轉使用)
}

咱們想在Unity中改顏色

先來明確編寫思路:
從上面的解釋能夠看出,咱們的顏色處理是在frag 函數中返回的
因此咱們要想改變物體顏色,只須要更改這個返回值便可
那麼要從unity中更改顏色,咱們就須要一個外接屬性
恩,上面也講了,從Properties 中設置!
直接上代碼吧
Shader "LT/Lesson1"
{
    Properties {
        _Color ("Main Color", Color ) = (1,0,0,1)
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            uniform float4 _Color;

            float4  vert ( float4 position : POSITION ) : SV_POSITION
            {
                return mul( UNITY_MATRIX_MVP, position );
            }

            fixed4 frag ( void ) : COLOR
            {
                return _Color;
            }
            
            ENDCG
        }
    }
}
好~
來解釋一下:
_Color ("Main Color", Color ) = (1,0,0,1) 
表示我在Unity的Shader面板中定義了一個_Color的外接屬性
格式爲 [變量名字] ("Unity中顯示的名字", [類型]) = (值)
具體後面還有其餘的,我也背不下來,用到再講,也能夠自行查閱
而後定義了以後,並不能直接被CG代碼識別,
須要用到 uniform float4 _Color;申明一下該變量名(名字必須徹底一致)
而後後續操做就不解釋了吧,直接該顏色,返回就行
咱們來看看效果

這裏寫圖片描述

我想更改頂點渲染位置

哈哈,這裏就是shader開始牛逼的地方了:
咱們能夠很高效的對模型頂點數據進行特殊處理!
此次咱們要更改vert函數(這個應該不難想吧,頂點相關的操做通常都在這裏作了)
直接來代碼:
Shader "LT/Lesson1"
{
    Properties {
        _Color ("Main Color", Color ) = (1,0,0,1)
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            uniform float4 _Color;

            float4  vert ( float4 position : POSITION ) : SV_POSITION
            {
                return mul( UNITY_MATRIX_MVP, position * float4 (2,0.5,1,1));
            }

            fixed4 frag ( void ) : COLOR
            {
                return _Color;
            }
            
            ENDCG
        }
    }
}
來,先看效果再解釋

這裏寫圖片描述

能夠很清楚地看到,X軸被放大到了2倍,y變爲了0.5倍,z沒有變化,
而後對比一下position * float4 (2,0.5,1,1)這個操做,應該很容易猜出這個操做的含義了吧
float4 (x,y,z,u)這個float4的xyz分別對應三個軸上的縮放量,u呢則是咱們的單位長度
具體的縮放關係體現爲 座標位置 = 原始位置 * (x / u)
固然,你也能夠在這個函數中對頂線信息進行其餘操做,這裏只是最簡單一個例子

總結

到這裏,今天的blog就到此結束了,但願你們能看懂,不明白的歡迎加QQ:821580467一塊兒探討
相關文章
相關標籤/搜索