Shader 表面着色器语法

作者:雨辰 发布于:2014-2-23 1:06 Sunday 分类:Unity3D

Unity 的表面着色器 (Surface Shader) 是一种代码生成方法,用它来编写光照着色器比用低级的顶点/像素着色器程序容易得多

表面着色器语法结构如下:

Shader "Customer/Example" 
{
	// Properties 所有类型如下:
	// Range:定义浮点属性。显示最小值到最大值的滑块
	// Color:定义颜色属性
	// 2D:定义二维纹理属性
	// Rect:定义矩形(非 2 的幂)纹理属性
	// Cube:定义立方体贴图纹理属性
	// Float:定义浮点属性
	// Vector:定义四分量向量属性
	
	Properties 
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader 
	{
		// Tags 标签如下:
		// Queue:渲染顺序(队列标记)
		// 1、Background: 后台。这个渲染队列在其他所有队列之前被渲染。其用于天空盒之类的对象
		// 2、Geometry:几何结构。用于大多数对象。不透明的几何结构使用这种队列
		// 3、AlphaTest:alpha 测试的几何结构使用这种队列。它是一个独立于几何结构 (Geometry) 的队列,因为它可以在所有固体对象绘制后更有效地渲染采用 alpha 测试的对象
		// 4、Transparent:透明。这种渲染队列采用由后到前的顺序在几何结构 (Geometry) 和 AlphaTest 队列后渲染。任何采用 alpha 混合的对象应到这里(玻璃、粒子效果)
		// 5、Overlay:叠加。这种渲染队列用于叠加效果。任何最后渲染的对象都应放置在此(比如镜头光晕)
		// RenderType:将着色器分为若干个预定义组。
		// ForceNoShadowCasting:当给定ForceNoShadowCasting 标记并且该标记有“真”值时,使用该子着色器渲染的对象将永不投射阴影。当在透明对象上使用着色器替换、但不想从另一个子着色器获得阴影通道时,这会非常有用
		// IgnoreProjector:当给定IgnoreProjector 标记并且该标记有“真”值时,使用该着色器的对象将不会受到投影仪的影响。这对半透明对象非常有用,因为投影仪没有影响它们的好办法
		
		Tags { "RenderType" = "Opaque" }

		CGPROGRAM
		
		// 语法:#pragma surface surfaceFunction lightModel [optionalparams]
		// surfaceFunction:函数名
		// lightModel:光照模型。可以自己写也可以使用内置光照模型(Lambert 和 BlinnPhong)
		// optionalparams:
		// 1、alpha:Alpha 混合模式。将该参数用于半透明着色器
		// 2、alphatest:VariableName:lpha 测试模式。将该参数用于透明镂空着色器。镂空值在有变量名 (VariableName) 的浮点型变量中
		// 3、vertex:VertexFunction:自定义顶点修改函数
		// 4、finalcolor:ColorFunction:自定义最终颜色修改函数
		// 5、exclude_path:prepass:请勿为给定的渲染路径生成通道
		// 6、exclude_path:forward:同上
		// 7、addshadow:添加阴影投射器和集合通道
		// 8、dualforward:将双光照贴图用于正向渲染路径中
		// 9、fullforwardshadows:支持正向渲染路径中的所有阴影类型
		// 10、decal:add:附加的印花着色器
		// 11、decal:blend:半透明印花着色器
		// 12、softvegetation:使表面着色器仅在“软植被”(Soft Vegetation) 开启时被渲染
		// 13、noambient:请勿应用任何环境光照或球面调和光照 
		// 14、novertexlights:请勿在正向渲染中应用任何球面调和光照或逐顶点光照
		// 15、nolightmap:在该着色器中禁用光照贴图支持
		// 16、nodirlightmap:在该着色器中禁用方向性光照贴图支持
		// 17、noforwardadd:禁用正向渲染附加通道
		// 18、approxview:对于有需要的着色器,逐顶点而不是逐像素计算规范化视线方向
		// 19、halfasview:将半方向向量(而非视线方向向量)传递到光照函数中
		// 20、tessellate:TessFunction:使用 DX11 GPU 密铺 (tessellation)
		
		#pragma surface surf Lambert

		sampler2D _MainTex;

		// Input 的结构值包括:
		// float2 uv_:纹理坐标必须被命名为纹理名称前加 uv 或以 uv2 开头以使用第二纹理坐标集
		// float3 viewDir:视图方向,用于计算视差效果、边缘光照等
		// float4 COLOR:每个顶点颜色的插值
		// float4 screenPos:屏幕空间中的位置。 为了反射效果,需要包含屏幕空间中的位置信息
		// float3 worldPos:世界空间中的位置
		// float3 worldRefl:世界空间中的反射向量。如果表面着色器不写入法线(o.Normal)参数,将包含这个参数
		// float3 worldNormal:世界空间中的法线向量。如果表面着色器不写入法线(o.Normal)参数,将包含这个参数
		// float3 worldRefl(INTERNAL_DATA):世界空间中的反射向量。如果表面着色器不写入法线(o.Normal)参数,将包含这个参数。为了获得基于每个顶点法线贴图的反射向量需要使用世界反射向量(WorldReflectionVector(IN, o.Normal))
		// float3 worldNormal(INTERNAL_DATA):世界空间中的法线向量。如果表面着色器不写入法线(o.Normal)参数,将包含这个参数。为了获得基于每个顶点法线贴图的法线向量需要使用世界法线向量(WorldNormalVector(IN, o.Normal))
		
		struct Input 
		{
			float2 uv_MainTex; 
		};
		
		// SurfaceOutput 的结构值包括:
		// half3 Albedo; 光源反射率
		// half3 Normal; 法线
		// half3 Emission; 自发光
		// half Specular; 高光(镜面)
		// half Gloss; 高光反射中的强度系数
		// half Alpha; 透明度
		
		// 表面着色器代码
		void surf (Input IN, inout SurfaceOutput o) 
		{
			o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
		}
		ENDCG
	}
	Fallback "Diffuse"
}

标签: Unity3D-Editer Unity3D-Shader Shader

发表评论:

雨辰 joyimp|@2011-2018 京ICP备16030765号