Unity Shader(顶点片元着色器Vertex&Fragment)

编译指令

编译指令 功能:告知编辑器顶点和片段着色函数的名称

顶点着色器的编译指令

每有一个顶点执行一次

#pragma vertex vert

片元着色器的编译指令

每有一个像素就执行一次

#progma fragment frga

顶点语义绑定

顶点的模型坐标 float4 POSITION
顶点的屏幕坐标 float4 SV_POSITION
顶点的法线向量坐标 float3 NORMAL
第一个UV坐标 float4 TEXCOORD0
第二个...第四个UV坐标 float4 TEXCOORD1...3
顶点切线向量坐标 float4 TENGENT
顶点颜色值 float4 COLOR

 常用函数库

辅助为跨平台的着色器编译宏和定义 HLSLSupport.cginc
常用全局变量 UnityShaderVariables.cginc
常用辅助函数 UnityCG.cginc
光、影函数 AutoLight.cginc
光照模型相关 Lighting.cginc
地形植被辅助 TerrainEngine.cginc
注意:函数库的源码地址Unity地址\Data\CGIncludes

UnityCG常用函数(UnityCG函数解释

将顶点模型坐标转换为顶点屏幕坐标 UnityObjectToClipPos

实例(SubShader中必须要有Pass通道)

        纯色Shader

顶点函数 参数

每个顶点的坐标位置

语义绑定:POSITION(坐标位置)

float4

返回值

每个顶点的像素位置

语义绑定:SV_POSITION(像素位置)

float4

作用:将三维空间坐标投影到二维窗口
片段函数 参数
返回值

片段颜色值
语义绑定:COLOR(颜色RGBA)

float4

作用:设置像素颜色

        彩色Shader

顶点着色器输出结构体

空间位置:float4 position:SV_POSITION

0级纹理坐标:float4 color:TEXCOORD0

顶点函数 参数

每个顶点的坐标位置

语义绑定:POSITION(坐标位置)

float4

返回值 输出结构体
作用:将顶点当作色彩参数赋值
片段函数 参数 顶点着色器输出结构体
返回值 片段颜色
作用:直接将顶点输出的颜色设置到像素中显示

         漫反射

进入库 #include "UnityCG.cginc"
顶点输入结构体 顶点位置

(float4)语义绑定:POSITION

法线

(float3)语义绑定:NORMAL

顶点输出结构体 像素位置

(float4)语义绑定:SV_POSIITON

法线

(float3)语义绑定:NORMAL

全局变量声明 光照颜色(內部值)

(float4)_LightColor0

漫反射颜色(属性)
顶点函数 输入结构体——输入
输出结构体——输出
步骤

矩阵变换

计算法线

输入法线扩充 float4(input.normal,0.0)

內部值 unity_WorldToObject

法线计算(固定公式

mul(float4(input.normal,0.0),unity_WorldToObject).xyz

片段函数 顶点输出结构体 输入
语义绑定(COLOR) 输出
步骤

获取输入法线方向(float3)

normalize(input.normal)

获取入射光线法线方向(float3)

normalize(_WorldSpaceLightPos0.xyz)

备注:_WorldSpaceLightPos0(入射光方向)

计算漫反射值(float3)

公式

正向渲染公式

Diffuse=LightColor*MainColor*Max(0,dot(N,L))

变量解释 LightColor(光照颜色)
MainColor(漫反射颜色)
入射光(N)
光照法线(L)

合并环境光(float4)

漫反射扩充 float4 (diffuse,1.0)
添加环境光 +UNITY_LIGHTMODEL_AMBIENT
返回结果
注意:需要在Pass通道中设置Tags为正向渲染
                "LightMode" = "ForwardBase"(光照模式设置成正向渲染)
//  顶点着色器的编译指令
//  每有一个顶点就执行一次
#pragma vertex vert
//  片元着色器的编译指令
//  每有一个像素就执行一次
#pragma fragment frag

#include "UnityCG.cginc"

    //  顶点输入结构体
    struct appdata
    {
        //  顶点模型坐标
        half4 vertexPos:POSITION;
        //  顶点法线向量
        half3 vertexNormal:NORMAL;
    };

    //  顶点输出结构体	
    struct v2f 
    {
        //  顶点屏幕坐标
        half4 screenPos:SV_POSITION;
        //  顶点屏幕法线
        half3 screenNormal:NORMAL;
	};

	//  声明漫反射颜色属性
	half4 _DiffuseCol;
	//  光照颜色【内部变量】
	half4 _LightColor0;

	//  顶点函数
	v2f vert(appdata data)
	{
		//  顶点输出结构体对象
		v2f o;
		//  将顶点模型坐标转换为顶点屏幕坐标
		o.screenPos = UnityObjectToClipPos(data.vertexPos);
		//  将顶点模型法线转换为顶点屏幕法线
		o.screenNormal = mul(half4(data.vertexNormal,1),unity_WorldToObject).xyz;
		//  返回结果
		return o;
	}

	//  片元函数
	half4 frag(v2f vertexInput):COLOR
	{
		//  求入射光线的单位向量
		half3 lightDir = normalize(_WorldSpaceLightPos0);
		//  求法线向量的单位向量
		half3 normalDir = normalize(vertexInput.screenNormal);
		//  通过漫反射公式计算所得每个像素的颜色【兰伯特】
		//half3 diffuseColor = _DiffuseCol.rgb * _LightColor0.rgb * max(0,dot(lightDir,normalDir));
		//  通过漫反射公式计算所得每个像素的颜色【半兰伯特】
		half3 diffuseColor = _DiffuseCol.rgb * _LightColor0.rgb * (0.5 * (dot(lightDir,normalDir) + 0.5));
		//  添加漫反射颜色再加上环境光
		return half4(diffuseColor,1) + UNITY_LIGHTMODEL_AMBIENT;
	}

猜你喜欢

转载自blog.csdn.net/qq_24977805/article/details/123041148
今日推荐