第五章 简单顶点和片元着色器
2019-03-21 本文已影响0人
李偌闲
shader 大体结构
Shader ” MyShaderName” {
Properties {
//属性
}
SubShader {
// 针对显卡A 的SubShader
Pass {
//设置渲染状态和标签
// 开始CG 代码片段
CGPROGRAM
//该代码片段的编译指令,例如:
#pragma vertex vert
#pragma fragment frag
//CG代码写在这里
ENDCG
//其他设置
}
//其他需要的Pass
}
SubShader {
//针对显卡B 的SubShader
}
//上述SubShader 都失败后用于回调的Unity Shader
Fallback ” VertexLit”
}
#pragma vertex vert
#pragma fragment frag
它们将告诉Unity,哪个函数包含了顶点着色器的代码,哪个函数包含了片元着色器的代码。更通用的编译指令表示如下
//name 就是 两个着色器的名称 -- 函数名
#pragma vertex namexxx
#pragma fragment nameYYY
//POSITION将告诉Unity,把模型的顶点坐标填充到输入参数 v 中, SV_POSITION 将告诉Unity,顶点着色器的输出是裁剪空间中的顶点坐标
float4 namexxx (float4 v : POSITION) : SV_POSITION {
return mul(UNITY_MATRIX_MVP, v);
}
//同于告诉渲染器,把用户的输出颜色存储到一个渲染目标(render target)中,这里将输出到默认的帧缓存中
fixed4 nameYYY() : SV_Target {
return fixed4(1.0, 1.0, 1.0, 1.0);
}
顶点和片元的 输入输出结构
原理就是 定义了 顶点的输入结构,通过meshRender 来获得对应的输入信息。
定义了 片元着色器的输入结构, 这个是在顶点着色器中 来填充这个结构数据
在片元着色器中利用输入的结构 输出对应的结构。
片元着色器中的输入实际上是把顶点着色器的输出进行插值后得到的结果
// 使用一个结构体来定义顶点着色器的输入
struct a2v {
// POSITION 语义告诉Unity ,用模型空间的顶点坐标填充vertex 变量
float4 vertex : POSITION;
// NORMAL 语义告诉Unity ,用模型空间的法线方向填充normal 变量
float3 normal : NORMAL;
// TEXCOORDO 语义告诉Unity ,用模型的第一套纹理坐标填充texcoord 变量
float4 texcoord : TEXCOORDO;
};
// 使用一个结构体来定义顶点着色器的输出
struct v2f {
// SV_POSITION 语义告诉Unity, pos 里包含了顶点在裁剪空间中的位置信息
float4 pos : SV POSITION ;
// COLORO 语义可以用于存储颜色信息
fixed3 color : COLORO;
};
float4 vert(a2v v) : SV_POSITION {
声明输出结构,对应数据填充到 结构体中
v2f o;
// 使用v.vertex 来访问在模型空间的顶点坐标
o.pos = mul(UNITY—_MATRIX_MVP, v.vertex);
// v.normal 包含了顶点的法线方向,其分量范围在[-1.0, 1.0]
//下面的代码把分量范围映射到了[0.0, 1.0]
// 存储到o.color 中传递给片元着色器
o.color = v.normal * 0.5 + fixed3(0.5 , 0.5, 0.5);
return o;
}
fixed4 frag(v2f i) : SV_Target {
// 将插值后的i.color 显示到屏幕上
return fixed4(i.color, 1.0);
}
Unity 内置文件
很多时候 一些矩阵,计算公式都可以直接调 unity封装的api
image image