編寫自己的Shader(著色器)
阿新 • • 發佈:2019-02-17
一、Shader 程式的基本結構##
Shader程式的基本結構首先是一些屬性定義,用來指定這段程式碼將有哪些輸入。接下來是一個或者多個的子著色器,在實際執行中,哪一個子著色器被使用是由執行的平臺所決定的。子著色器是程式碼的主體,每一個子著色器中包含一個或者多個的Pass。在計算著色時,平臺先選擇最優先可以使用的著色器,然後依次執行其中的Pass,然後得到輸出的結果。最後指定一個回滾,用來處理所有Subshader都不能執行的情況(比如目標裝置實在太老,所有Subshader中都有其不支援的特性)。
需要提前說明的是,在實際進行表面著色器的開發時,我們將直接在Subshader這個層次上寫程式碼,系統將把我們的程式碼編譯成若干個合適的Pass。廢話到此為止,下面讓我們真正實際進入Shader的世界吧。
二、進入Shader內部程式碼結構熟悉##
建立Shader內部展示屬性定義
屬性的對應SuberShader(子著色器)
SuberShader三、簡單Shader展示##
Shader "Custom/ShaderTest" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
//在輸入貼圖時候,必須要寫一個什麼都不含的{}
//需要開啟特定選項時可以把其寫在這對花括號內.
//如果需要同時開啟多個選項,可以使用空白分隔
_MainTex ("Albedo (RGB)" , 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_MainColor("Main Color",Color)=(0,0,0,1)
_Testure("Texture",2D)="White"{}
}
SubShader {
//表面著色器可以被若干的標籤(tags)所修飾
//硬體將通過判定這些標籤來決定什麼時候呼叫該著色器
Tags { "RenderType" ="Opaque" }//標籤內部就是告訴系統渲染非透明的物體呼叫我們
//Tags { "RenderType"="Transparent" }//渲染透明物體呼叫
//Tags { "IgnoreProjector"="True" }//不被Projectors影響
//Tags{ "ForceNoShadowCasting"="True" }//不產生陰影
//指定渲染佇列(下面有系統預設的佇列)
//Tags{ "Queue"="Geometry" }
//Background--最早被呼叫的渲染,用來渲染天空盒或者背景
//Geometry--預設值,用來渲染非透明物體(普通情況下,場景中的絕大多數物體應該是非透明的)
//AlphaTest--用來渲染經過Alpha Test的畫素,單獨為AlphaTest設定一個Queue是出於對效率的考慮
//Overlay--用來渲染疊加的效果,是渲染的最後階段(比如鏡頭光暈等特效)
//Transparent--以從後往前的順序渲染透明物體
//預設的佇列本質就是定義的整數(有點像列舉值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最後Overlay=4000
//如何自定義列表
//Tags{ "Queue"="Transparent+200" }//通過呼叫Queue值,確保渲染的先後順序
//Unity的內建Diffuse著色器的設定值,這個數值決定了我們能用什麼樣的Shader
//這個數值可以在unity中的質量設定中設定
LOD 200//著色器的設定值
//Decal, Reflective VertexLit = 150
//Diffuse = 200
//Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
//Bumped, Specular = 300
//Bumped Specular = 400
//Parallax = 500
//Parallax Specular = 600
//Shader字型:也就是將輸入轉變成輸出的程式碼部分
CGPROGRAM//開始CG語言的編寫
// Physically based Standard lighting model, and enable shadows on all light types
//surface:申明的是一個表面著色器
//surf:著色器程式碼的方法的名字,下方的程式碼有這個函式
//Standard:標準
//fullforwardshadows:光照模型
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
//在CG中,sampler2D就是和texture所繫結的一個數據容器介面
//其實就是記憶體儲存的RGB通道,sampler2D:就是GLSL中的2D貼圖的型別
//其他型別:sampler1D,sampler3D,samplerCube
// 圖片
sampler2D _MainTex;
// 用來獲取MainTex的UV資訊
struct Input {
float2 uv_MainTex; // 用來獲取MainTex的UV資訊
vec2 coordinate;//float和vec都可以在之後加入一個2到4的數字,來表示被打包在一起的2到4個同類型數
float4 color;
};
half _Glossiness;//half指的是半精度浮點數,精度最低,運算效能相對比高精度浮點數高一些
half _Metallic;
// 顏色屬性
fixed4 _Color;
// SurfaceOutputStandard 表面著色器輸出一個標準的結構體
//著色器的工作核心,著色器就是給定了輸入,然後給出輸出進行著色的程式碼,第一個引數是Input結果,第二個引數是一個inout的SurfaceOutput結構
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
// 獲取圖片 * 我們選定的顏色
//fixed4:定點書:整形資料型別,作用就是把所有數進行轉換,得到相應型別的整形表達
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
// 輸出的畫素的顏色 = 影象的顏色(RGB)
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
// 輸出的顏色效果(金屬方面) = 設定的金屬值
o.Metallic = _Metallic;
// 輸出的光滑粗糙程度 = 設定的光滑粗燥程度
o.Smoothness = _Glossiness;
// 輸出的透明通道 = 影象的透明通道
o.Alpha = c.a;
}
ENDCG//結束CG語言的編寫
}
FallBack "Diffuse"
}
結構體展示