Dirtex-HLSL语义文档:https://docs.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics?redirectedfrom=MSDN Unity-ShaderLab语义文档:https://docs.unity3d.com/cn/2020.3/Manual/SL-ShaderSemantics.html ⚠️注意:Unity并不支持全部的HLSL的语义
语义:
语义的作用: 在编写Shader的时候,从渲染流水线(RenderPipeline)中获取和修改相关数据 ⚠️注意: 由于渲染流水线(RenderPipeline)的特点,顶点着色器不能编辑片元着色器的数据,片元着色器反过来也不能修改顶点着色器的数据,因此在各个不同处理阶段的语义不一定能通用。
顶点着色器语义
几何阶段处理的数据
顶点着色器输入语义
作用: 顶点着色器能够获取到的数据 通常定义在a2v结构体内,用来将 Application 应用程序(从cpu过来)的模型数据 传输到 VertexShader 顶点着色器
用在的地方:定义VertexShader 顶点着色器时,作为传入参数
数据类型 | 语义 | 说明 |
---|---|---|
float3、float4 | POSITION | ⚪顶点位置 |
float4 | NORMAL | ⚪顶点法线 |
float4 | TANGENT | ⚪切线(用于法线贴图) |
float2、float3、float4 | TEXCOORD[n] 示例: TEXCOORD0 |
⚪纹理坐标(uv) 注:n在[0,7]之间取值 |
float4 fixed3 |
COLOR | ⚪顶点颜色 |
uint | SV_VertexID | ⚪顶点ID ⚠️注意: 需要包含编译指令 #pragma target 3.5 |
#include "UnityCG.cginc" //在这个头文件中包含事先定义好,
//顶点着色器可用的输入结构体
struct appdata_base //顶点着色器输入:顶点位置、法线、1个纹理坐标
struct appdata_tan //顶点着色器输入:顶点位置、法线、切线、1个纹理坐标
struct appdata_full //顶点着色器输入:顶点位置、法线、切线、顶点颜色、2个纹理坐标
struct appdata_img //顶点着色器输入:顶点位置、1个纹理坐标
//注:无需定义结构体,直接用
//示例
#pragma target 3.5
struct Application_To_VertexShader //a2v
{
float4 pos : POSITION;
float4 nor : NORMAL;
float2 uv : TEXCOORD0;
float4 color : COLOR;
uint vid : SV_Vertex;
};
顶点着色器输出语义
作用: 顶点着色器计算完成后返回的数据 通常定义在v2f结构体内,用来将 VertexShader 顶点着色器 处理完成的模型数据 传输到 FragmentShader 片元着色器
用在的地方:定义VertexShader 顶点着色器时,作为返回值参数 定义FragmentShader片元着色器时,作为参数传入
数据类型 | 语义 | 说明 |
---|---|---|
float4 | SV_POSITION | ⚪剪裁空间下的顶点坐标 |
float2~4 | TEXCOORD[n] | ⚪纹理坐标(UV) |
float4 fixed3 |
COLOR0 COLOR1 |
⚪顶点颜色 |
片元着色器语义
(注:DirecrX中被称为像素着色器) 栅格化阶段处理的数据
片元着色器输入语义
作用:元着色器能够获取到的数据 几何阶段处理完成后的数据 几何阶段数据处理完成后,将数据传输到 Fragment Shader 片元着色器中 ⚠️注意: VFACE、VPOS无法存在于v2f结构体内(因为顶点着色器没有输出这个数据), 因此要单独设置返回值(定义函数参数时关联语义)或者定义一个专门的片元着色器输入结构体
数据类型 | 语义 | 说明 |
---|---|---|
float4 | SV_POSITION | ⚪剪裁空间下的顶点坐标 |
float4 fixed3 |
COLOR0 COLOR1 |
⚪顶点颜色 |
float2~4 | TEXCOORD[n] | ⚪纹理坐标 |
float2 float4 UNITY_VPOS_TYPE |
VPOS | ⚪屏幕坐标(ScreenPosition) ⚠️注意: 多数平台的数据类型是float4 DirextX的数据类型是float2 为了兼容性,请使用UNITY_VOPS_TYPE 数据类型 ⚠️注意: 需要包含编译指令 #pragma target 3.0 ⚠️注意: 无法与SV_POSITION同时存在于同一个结构体 |
float | VFACE | ⚪面的朝向(表示面是否正对相加) ⚠️注意: 需要包含编译指令 #pragma target 3.0 |
片元着色器输出语义
作用:片元着色器输出的数据
数据类型 | 语义 | 说明 |
---|---|---|
fixed4 | SV_Target SV_Target[n] |
⚪渲染目标 ⚪多渲染目标技术(MRT) n的取值范围在[0,7]之间 作用:将渲染结果保存至帧缓冲区 |
fixed4 | SV_Depth | ⚪一般不修改这个值 |
示例
Shader "Hibari/VertexFragMentShader"
{
Properties
{}
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vertexShader //声明VertexShader函数
#pragma fragment fragmentShader //声明fragmentShader函数
#pragma target 3.5
//#pragma target 3.0
////////////////////////////////////////////////////////
//////////////////// 输入输出结构体 /////////////////////
////////////////////////////////////////////////////////
//顶点着色器输入输出
struct VertexInput
{
float4 pos : POSITION;
float4 nor : NORMAL;
float2 uv : TEXCOORD0;
float4 col : COLOR;
};
struct VertexOutput
{
float4 sv_pos : SV_POSITION;
float2 uv : TEXCOORD0;
float4 col : COLOR0;
};
//片元着色器输入输出
struct fragmentInput
{
float4 sv_pos : SV_POSITION;
float2 uv : TEXCOORD0;
fixed3 col : COLOR0;
//UNITY_VPOS_TYPE ScreenPos : VPOS; //无法与SV_POSITION同时存在于同一个结构体
float vf : VFACE;
};
struct fragmentOutput
{
fixed4 renderOutput : SV_Target;
};
////////////////////////////////////////////////////////
/////////////////////// Shader函数 /////////////////////
////////////////////////////////////////////////////////
//顶点着色器函数
VertexOutput vertexShader(VertexInput input)
{
VertexOutput output;
output.sv_pos = UnityObjectToClipPos(input.pos);
output.col = input.nor;
return output;
}
//片元着色器函数
fragmentOutput fragmentShader(fragmentInput input)
{
fragmentOutput output;
output.renderOutput = fixed4(input.col, 1.0);
return output;
}
ENDCG
}
}
}