unity Shader


前言

学习shader不会是一门课的知识就能够掌握的,还是需要多个课程/教程“服用”效果更佳。好好学基础知识,基础决定上层建筑。
推荐:
①、《unity shader 入门精要 》这本书作为基础入门,细嚼慢咽更有味道。
②、B站上庄懂老师的课程(更适合美术往TA发展的基础教程)
③、B站上的GAMES101-现代计算机图形学入门-闫令琪老师的课程适合了解计算机图形学方面的知识
④、还可以去B站看看百人计划,百人计划虽说是零基础,但有些课程内容还是需要有一点基础才能看懂的,定义为中级的比较合适。

最后,为自己的学习做个小小的笔记


1 unity shader代码结构

Shader "MyShader/ShaderName"        //shader命名
{
    Properties
    {
        //unity属性Properties段
    }
    
    SubShader
    {
    	// 定义可选的标签【Tags】和渲染设置【RenderSetup】
        Tags { "RenderType"="Opaque" }

        Pass
        {
			name "FORWARD"
			Tags { "LightMode" = "ForwardBase" }
			
			//Cg代码代码片段,以CGPROGRAM开始,ENDCG结束
            CGPROGRAM
            
            //编译指令
            #pragma vertex vert
            #pragma fragment frag
            
            //引入unity内置shader中的UnityCG.cginc库文件
            #include "UnityCG.cginc"
			
			// shader代码执行的顺序为:     输入结构>>>顶点Shader>>>输出结构>>>片元/像素shader
			
			//输入结构,appdata是输入结构的名字(名字可以自定义,但为了规范性和别人能看懂建议用appdata,VertInput,a2f这些来命名)
            struct appdata
            {
            	//将需要用到的模型的数据输入,如顶点坐标、法线、uv等
            };

			//输出结构,v2f是输入结构的名字,也有用VertOutput命名的
            struct v2f
            {
            	//将顶点shader中准备的数据作为结构体保存
            };
            
			//顶点shader
            v2f vert (appdata v)
            {
                v2f o;                                             //新建一个v2f输出结构
                //一般在这对片元shader需要的数据做变换,准备的数据就是输出结构中的数据,会在这将模型的信息从模型空间转换成世界空间中的信息
                return o;                                          // 将输出结构输出
            }

			//片元/像素shader
            fixed4 frag (v2f i) : SV_Target
            {
				//重点的运算操作在这里执行。片元or像素shader运算段
            }
            
            //Cg代码结束字
            ENDCG
        }
    }

	//FallBack语义段,也可以没有该语义段,但是为了某些设备不支持上述的shader,可以回调某个消耗性能不高的shader设置
	//如下代码是,如果硬件不支持上面的shader,则回调unity内置的"Diffuse" 
	FallBack "Diffuse"                                                      
}

1.1 shader命名

通过在字符串中添加斜杠(“/”),可以控制Unity Shader在材质面板中出现的位置。
如代码块中的 Shader “MyShader/ShaderName” {};
则这个unity shader在材质面板中的位置就是shader->MyShader;ShaderName就是该unity shader的名字。

1.2 Properties语义块

  • Properties语义并不是必需的,我们可以选择不声明任何材质属性。
  • 在Unity中,这些属性的名字通常由一个下划线“_”开始,如"_MainTex"。
  • Properties语义块的作用仅仅是为了让这些属性可以出现在材质面板中。

Properties语义块定义:

Properties
{
	Name("display name" , PropertyType) = DefaultValue
	//如下贴图的属性定义
	_MainTex("主贴图", 2D) = "white"{}
}

所有属性类型的例子

//数值型
_Int ("Int", Int) = 1
_Float ("Float", Float) = 1.0
_Range ("Range", Range(1,50)) = 10
//颜色和向量
_Color("Color", Cplor) = (1,1,1,1)
_Vector ("Vector", Vector) = (2,3,6,1)
//纹理型 Textures
_2D("2D", 2D) = ""{}
_Cube("Cube", Cube) = "white"{}
_3D("3D", 3D) = "black"{}

①对于Int、Float、Range这些数字类型的属性,其默认值就是一个单独的数字;
②对于Color和Vector这类属性,默认值是用圆括号包围的一个四维向量;
③对于2D、Cube、3D这3种纹理类型,它们的默认值是通过一个字符串后跟一个花括号来指定的,其中,字符串要么是空的,要么是内置的纹理名称,如“white”“black”“gray”或者“bump”。(当该纹理是法线纹理的时候使用的是“bump”)

属性定义完后,在使用前还需要声明该属性

Properties
{
	_MainCol("颜色",color) = (1.0,1.0,1.0,1.0)
	_SpecularPow("高光次幂",Range(1,90)) = 30
}

	//在Cg语言中声明属性值,并且必须要在属性值使用前声明,一般建议把该声明放在输入结构前
	//要和Properties段定义的参数一一对应,如Properties中是_MainCol,这里也要是_MainCol;并且适当的选取参数
	uniform float3 _MainCol;       
	uniform float _SpecularPow;     

