顶点片元着色器

作者:追风剑情 发布于:2014-6-17 21:59 分类:Shader

   顶点片元着色器不使用灯光交互,实际着色器代码用CG或HLSL语言编写,嵌入在着色器的通道块中。在着色器开始处,可以使用编译指令#pragma,常用编译指令如表所示:

顶点片元着色器常用编译指令

编译指令 说明
#pragma vertex <name> 声明以name为名字的函数是顶点程序
#pragma fragment <name>
声明以name为名字的函数是片元程序
#pragma fragmentoption <option>
添加选项到编译的OpenGL片元程序,通过OpenGL的ARB_fragment_program可以查询到所允许的规范的选项列表。这个指令对顶点程序或者不是以OpenGL为编译目标的程序无效。
#pragma target <name>
着色器目标编译
#pragma only_renderers <names>
仅用给定的渲染器编译着色器。默认情况下用所有的渲染器都编译着色器。当选择多个渲染器时用空格隔开
#pragma exclude_renderers <names>
不用给定的渲染编译着色器。默认情况下用所有的渲染器都编译着色器。当选择多个渲染器时用空格隔开
#pragma glsl
用桌面OpenGL平台编译着色器时,将Cg/HLSL转换成GLSL而不是默认的ARB顶点片元着色器

提示

   每个顶点片元着色器必须包含一个顶点程序或者片元程序(或者两者兼有),因此需要一个#pragma vertex命令或者#pragma fragment命令(或者两者兼有)。

   默认情况,Unity将顶点程序编译成着色模型1.1(Shader Model1.1),片元程序将编译成着色模型(Shader Model2.0)。使用#pragma target将着色器编译成其他兼容的等级。目前支持下面这些目标。

#pragma target default

编译成默认目标,在Direct3D 9环境中编译成顶点着色器1.1(Vertex Shader1.1)和像素着色器2.0(Pixel Shader2.0)。

ARB_vertex_program有128个指令限制,ARB_fragment_program有96个指令限制(32个纹理+64位算术运算),16个临时寄存器和4个间接纹理。

#pragma target 3.0

编译成着色模型3.0(Shader Model3.0),在Direct3D 9环境中编译成顶点着色器3.0(Vertex Shader3.0)和像素着色器3.0(Pixel Shader3.0)。

ARB_vertex_program没有指令限制,ARB_fragment_program有1024位指令限制(512位纹理+512位算术运算),32个临时寄存器和4个间接纹理。可以使用#pragma profileoption命令扩展这些限制值。如:#pragma profileoption MaxTexIndirections=256增加间接纹理上限到256个。

提示

   编译成着色模型3.0时,顶点和片元程序需要同时存在。着色模型(Shader Model)是Direct3D的标准,由顶点着色器(Vertex Shader)和像素着色器(Pixel Shader)两个着色语言规范组成,和本书中的顶点程序、片元程序在本质上是一样的。

   Unity支持多种渲染API(比如:Direct3D 9 和 OpenGL),默认情况下被支持的渲染器会编译所有着色器程序,但可以使用#pragma only_renderers或#pragma exclude_renderers指令来指定渲染器编译着色器。目前支持的渲染器如表所示。

Unity渲染器

渲染器 渲染器指令代码
Direct3D 9 d3d9
OpenGL opengl
OpenGL ES 2.0 gles
Xbox 360 xbox360
PlayStation 3 ps3
Flash flash

下面的代码片段表示只用Direct3D 9渲染器编译着色器:

#pragma only_renderers d3d9

   CG顶点程序必须在结构体中传递顶点数据。几种常用的顶点结构体定义在文件UnityCG.cginc中。在大部分情况下仅仅使用它们就够了。主要结构体如下所列。

appdata_base

包含顶点位置、法线和一个纹理坐标。

appdata_tan

包含顶点位置、切线、法线和一个纹理坐标。

如果想访问个别的顶点数据,必须另外声明顶点结构体。结构体中的成员必须是表中所列出的成员。

顶点结构体成员

成员 说明
float4 vertex 顶点位置
float3 normal 顶点法线
float4 texcoord 第一UV坐标
float4 texcoord1 第二UV坐标
float4 tangent 切线向量(用在法线贴图中)
float4 color 每个顶点(per-vertex)颜色

以下着色器代码通过顶点程序输入结构体使用了顶点位置和第一纹理坐标。这在网格中调式UV坐标是非常有用的。UV坐标是可见的红色和绿色,坐标以外应用的是取值范围在0到1之间的蓝色值:

Shader "!Debug/UV 1" {
SubShader {
	Pass {
		Fog { Mode Off }
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		struct appdata {//顶点输入结构体
			float4 vertex : POSITION;//顶点坐标
			float4 texcoord : TEXCOORD0; //第一UV坐标
		};
		struct v2f {
			float4 pos : SV_POSITION;//纹理坐标
			float4 uv : TEXCOORD0;//第一UV坐标
		};
		v2f vert (appdata v) { //顶点程序
			v2f o;
			o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//计算顶点位置
			o.uv = float4(v.texcoord.xy, 0, 0);//计算UV坐标
			return o;
		}
		half4 frag(v2f i) : COLOR {//片元程序
			half4 c = frac(i.uv);
			if (any(saturate(i.uv) - i.uv))//计算片元颜色
				c.b = 0.5;
			return c;
		}
		ENDCG
	}
}
}

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号