Unity shader语法

前文:TA Shader基础

shader语法

ShaderLab+CG

Unity定义常用的基于顶点的数据盒子

以下盒子默认数据如下,可以自己灵活改变,装载任意数据类型(float,float2,float3,float4):
POSITION:位置
NORMAL:法线
TANGENT:切线
TEXCOORD0:纹理坐标
TEXCOORD(n):自己定义内容,Shader Model为2/3的时候最多有8个这样的盒子,如果是4/5,最多有16个盒子
COLOR0:颜色,此外还有COLOR1

以下是系统指定用途,最好不要改变:
SV_POSITION:顶点shader返回的顶点位置
SV_Target:片元着色器shader返回给渲染管线的颜色

顶点shader如何传递数据给着色器shader

顶点shader的有一个入口函数vert,其默认传递的参数是一个结构体appdata,在结构体中我们可以把数据盒子中的数据(基于模型的顶点数据)赋给其成员,默认的成员是传递顶点坐标的float4 vertex : POSITION和传递纹理坐标的float2 uv : TEXCOORD0;,具体什么成员变量存放什么数据完全由我们自己决定。然后我们就可以在vert函数中使用这个结构体进行计算了。
vert返回的数据默认也是一个名为v2f的结构体,这个结构体的成员变量定义了要传递给片元着色器shader的数据,存放的盒子可以自己来定,默认是vertex:ST_POSITION和uv:TEXCOORD0,其中ST_POSITION是顶点shader返回给系统的片元坐标数据,我们不要修改它,其他变量例如uv是传给着色shader的,可以自己定。在vert函数中我们需要通过appdata传进来的数据计算出v2f返回的数据。
顶点shader对传递给片元着色shader的数据v2f会经过三角形插值处理,经过插值后,每一个片元都拥有和顶点一样格式的v2f数据,然后片元着色shader会对片元进行逐个处理。

片元着色shader处理数据

片元着色shader接收顶点shader返回插值后的数据,对片元进行逐个处理。
处理时通过法线,光源位置,片元本色等信息,计算出片元应当显示的颜色。
处理完成之后,返回值是片元的颜色,通过ST_Target返回渲染管线。

CPU如何传递数据给GPU

在shader中,CPU通过在CGProgram中定义的变量把数据传递给GPU,例如:

sampler2D _MainTex;
float4 _MainTex_ST:
float3 _MyColor:
float _MyValue:

这些变量前面可以加上一个uniform,Unity中可以省略,这些数据在shader中只读不能修改,但是为了操作方便,我们可以把数据绑定到材质球的属性面板中进行修改,可以在属性列表properties中定义。

Properties
    {
        // 变量名字("显示名字",类型) = 默认值
        _MainTex ("Texture", 2D) = "white" {}
        _MyPos("MyPos", Vector) = (1.0, 1.0, 1.0, 1.0)
        _MyColor ("MyColor", Color) = (1.0, 1.0, 1.0, 1.0)
        _MyValue ("MyValue", Range(0, 1.0)) = 0.5        
    }

下面是Properties中类型对应的变量:
Color,Vector --> float4,half4,fixed4
Range,Float --> float
2D --> Sampler2D
Cube --> SamplerCube
3D --> Sampler3D

渲染管线配置

一个shader脚本可以包含多个SubShader,但是只会运行一个,如果前面的不能运行,才会运行后面的。如果所有的SubShader不能运行的时候,可以在最后指定默认的shader:

Fallback "VertexLit"

每个SubShader会包含若干个Pass,每个Pass都是一个完整的渲染流水线,Pass的渲染管线状态可以进行如下设置(如果写到SubShader则所有SubShader的Pass都用):

Cull Back|Front|off     //设置提出模式:剔除背面/正面/关闭,默认是Back
Ztest Less|Greater|LEqual|GEqual|Equal|NotEqual|Alway //设置深度测试使用的规则
Zwrite On|Off  //开启/关闭深度写入
Blend SrcFactor DstFactor //开启并设置混合模式

在pass中可以定义名字:

name "myShader"

这样就能直接使用这个名字进行调用了

标签Tag

