渲染管線
每次看都會有新的理解 反覆看吧
計劃加深normalmap的渲染並結合光照
先寫出基本結構
Shader "Practice/NormalMap"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct a2v{
};
struct v2f{
};
v2f vert(a2v v)
{
v2f o;
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
return fixed4(1,1,1,1);
}
ENDCG
}
}
}
接下來讓完成基本的一個能使用顏色調節的功能
Shader "Practice/NormalMap"
{
Properties
{
_MainColor("Main Color",COLOR)=(1,1,1,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _MainColor;
struct a2v{
float4 pos:POSITION;
};
struct v2f{
float4 worldPos:SV_POSITION;
};
v2f vert(a2v v)
{
v2f o;
o.worldPos=UnityObjectToClipPos(v.pos);
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
return _MainColor;
}
ENDCG
}
}
}
POSITION和SV_POSITION都是CG/HLSL的語義,它的返回值是一個float4類型的變量, POSITION語義告訴untiy把模型的頂點座標填充到參數pos中,SV_POSITION告訴Unity頂點着色器的輸出是裁剪空間中的頂點座標,SV_TARGET 告訴渲染器把用戶的輸出顏色儲存到一個渲染目標,這裏將輸出到默認的幀緩存中。
POSITION:頂點在模型座標系下的位置
SV_POSITION:頂點在投影空間下的位置,注意和輸入的模型座標系下的位置不同,這個字段必必須設置,這個座標轉換是頂點着色器的重要工作。在unity中定義爲:
UnityObjectToClipPos函數 找下定義 UnityCG.cginc文件中沒有定義但有這些文件Include
在UnityShaderUtilities.cginc 找到
網上搜索解釋一下 UNITY_MATRIX_M V P這幾個:define UNITY_MATRIX_M unity_ObjectToWorld:
在內置文件的定義這是幾個意思?
別名 定義 含義
UNITY_MATRIX_M unity_ObjectToWorld 模型變換矩陣
UNITY_MATRIX_V unity_MatrixV 視圖變換矩陣
UNITY_MATRIX_P glstate_matrix_projection 投影變換矩陣
UNITY_MATRIX_VP unity_MatrixVP 視圖投影變換矩陣
UNITY_MATRIX_MV mul(unity_MatrixV, unity_ObjectToWorld) 模型視圖變換
UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld) 模型視圖投影變換
下面完成Diffuse部分 頂點渲染
Shader "Practice/NormalMap"
{
Properties
{
_MainColor("Main Color",COLOR)=(1,1,1,1)
_Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
}
SubShader
{
Tags{"LightMode"="ForwardBase"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _MainColor;
fixed4 _Diffuse;
struct a2v{
float4 pos:POSITION;
float3 normal:NORMAL;
};
struct v2f{
float4 worldPos:SV_POSITION;
fixed4 finalCol:COLOR;
};
v2f vert(a2v v)
{
v2f o;
o.worldPos=UnityObjectToClipPos(v.pos);
fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
fixed3 worldNormal=normalize(mul(v.normal,unity_ObjectToWorld));
//fixed3 worldNormal=normalize(mul(v.normal,UNITY_MATRIX_M));等價
o.finalCol=_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
return v.finalCol+ambient;
}
ENDCG
}
}
}
如下是逐片元
Shader "Practice/NormalMap"
{
Properties
{
_MainColor("Main Color",COLOR)=(1,1,1,1)
_Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
}
SubShader
{
Tags{"LightMode"="ForwardBase"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _MainColor;
fixed4 _Diffuse;
struct a2v{
float4 pos:POSITION;
float3 normal:NORMAL;
};
struct v2f{
float4 worldPos:SV_POSITION;
float3 worldNormal:NORMAL0;
};
v2f vert(a2v v)
{
v2f o;
o.worldPos=UnityObjectToClipPos(v.pos);
o.worldNormal=mul(v.normal,UNITY_MATRIX_M);
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
fixed3 worldNormal=normalize(v.worldNormal);
fixed4 diffuse=_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
return diffuse+ambient;
}
ENDCG
}
}
}
在上面的shader中可以嘗試輸出顏色瞭解各種值大概的大小和幫助理解。
下面實現高光
我擦 沒保存 重寫
由於這個相對來說容易忘記 記錄下
Shader "Practice/NormalMap"
{
Properties
{
// _MainTex("MainTex",2D)="white"{}
_MainColor("Main Color",COLOR)=(1,1,1,1)
_Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
_Specular("SpecuColor",COLOR)=(1,1,1,1)
_Gloss("Gloss",Range(0,20))=8
}
SubShader
{
Tags{"LightMode"="ForwardBase"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _MainColor;
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
sampler2D _MainTex;
float4 _MainTex_ST;
struct a2v{
float4 pos:POSITION;
float3 normal:NORMAL;
float2 uv:TEXCOORD;
};
struct v2f{
float4 vertex:SV_POSITION;
float3 worldNormal:NORMAL0;
float3 worldPos:NORMAL1;
float2 uv:TEXCOORD;
};
v2f vert(a2v v)
{
v2f o;
o.vertex=UnityObjectToClipPos(v.pos);
o.worldNormal=mul(v.normal,UNITY_MATRIX_M);
o.worldPos=mul(v.pos,UNITY_MATRIX_M);
// o.uv=TRANSFORM_TEX(v.uv,_MainTex);
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
// fixed4 texCol=tex2D(_MainTex,v.uv);
fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
fixed3 worldNormal=normalize(v.worldNormal);
fixed4 diffuse=_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
fixed3 viewDir=_WorldSpaceCameraPos.xyz-v.worldPos;
fixed3 refect=normalize(normalize(_WorldSpaceLightPos0.xyz)+normalize(viewDir));
fixed4 specular=_Specular*_LightColor0* pow(saturate(dot(worldNormal,refect)),_Gloss);
//return fixed4(viewDir,1);
return specular+diffuse+ambient;
}
ENDCG
}
}
}
接着實現簡單紋理
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Practice/NormalMap"
{
Properties
{
_MainTex("MainTex",2D)="white"{}
_MainColor("Main Color",COLOR)=(1,1,1,1)
_Diffuse("DiffuseColor",COLOR)=(1,1,1,1)
_Specular("SpecuColor",COLOR)=(1,1,1,1)
_Gloss("Gloss",Range(0,20))=8
}
SubShader
{
Tags{"LightMode"="ForwardBase"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _MainColor;
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
sampler2D _MainTex;
float4 _MainTex_ST;
struct a2v{
float4 pos:POSITION;
float3 normal:NORMAL;
float2 uv:TEXCOORD;
};
struct v2f{
float4 vertex:SV_POSITION;
float3 worldNormal:NORMAL0;
float3 worldPos:NORMAL1;
float2 uv:TEXCOORD;
};
v2f vert(a2v v)
{
v2f o;
o.vertex=UnityObjectToClipPos(v.pos);
o.worldNormal=mul(v.normal,UNITY_MATRIX_M);
o.worldPos=mul(v.pos,UNITY_MATRIX_M);
o.uv=TRANSFORM_TEX(v.uv,_MainTex);
return o;
}
fixed4 frag(v2f v):SV_TARGET
{
fixed4 texCol=tex2D(_MainTex,v.uv);
fixed4 ambient=UNITY_LIGHTMODEL_AMBIENT;
fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);
fixed3 worldNormal=normalize(v.worldNormal);
fixed4 diffuse=texCol*_LightColor0*_MainColor*_Diffuse*(dot(worldNormal,worldLightDir)*0.5f+0.5f);
fixed3 viewDir=_WorldSpaceCameraPos.xyz-v.worldPos;
fixed3 refect=normalize(normalize(_WorldSpaceLightPos0.xyz)+normalize(viewDir));
fixed4 specular=_Specular*_LightColor0* pow(saturate(dot(worldNormal,refect)),_Gloss);
//return fixed4(viewDir,1);
return specular+diffuse+ambient;
}
ENDCG
}
}
}
爲什麼要定義 float4 _MainTex_ST ? TRANSFORM_TEX函數? tex2D函數?
tex2D: 紋理採樣 CG標準函數。