uniform修饰字共享于vert和frag;attibute修饰字仅用于vert;varying用于vert,frag传数据,不写这些修饰字也可以,写了是为了更加的规范。

1.3 SubShader

  • 每一个Unity Shader文件可以包含多个SubShader语义块,但最少要有一个。
  • 其中SubShader中定义了一系列Pass、可选的状态([RenderSetup])和标签([Tags])设置。

1.3.1 Pass

  • 每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成渲染性能的下降。

1.3.2 SubShader和Pass中的状态和标签设置

  • 状态和标签同样可以在Pass声明。
  • SubShader中的标签([Tags])设置是特定的,和Pass中使用的标签是不一样的。
  • SubShader的标签(Tags)是一个键值对(Key/Value Pair),它的键和值都是字符串类型。这些键值对是SubShader和渲染引擎之间的沟通桥梁。
  • 对于状态([RenderSetup])设置来说,SubShader和Pass中使用的语法是相同的。但如果在SubShader进行了这些设置,那么将会用于所有的Pass。

标签的结构:

Tags{ "TagsName1" = "Value1"   "TagsName2" = "Value2"  }

1.4 Fallback

  • Unity提供这种语义的原因在于,不同的显卡具有不同的能力。
  • 一般VertexLit、Diffuse、Specular等作为回调。
FallBack "Diffuse" 

2 关于unity内置shader库文件

2.1 如何查看unity内置shader库

①、可以在unity安装路径中的文件夹里面找到unity的内置shaderLab的一下库文件,比如//…/unity版本号\Editor\Data\CGIncludes的文件夹里面就能找到常用的unityCG.cginc文件。
②、找不到这个文件夹可以到unity官方网站下载。

2.2 unity shader库文件or函数

  • 包含文件(include file),是类似于C++中头文件的一种文件。在Unity中,它们的文件后缀是.cginc。
  • 有一些文件是即便我们没有使用#include指令,它们也是会被自动包含进来的,例如UnityShaderVariables.cginc。

2.2.1 unity常用内置函数

函数描述
float4 UnityObjectToClipPos ( float4 v);输入一个模型空间的顶点位置,返回世界空间中该顶点的位置(将顶点信息从模型空间变换到屏幕空间)
float3 ObjectSpaceViewDir输入一个模型空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向
float3 ObjSpaceViewDir ( float4 v )输入一个模型空间中的顶点位置,返回模型空间中从该点到摄像机的观察方向
float3 WorldSpaceLightDir ( float4 v )输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有被归一化(仅可用于前向渲染中)
float3 ObjSpaceLightDir ( float4 v )输入一个模型空间中的顶点位置,返回模型空间中从该点到光源的光照方向。没有被归一化(仅可用于前向渲染中)
float3 UnityObjectToWorldNormal (float3 normal)把法线方向从模型空间变换到世界空间
float3 UnityObjectToWorldDir (in float3 dir)把方向矢量从模型空间变换到世界空间
float3 UnityWorldToObjectDir (float3 dir)把方向矢量从世界空间变换到模型空间

2.3 如何使用unity库文件or库文件函数

2.3.1 引入unity库文件

①、内置库文件
//使用#Include引入unity shader中内置的UnityCG.cginc文件,还有一些其他的内置文件,可自行查看
#include "UnityCG.cginc"
②、自定义库文件
  • 创建自定义的库文件,并进行编写库文件内容。
  • 在创建的unity shader代码块中先引入自定义的库文件,就能使用库文件中自定义的函数等内容。

2.4 unity常用语义

  • POSITION将告诉Unity,把模型的顶点坐标填充到输入参数v中;
  • SV_POSITION将告诉Unity,顶点着色器的输出是裁剪空间中的顶点坐标。

①、从应用阶段传递模型数据给顶点着色器时unity支持的常用语义(输入结构)

语义描述
POSITION模型空间中的顶点位置,通常是 float4 类型
NORMAL顶点法线,通常是 float3 类型
TANGENT顶点切线,通常是 float4 类型
TEXCOORDn ,如TEXCOORD0,TEXCOORD1该顶点的纹理坐标,TEXCOORD0表示第一组坐标纹理,通常是float2,或float4类型(unity中最多支持模型拥有四套uv
COLOR顶点颜色,通常是fixed4或float4类型

②、顶点着色器传递模型数据给片元着色器时unity支持的常用语义(输出结构)

语义描述
SV_POSITION裁剪空间中的顶点坐标,结构体中必须包含一个用该语义修饰的变量。等同于DirectX9中的POSITION,但最好使用SV_POSITION
COLOR0通常用于输出第一组顶点颜色,但不是必须的
COLOR1通常用于输出第二组顶点颜色,但不是必须的
TEXCOORD0~TXECOORD7通常用于输出纹理坐标,但不是必须的

③、片元着色器输出时unity支持的常用语义(片元shader)

语义描述
SV_Target输出值将会存储到渲染目标(render target)中。等同于DirectX9中的COLOR语义,但最好使用 SV_Target
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值