Unity Shader常见问题

ShaderLab基础

shader语法基本框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Shader"ShaderName"{//定义Shader名字
Properties{//属性,cpu传给shader的值,出现在unity材质面板中,在Pass中要重新声明

}
SubShader{
//针对显卡A的shader
//此处设置标签1
//此处设置状态
Pass{
//此处也可以设置标签2
//此处设置状态
CGPROGRAM

//下面是两条关键的编译指令,告诉unity哪两个函数最最重要的
#pragma vertex vertname
#pragma fragment fragname

//此处定义cg代码

ENDCG

}
Pass{

}
}
SubShader{
//针对显卡B的shader
}
}

Pass的执行

Pass译为通道,一般渲染对象只经过一次Pass,效果是单薄的,多Pass渲染会让画面更加有趣。Pass可以命名,可以设置标签,可以指定某个Pass对对象进行渲染,也可以指定多个Pass进行渲染。

关于标签1常出现的字符串:

1
2
3
4
SubShader{
Tags{"RenderType"="Opaque" "Queue"="Geometry"}
...
}

RenderType

其中RenderType使用的值通常包括Opaque、Transparent、Background等,实际上是一种约定,用来区别这个Shader要渲染的对象。并且可以使用自定义值,影响不大,只是在代替渲染时,定义者要区分不同RenderType类型的Shader。

代替渲染解释:

1
2
Camera.SetReplacementShader("shader1","") //场景中所有的渲染对象的shader都替换成shader1进行渲染
Camera.SetReplacementShader("shader1","RenderType") //场景中所有RenderType类型与shader1的RenderType一致的渲染对象,其shader都替换为shader1,再渲染

Queue

Queue渲染队列,用来指定当前shader渲染对象的渲染顺序,其值有Background、Geometry、AlphaTest、Transparent等,
乐乐在书中介绍,队列索引号越小说明越先被渲染:

关于标签2中常出现的字符串:

1
2
3
4
Pass{
Tags{"LightMode"="ForwardBase" }
...
}

程序员指定渲染路径LightMode,是想配置光照属性与渲染流程。这是程序员与Unity的一个暗号。详见这里

状态设置

SubShader或Pass中常出现一些状态设置:
: Cull
: ZTest
: Zwrite
Blend
在SubShader中出现,表示该SubShader中所有的Pass都受状态设置的影响;在Pass中出现,说明只有当前Pass受状态设置的影响。

Shader中的系统语义

在定义输入struct的时,常遇到POSITION、SV_POSITION、SV_Target、NORMAL等语义,这些语义告诉Unity此处变量的输入输出类型,例如变量后有”:POSITION”指示Unity把模型的顶点坐标存到变量里,变量后有“:SV_POSITION”指示该变量存的值是裁剪空间中的模型坐标,“SV_Target”指示将输出输入到渲染缓冲中,一般为帧缓冲。

shader不报错

参考

  1. RenderType与Queue的理解
  2. Unity Shader 入门精要