《Unity Shader入门精要》学习笔记第三章 Unity Shader基础

本文章用于帮助自己学习,因此只记录一些个人认为比较重要或者还不够熟悉的内容。
原作者:http://blog.csdn.net/candycat1992/article/

第三章 Unity Shader基础

3.1Unity Shader概述

最常见的流程:
由一个三维场景生成一张二维图像。
(1) 创建一个材质;
(2) 创建一个Unity Shader,并把它赋给上一步中创建的材质:
(3) 把材质赋给要渲染的对象;
(4) 在材质面板中调整Unity Shader的属性,以得到满意的效果。

3.2ShaderLab

Unity Shader是Unity为开发者提供的高层级的渲染抽象层。

在Unity中,所有的Unity Shader都是用ShaderLab来编写的。ShaderLab是Unity提供的编写Unity Shader的一种说明性语言。

3.3Unity Shader的结构

3.3.1给Shader起名

Shader "Custom/MyShader"

通过在字符串中添加斜杠(“/”),可以控制Unity Shader在材质面板中出现的位置。

3.3.2Properties

Properties语义块中包含了一系列属性(property), 这些属性将会出现在材质面板中。

Properties
    {
       Name ("display name", PropertyType) = DefaultValue
    }

Name是属性的名字,一般由一个下划线开始。
display name显示在材质面板上的名字。
PropertyType是属性的类型
等号后面的DefaultValue就是需要给属性指定的默认值

  • Properties语义块支持的属性类型

