在Unity中,不管什么种类的Shader,都是基于顶点片元着色器(Vertex Fragment Shader)制作的
完整案例
Shader "Hibari/VertexFragMentShader"{SubShader{pass{CGPROGRAM#pragma vertex vert //声明VertexShader函数#pragma fragment frag //声明fragmentShader函数/*输入结构体:将数据从应用程序发送至顶点着色器*/struct a2v{float4 vertex : POSITION; //传入顶点坐标float4 normal : NORMAL; //传入顶点法向float4 texcoord : TEXCOORD0; //传入纹理坐标};/*输出结构体:从顶点着色器获取数据,并输出至片元着色器*/struct v2f{float4 myPosition : SV_POSITION; //从剪裁空间中获取顶点坐标fixed3 myColor : COLOR0; //获取顶点色};/*定义顶点着色器函数*/v2f vert(a2v input){v2f output;output.myPosition = UnityObjectToClipPos(input.vertex);output.myColor = input.normal;return output;}/*定义片元着色器函数*/fixed4 frag(v2f input) : SV_Target{return fixed4(input.myColor, 1.0);}ENDCG}}}
编译指令
编译指令用来告诉 着色器的函数 名字叫什么
注:虽然名字可以自定义,但通常会约定一个名字 vert:顶点着色器函数(Vertex Shader Function) frag:片元着色器函数(Fragment Shader Function)
#pragma vertex [function Name] //声明VertexShader函数#pragma fragment [function Name] //声明fragmentShader函数
语义
在定义【变量或函数】时,后面会带一个【冒号+单词】,这个单词就是语义。
语义的作用: 在Shader编程过程中,我们需要获取渲染流水线中相关的模型数据 语义的作用就是,将【渲染流水线中相关的数据】与【函数、变量做关联】 通过变量达到读取数据和返回输出数据
//语法Type varName : [语义] //将变量与语义做关联(表示读取)tpye functionName() : [语义] //将返回值与语义做关联(表示输出)typeA functionName(TypeB varName : [语义])//将输入的参数与语义做关联,//和返回值具有相同的功能(表示输出)//示例float4 vertex : POSITION;fixed4 frag(v2f input) : SV_Target{return fixed(1,1,1,1);}
顶点着色器输入输出结构体
有时候函数输入或者输出多个语义数据时,当个变量会不方便,做一个结构体会比较方便使用
a2v:应用程序输入到顶点着色器
a2v(Application To VertexShader) Application 应用程序(从cpu过来的模型数据) VertexShader 顶点着色器 将数据从应用程序中读取到顶点着色器
//示例struct a2v{float4 vertex : POSITION; //传入顶点坐标float4 normal : NORMAL; //传入顶点法向float4 texcoord : TEXCOORD0; //传入纹理坐标};
v2f:从顶点着色器到片元着色器
v2f(VertexShader To FragmentShader) VertexShader 顶点着色器 FragmentShader 片元着色器 将顶点数据输出到片元着色器
//示例struct v2f{float4 myPosition : SV_POSITION; //从剪裁空间中获取顶点坐标fixed3 myColor : COLOR0; //获取顶点色};
着色器函数
顶点与片元着色器算法主要就写在这里面 vert:表示顶点着色器函数(VertexShaderFunction) frag:表示片元着色器函数(FragmentShaderFunction)
Vert:顶点着色器函数
顶点着色器函数需要从【应用程序】获取数据到【顶点着色器】,所以【函数参数a2v类型】 顶点着色器函数运算完成后,需要将数据输出到【片元着色器】,所以【返回值为v2f类型】
v2f vert(a2v input){v2f output;//修改数据output.myPosition = UnityObjectToClipPos(input.vertex); //编辑顶点坐标output.myColor = input.normal; //编辑顶点颜色return output;}
Frag:片元着色器函数
片元着色器需要从【顶点着色器】获取已经【运算完成信息】,所以【函数参数v2f类型】
注:片元着色器在运算完成后,只有一个信息(即将渲染结果保存到帧缓存) 因此不需要额外定义一个结构体,直接将函数的返回值与SV_Taregt做关联即可。
fixed4 frag(v2f input) : SV_Taregt{return fixed4(input.myColor, 1.0);}