Tag可以在SubShader或Pass中设置:
格式:Tag{“Key”=“Value” “Key2”=“Value2”}
Queue:渲染队列 Qpaque/Transparent,渲染队列的值可以在材质面板中设置,它的默认值就是基于Qpaque(2000),Tansparent(3000)的
RanderType:对着色器进行分类,不透明着色器/半透明着色器 Qpaque/Transparent
DisableBatching:指明是否对该物体使用批处理 “DisableBatching”=True
ForceNoShadowCasting:控制是否会投射阴影
IgnoreProjector:如果设置为True,物体不会受Projector影响,用于半透明
CanUsePriteAtlas:如果用于精灵,设置为False
PreviewType:材质在属性面板中如何显示,默认是球,可以设置为Plane,SkyBox
LightMode:定义该Pass在渲染流水线中的角色

Shader数据类型

浮点型

主要包括float(32)、half(16)、fixed三种精度
所有平台显卡都支持float,fixed部分显卡不支持,但是如果代码用到了就会自动用float进行替代,一般情况下我们使用float就可以了。

浮点数用于表示向量或颜色:

  1. 颜色可以由3到4个浮点数表示,float3–>rgb,float4–>rgba
  2. 向量可以分为三种(二维,三维,四维),对应于(x,y),(x,y,z),(x,y,z,w)

初始化:

float3 color = float3(1,0,0)
float4 view = float4(1,1,1,1)

访问(降维和加维):

color.r
color.g
color.b
color.rgb  // 会输出三维的浮点数
view.x
view.y
view.z
view.w
view.xy
view.xyz
float value = float4(view.xyz,1.0)
结构体
struct temp_data{
    int a;
    float2 b;
    uint c;
}
struct temp_data temp;
temp.a = 10
temp.b = float2(10.0,10.0)
纹理类型和采样函数
// 三种纹理类型
sampler2D a;
samplerCUBE b;
sampler3D c;
// 采样函数
float4 col = tex2D(a,i.uv);
float3 col2 = texCUBE(b,float3(1.0,0.0,0.0));
float3 col3 = tex3D(c,float3(1.0,0.0,0.0));

颜色

颜色有两种描述方式,两种可以相互转换

  1. 红,绿,蓝三个分量,简称RGB
  2. 色相,饱和度,亮度,简称HSV
Bool,条件判断,循环语句
bool isSelf = false
int mask = 0xff
int value = 0xffffffff
// 与或非:&& || !
// 位运算:左移<<  右移>>  按位或|  按位与&  按位取反~  按位异或^
if(isSelf) // 条件和循环语句与C#一致
{
    mask = mask | value;
}
else if(mask==value){
}
int i = 0;
while(i < 10){
    i++;
}
for(int k = 0;k < 10;k++){
}
矩阵

矩阵是描述线性变换的数学工具,用一个矩阵乘以一个向量,我们就可以把这个向量映射到另一个向量。Unity中矩阵往往表示一个点在N维空间的变换。包括但不限于缩放,平移,旋转。在Unity中矩阵最多只有4x4。

// 矩阵的定义
float2x2 a = float2x2(1,0,0,1);
float3x3 b = float2x2(1,0,0,1,1,0,0,1,1);
float2x3 c = float2x3(1,0,0,1,1,0);
float4 v1 = float4(1,0,0,0);
float4x4 d = float4x4(v1,v1,v1,v1);
float value = d[3][3]

常用内置函数(Cg和GLSL)

radians(degrees) // 度转弧度
degrees(radians) // 弧度转度
sin
cos
tan
asin
acos
atan
pow
exp
log:e为底
exp2:2的几次方
log2:2为底
sqrt
inversesqrt:开根号的倒数
abs
sign
floor:向下取整
ceil:向上取整
fract:取小数部分
mod:传入x,y,返回x-y*floor(x/y)
min
max
clamp
mix:传入x,y,a,返回x*(1-a) + y*a
step:传入edge,x,x大于等于edge返回1,否则返回0
smoothstep:传入edge0,edge1,x,t=clamp((x-edge0)*(edge1-edge0),0,1),返回t*t*(3-2*t)
matrixCompMult(mat x,mat y):两个矩阵对应的元素相乘,并非常识上的矩阵乘法
// 向量相关
lessThan
lessThanEqual
greaterThan
greaterThanEqual
equal
any
all
not
// 材质查找
texture2D
texture2DProj
texture2DLod
texture2DProjLod
textureCube
textureCubeLod
// 几何函数
distance
faceforward
length
normalize
reflect
refract
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑小星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值