属性类型 默认值的定义语法 例子
Int number ("Int”, Int) = 2
Float number Float ("Float”, Float) = 1.5
Range(min,max) number _Range(“Range”, Range(0.0, 5.0)) = 3.0
Color (number,number,number,number) Color ("Color”, Color) = (1,13,1)
Vector (number,number,number,number) _Vector (“Vector”, Vector) = (2, 3, 6, 1)
2D “defaulttexture” {} _2D ("2D”, 2D) = ”” {}
3D “defaulttexture” {} 3D(”3D”,3D) = "black” ()
Cube “defaulttexture” {} _Cube (“Cube”, Cube) = “white” (}

3.3.3SubShader

SubShader语义块中包含的定义通常如下:

SubShader {
//可选的
[Tags]
//可选的
[RenderSetup]
Pass (
}
// Other Passes

SubShader中定义了一系列Pass以及可选的状态([RenderSetup])和标签([Tags])设置。每个Pass定义了一次完整的渲染流程。状态和标签同样可以在Pass声明,但是,如果在Shader进行了这些设置,那么将会用于所有的Pass

  • 状态设置可以设置显卡的各种状态。

表3.2

常见的渲染状态设置选项

状态名称

设置指令

解 释

Cull

Cull Back | Front | Off

设置剔除模式:剔除背面/正面/关闭 剔除

ZTest

ZTest Less Greater | LEqual | GEqual | Equal | NotEqual | Always

设置深度测试时使用的函数

ZWrite

ZWrite On | Off

开启/关闭深度写入

Blend

Blend SrcFactor DstFactor

开启并设置混合模式

当在SubShader块中设置了上述渲染状态时,将会应用到所有的Pass。

  • SubShader 的标签
    SubShader的标签(Tags)是一个键值对(Key/Value Pair),它的键和值都是字符串类型。它们用来告诉Unity的渲染引擎:SubShader我希望怎样以及何时渲染这个对象
Tags { "TagName1" = "Valuel" "TagName2" ="Value2" }

表3.3

SubShader的标签类型

标签类型

说 明

例 子

Queue

控制渲染顺序,指定该物体属于哪一个渲染队列,通 过这种方式可以保证所有的透明物体可以在所有不透 明物体后面被渲染(详见第8章),我们也可以自定义 使用的渲染队列来控制物体的渲染顺序

Tags ("Queue'1 = "Transparent" }

RenderType

对着色器进行分类,例如这是一个不透明的着色器, 或是一个透明的着色器等。这可以被用于着色器替换

(Shader Replacement)功能

Tags {"RenderType" = "Opaque" }

DisableBatching

一些S泌S/wd”在使用Unity的批处理功能时会出现问 题,例如使用了模型空间下的坐标进行顶点动画(详 见11.3节)。这时可以通过该标签来直接指明是否对该 SubShader使用批处理

Tags ("DisableBatching" = "True" }

ForceNoShadowCasting

控制使用该SubShader的物体是否会投射阴影(详见

8.4 节)

Tags { "ForceNoShadowCasting"= "True” }

IgnoreProjector

如果该标签值为“True”,那么使用该SubShader的物 体将不会受Projector的影响。通常用于半透明物体

Tags ('IgnoreProjector" = "True" }

CanUseSpriteAtlas

当该SubShade矿是用于精灵(sprites)时,将该标签设 为 “False”

Tags {"CanUseSpriteAtlas" = "False"}

PreviewType

指明材质面板将如何预览该材质。默认情况下,材质 将显示为一个球形,我们可以通过把该标签的值设为 “Plane” “SkyBox”来改变预览类型

Tags ( "PreviewType” = "Plane" }

上述标签仅可以在SubShader中声明,而不可以在Pass块中声明。

  • Pass语义块

Pass语义块包含的语义如下:

Pass (
[Name]
[Tags]
[RenderSetup]
// Other code
}

首先定义名称,例如:

Name "MyPassName"

可以使用ShaderLab的UsePass命令来直接使用其他Unity Shader中的 Pass。例如:

UsePass "MyShader/MYPASSNAME"

在使用UsePass命令时必须使用大写形式的名字

其次,可以对Pass设置渲染状态。SubShader的状态设置同样适用于Pass

Pass同样可以设置标签,但它的标签不同于SubShader的标签

表3.4

Pass的标签类型

标签类型

说 明

例 子

LightMode

定义该Pass在Unity的渲染流水线中的角色

Tags { "LightMode** = "ForwardBase" }

RequireOptions

用于指定当满足某些条件时才渲染该Pass,它的值是一个 由空格分隔的字符串。目前,Unity支持的选项有: Soft Vegetation o在后面的版本中,可能会增加更多的选项

Tags ( "RequireOptions" = "SoftVegetation"}

3.3.4Fallback

紧跟在各个SubShader语义块后面的,可以是一个Fallback指令。它用于告诉Unity:“如果上面所有的SubShader在这块显卡上都不能运行,那么就使用这个最低级的Shader。 ”

它的语义如下:


Fallback "name"
//或者
Fallback Off//关闭Fallback

例:

Fallback "VertexLit"

3.4Unity Shader的形式

UnityShader最重要的任务是指定各种着色器所需的代码。这些着色器代码可以写在SubShader语义块中(表面着色器的做法),也可以写在Pass语义块中(顶点/片元着色器和固定函数着色器的做法)。

Shader "MyShader"(
Properties {
		//所需的各种属性
}
SubShader (
		//真正意义上的Shader代码会出现在这里
		//表面着色器(Surface Shader )或者
		//顶点/片元着色器(Vertex/Fragment Shader )或者
		// 固定函数着色器(Fixed Function Shader )
}
SubShader {
		//和上一个SubShader类似
	}
}

3.4.1表面着色器

表面着色器在本质上和顶点/片元着色器是一样的。当给Unity提供一个表面着色器的时候,它在背后仍旧把它转换成对应的顶点/片元着色器。
示例代码:

Shader "Custom/Simple Surface Shader" { 
	SubShader {
		Tags ( "RenderType** = "Opaque" }
		CGPROGRAM
		#pragma surface surf Lambert
		struct Input (
		float4 color : COLOR;
		);
		void surf (Input IN, inout Surfaceoutput o) (
		o.Albedo = 1;
		}
		ENDCG
	}
	Fallback “Diffuse”
)

表面着色器被定义在SubShader语义块(而非Pass语义块)中的 CGPROGRAM和ENDCG之间

CGPROGRAM和ENDCG之间的代码是使用CG/HLSL编写的。

3.4.1顶点/片元着色器

示例代码:

Shader "Custom/Simple VertexFragment Shader" (
	SubShader (
		Pass (
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			float4 vert(float4 v : POSITION) : SV_POSITION (
				return mul (UNITY_MATRIX_MVP, v);
			}
			fixed4 frag() : SV_Target (
				return fixed4(1.0,0.0,0.0,1.0);
			}
			ENDCG
		}
	}
}

顶点/片元着色器的代码也需要定义在CGPROGRAM和ENDCG之间, 但不同的是,顶点/片元着色器是写在Pass语义块内,而非SubShader内的。

上一篇:Unity Shader学习记录:Unity Shader


下一篇:4.shader基本语法变量