unity shader 可编程管线(二) 顶点和片段着色器(Vertex Shader and Fragmet Shader)

顶点着色器和片段着色器。

可编程Shader的特点为:

    • 功能最强大、最自由的形态。
    • 特征是在Pass里出现CGPROGRAM和ENDCG块
    • 编译指令#pragma。详见官网Cg snippets。其中重要的包括:

编译指令

示例/含义

#pragma vertex name
#pragma fragment name

替换name,来指定Vertex Shader函数、Fragment Shader函数。

#pragma target name

替换name(为2.0、3.0等)。设置编译目标shader model的版本。

#pragma only_renderers name name ...
#pragma exclude_renderers name name...

#pragma only_renderers gles gles3,
#pragma exclude_renderers d3d9 d3d11 opengl,
只为指定渲染平台(render platform)编译

    • 关于引用库。通过形如#include "UnityCG.cginc"引入指定的库。常用的就是UnityCG.cginc了。其他库详见官网Built-in shader include files
    • ShaderLab内置值。Unity给Shader程序提供了便捷的、常用的值,比如下面例子中的UNITY_MATRIX_MVP就代表了这个时刻的MVP矩阵。详见官网ShaderLab built-in values
    • Shader输入输出参数语义(Semantics)。在管线流程中每个阶段之间(比如Vertex Shader阶段和FragmentShader阶段之间)的输入输出参数,通过语义字符串,来指定参数的含义。常用的语义包括:COLOR、SV_Position、TEXCOORD[n]。完整的参数语义可见HLSL Semantic(由于是HLSL的连接,所以可能不完全在Unity里可以使用)。
    • 特别地,因为Vertex Shader的的输入往往是管线的最开始,Unity为此内置了常用的数据结构:

数据结构

含义

appdata_base

顶点着色器输入位置、法线以及一个纹理坐标。

appdata_tan

顶点着色器输入位置、法线、切线以及一个纹理坐标。

appdata_full

顶点着色器输入位置、法线、切线、顶点颜色以及两个纹理坐标。

appdata_img

顶点着色器输入位置以及一个纹理坐标。


例子如下:

Shader "基础/简单的顶点和片段着色器" 
{
	//-------------------------------【属性】--------------------------------------
	Properties 
	{
		_Color ("Color", Color) = (1.0,1.0,1.0,1.0)
		_SpecColor ("Specular Color", Color) = (1.0,1.0,1.0,1.0)
		_Shininess ("Shininess", Float) = 10
	}

	//--------------------------------【子着色器】--------------------------------
	SubShader 
	{
		//-----------子着色器标签----------
		Tags { "LightMode" = "ForwardBase" }

		//----------------通道---------------
		Pass 
		{
			//-------------------开始CG着色器编程语言段-----------------  
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			//---------------声明变量--------------
			uniform float4 _Color;
			uniform float4 _SpecColor;
			uniform float _Shininess;
			
			//--------------定义变量--------------
			uniform float4 _LightColor0;
			
			//--------------顶点输入结构体-------------
			struct vertexInput 
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};

			//--------------顶点输出结构体-------------
			struct vertexOutput 
			{
				float4 pos : SV_POSITION;
				float4 col : COLOR;
			};
			
			//--------------顶点函数--------------
			vertexOutput vert(vertexInput v)
			{
				vertexOutput o;
				
				//一些方向
				float3 normalDirection = normalize( mul( float4(v.normal, 0.0), _World2Object ).xyz );
				float3 viewDirection = normalize( float3( float4( _WorldSpaceCameraPos.xyz, 1.0) - mul(_Object2World, v.vertex).xyz ) );
				float3 lightDirection;
				float atten = 1.0;
				
				//光照
				lightDirection = normalize(_WorldSpaceLightPos0.xyz);
				float3 diffuseReflection = atten * _LightColor0.xyz * max( 0.0, dot( normalDirection, lightDirection ) );
				float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb * max( 0.0, dot( normalDirection, lightDirection ) ) * pow( max( 0.0, dot( reflect( -lightDirection, normalDirection ), viewDirection ) ), _Shininess );
				float3 lightFinal = diffuseReflection + specularReflection + UNITY_LIGHTMODEL_AMBIENT;
				
				//计算结果
				o.col = float4(lightFinal * _Color.rgb, 1.0);//颜色
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//位置
				return o;
			}
			
			//--------------片段函数---------------
			float4 frag(vertexOutput i) : COLOR
			{
				return i.col;
			}

			//-------------------结束CG着色器编程语言段------------------
			ENDCG
		}
	}
	//备胎
	Fallback "Diffuse"
	
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值