區(qū)分Unity 中3大Shader
沒有嵌套CG語言,也就是代碼段中沒有CGPROGARAM和ENDCG關(guān)鍵字的粟誓,就是固定功能著色器。
嵌套了CG語言,代碼段中有surf函數(shù)的蒜埋,就是表面著色器。
嵌套了CG語言毅臊,代碼段中有#pragma vertex name和 #pragma fragment frag聲明的理茎,就是頂點著色器&片段著色器黑界。
從這里開始不加;會報錯
Shader "Sbin/vf" {
SubShader {
pass{
//CG代碼寫到限定范圍內(nèi)
CGPROGRAM
//CG類似類的聲明 都要小寫不然不報錯也不顯示
#pragma vertex vert
#pragma fragment frag
//頂點 //變量 傳入 2階向量 //傳出一個四階 pos
void vert(in float2 objPos:POSITION,out float4 pos:POSITION)
{
pos=float4(objPos,0,1);
}
//COLOR=COLOR0
void frag(out float4 col:COLOR0)
{
col=float4(1,0,0,1);
}
ENDCG
}
}
}
然后成了這樣 說是以后再解釋 我的Game視圖什么也看不見 視屏卻有
Shader "Sbin/vf" {
SubShader {
pass{
//CG代碼寫到限定范圍內(nèi)
CGPROGRAM
//CG類似類的聲明 都要小寫不然不報錯也不顯示
#pragma vertex vert
#pragma fragment frag
//頂點 //變量 傳入 2階向量 //傳出一個四階 pos
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=float4(0,0,1,1);//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
}
//COLOR=COLOR0 片段著色器
void frag(inout float4 col:COLOR)
{
col=float4(0,1,0,1);
}
ENDCG
}
}
}
還是顯示不出來 運行會報錯但是不知道哪里錯了
找到原因了
把matrail的渲染隊列調(diào)為transparent
然后就Game視圖有圖了 但是還是運行會報
右邊顯示沒有錯誤 很神奇
這是人家視頻的效果
Shader "Sbin/vf" {
SubShader{
pass {
//CG代碼寫到限定范圍內(nèi)
CGPROGRAM
//CG類似類的聲明 都要小寫不然不報錯也不顯示
#pragma vertex vert
#pragma fragment frag
//頂點 //變量 傳入 2階向量 //傳出一個四階 pos
void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
{
pos = float4(objPos,0,1);
col = pos;//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
}
//COLOR=COLOR0 片段著色器
void frag(inout float4 col:COLOR)
{
//col = float4(0,1,0,1);
}
ENDCG
}
}
}
我換了2018版本的就好了但是圖是反過來的
CG基本數(shù)據(jù)類型
float half fixed bool int sampler*
頂點和片段profile是某硬件可支持的預算的一種特性
Shader "Sbin/vf" {
SubShader{
pass {
//CG代碼寫到限定范圍內(nèi)
CGPROGRAM
//CG類似類的聲明 都要小寫不然不報錯也不顯示
#pragma vertex vert
#pragma fragment frag
//頂點 //變量 傳入 2階向量 //傳出一個四階 pos
void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
{
pos = float4(objPos,0,1);
col = pos;//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
}
//COLOR=COLOR0 片段著色器
void frag(inout float4 col:COLOR)
{
//col = float4(0,1,0,1);
fixed r=-0.5;
fixed g=-0.5;
fixed b=0;
fixed a=0;
//CG里的構(gòu)造器
col=float4(r,g,b,a);
//CG的基本類型 根據(jù)不同精度定義的數(shù)據(jù)類型 CG不含有指針
//fixed1=fixed 描述的是9位整數(shù)被規(guī)格化到-1到1 就是2的8次方 256跟顏色的最大值對應(yīng)
//fixed2=fixed(1,0);
//float可以變?yōu)閒loat2 float3 float4 沒有五階
//half half2 half3 half4
//fixed fixed2 fixed3 fixed4
}
ENDCG
}
}
}
![image.png](https://upload-images.jianshu.io/upload_images/15146729-5666734f1a3c801e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
官方已經(jīng)到了5.0 DX11
Shader "Sbin/vf" {
SubShader{
pass {
//CG代碼寫到限定范圍內(nèi)
CGPROGRAM
#include "UnityCG.cginc"
//CG類似類的聲明 都要小寫不然不報錯也不顯示
#pragma vertex vert
#pragma fragment frag
//定義宏
#define MACROFL FL4(fl4.ab,fl3.zy);
typedef float4 FL4;//聲明別名
//結(jié)構(gòu)體 2018新版本不能為空
struct v2f{
float4 pos:POSITION;
float2 uv:TEXCOORD0;
};
//頂點 //變量 傳入 2階向量 //傳出一個四階 pos
void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
{
pos = float4(objPos,0,1);
col = pos;//也可以這樣賦值 不過frag里的col賦值會覆蓋這個
}
//COLOR=COLOR0 片段著色器
void frag(inout float4 col:COLOR)
{
//col = float4(0,1,0,1);
fixed r=-0.5;
fixed g=-0.5;
fixed b=0;
fixed a=0;
//CG里的構(gòu)造器
col=float4(r,g,b,a);
bool bl=false;
col=bl?col:fixed4(0,1,0,1);//true是黑 false是綠
//int 一般會被當作float使用
//描述是幾維向量
float2 fl2=float2(1,0);
float3 fl3=float3(1,0,1);
float4 fl4=float4(1,1,0,1);
//Swizzle操作
//float4 fl=float4(fl2,0,1);//紅色
//float4 fl=float4(fl2.xy,0,1);//xyzw 或者 rgba按照一定順序去取可以截取這個值
//float4 fl=float4(fl4.wzyx);//紫色
//float4 fl=float4(fl4.ab,fl3.zy);//紫色
//宏的使用
FL4 fl=MACROFL //紫色
col=fl;
//CG的基本類型 根據(jù)不同精度定義的數(shù)據(jù)類型 CG不含有指針
//fixed1=fixed 描述的是9位整數(shù)被規(guī)格化到-1到1 就是2的8次方 256跟顏色的最大值對應(yīng)
//fixed2=fixed(1,0);
//float可以變?yōu)閒loat2 float3 float4 沒有五階
//half half2 half3 half4
//fixed fixed2 fixed3 fixed4
//2行4列的矩陣 通常用4x4不會報錯但是會黃色警告
// float2x4 M2x4={1,0,0,1,0,1,0,1};//便于閱讀也可以{(1,0,0,1),(0,1,0,1)}
float4x4 M2x4={1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0};
col=M2x4[0];//取矩陣第一行 紅色
col=M2x4[1];//取矩陣第二行 綠色
//數(shù)組
float arr[4]={1,0.5,0.5,1};//橙紅色
col=float4(arr[0],arr[1],arr[2],arr[3]);
//結(jié)構(gòu)體賦值 改值操作
v2f o;
o.pos=fl4;
o.uv=fl2;
}
ENDCG
}
}
}
CG的條件語句
if..else
while
Do...while
for
switch...case(有用但是最好別用皂林,沒有良好的支持朗鸠,容易亂)
我這邊試的也有錯
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
if(pos.x<0 && pos.y<0)
{
col=float4(1,0,0,1);
}
else if(pos.x<0)
{
col=float4(0,1,0,1);
}
else if(pos.y>0)
{
col=float4(1,1,0,1);
}
else
{
col=float4(0,0,1,1);
}
//col=pos;
}
void frag(inout float4 col:COLOR)
{
//最好別用有一定問題 用if else代替
// int i=0;
// switch(i)
// {
// case 0:
// col=float4(1,0,0,1);
// break;
// case 1:
// col=float4(0,1,0,1);
// break;
// case 2:
// col=float4(0,0,1,1);
// break;
// }
}
ENDCG
}
}
}
老師是這樣的我的進不來
之后的還可以
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=pos;
}
void frag(inout float4 col:COLOR)
{
//測試while
int i=0;
while(i<10)
{
i++;
}
if(i==10)
{
col=float4(0,0,0,1);
}
//看下do while
i=0;
do{
i++;
}
while(i<10);
if(i=10)
col=float4(1,1,1,1);
//for 循環(huán)有上限 老師的是1023 我的直接報黃說被迫執(zhí)行一次循環(huán)
i=0;
for(i=0;i<10;i++)
{
if(i=10)
col=float4(0.5f,0.5f,0,1);
}
}
ENDCG
}
}
}
這個也動不了 之后把上面提示的錯誤信息刪掉就好了
// Upgrade NOTE: excluded shader from DX11, OpenGL ES 2.0 because it uses unsized arrays
#pragma exclude_renderers d3d11 gles
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
// Upgrade NOTE: excluded shader from DX11, OpenGL ES 2.0 because it uses unsized arrays
#pragma exclude_renderers d3d11 gles
#pragma vertex vert
#pragma fragment frag
void Func(out float4 c);
float Func2(float arr[2])
{
float sum=0;
for (int i=0;i<arr.Length;i++)
{
sum+=arr[i];
}
return sum;
}
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=pos;
}
void frag(inout float4 col:COLOR)
{
//Func(col);
//維度必須相同傳遞 沒有維度不行
float arr[]={0.5,0.5};
//我的Func2掛掉了 說我的GPU不支持明暗編輯器
col.x= Func2(arr);
}
//函數(shù)必須在調(diào)用之前 或者在之前聲明
void Func(out float4 c)
{
//CG參數(shù)以值拷貝進行傳遞
c=float4(0,1,0,1);
}
ENDCG
}
}
}
自定義函數(shù)
這樣每次在頭聲明函數(shù)很麻煩
創(chuàng)建一個cginc的文件
里面放自己的函數(shù)
//函數(shù)必須在調(diào)用之前 或者在之前聲明
void Func(out float4 c)
{
//CG參數(shù)以值拷貝進行傳遞
c=float4(0,1,0,1);
}
float Func2(float arr[2])
{
float sum=0;
for (int i=0;i<arr.Length;i++)
{
sum+=arr[i];
}
return sum;
}
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//自定義函數(shù)
#include "sbin.cginc"
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=pos;
}
void frag(inout float4 col:COLOR)
{
Func(col);
//維度必須相同傳遞 沒有維度不行
float arr[2]={0.5,0.5};
//我的Func2掛掉了 說我的GPU不支持明暗編輯器 把上面自動生成的提示刪了就好了
col.x= Func2(arr);
}
ENDCG
}
}
}
是黃色
當Shader和.cginc在同一目錄情況下可以直接名字引用
如果放在不同文件夾 應(yīng)該是安路徑找 但是我的就可以直接用 回報黃 然后多試了幾下還是會報錯 第一個是我放的文件夾 建議這么寫
include "Cginc/sbin.cginc"
找到unity安裝包路徑 這個就是unity自帶的CG庫 我們可以調(diào)用 為我們節(jié)省很多時間
Editor/Data/CGIncludes(MAC下是Content/CGIncludes)
Unity函數(shù)
這個文庫很全
https://wenku.baidu.com/view/3a9db318fad6195f312ba675.html
常用的lerp(a,b,f)是個差值
感覺像是個max()min()結(jié)合體
還有這個sin cos結(jié)合函數(shù)
就是把矩陣行變成列
這個模 就是向量v開平方相加除根號
為什么這么簡單的要封裝起來,因為他們的算是優(yōu)化速度最快的础倍,自己寫的話不一定有他們快 就跟自己Json寫的序列化反序列化 不如人家谷歌那群人寫的Protobuf得快
這個是Shader源碼
https://github.com/1004019267/ShaderTest/tree/master