Back

ShaderCode常用函数解释

介绍 shader 编码过程中函数方法

技美——函数方法解释

[TextureName]_ST

举例来说一个纹理贴图:_Main_ST ,其中 ST 代表的是纹理的缩放属性 (Scale) 和平移 (Translation) 的缩写。_Main_ST.xy 存储缩放值,_Main_ST.zw 存储偏移值。不知道什么是纹理的缩放和偏移,建议补一下计算机图形学,里面有详细的介绍。

POSITION vs SV_POSITION

POSITION 被用作 vertex shader 的输入,SV_POSITION 被用作 vertex shader 的输出,fragment shader 的输入。SV 是 Systems Value 的简写,SV_POSITION 用来标识经过 vertex shader 变换后的顶点坐标。

UnityObjectToClipPos

在unity5.6 以前是 UNITY_MATRIX_MVP,用法:

unity 5.6 前:o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);

unity 5.6 后:o.vertex = UnityObjectToClipPos(v.vertex);

到这里就因该明白了,UnityObjectToClipPos 是一个 MVP 变换方法。

TRANSFORM_TEX

将模型顶点的UV与Tiling、Offset两个变量进行运算,计算出实际显示用的顶点UV,在UnityCG.cginc中的定义如下:

// Transforms 2D UV by scale/bias property
 #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);

v 是 appdata_base 类型,v.texcoord 就是模型顶点的 uv 数据。

_MainTex 是使用的图片;

name##_ST 实际上就是 _MainTex_ST; name## ST.xy 就是 Tiling 的 xy 值;

name##_ST.zw 就是 Offset 的 xy 值。

Tex2D(_MainTex, IN.uv_MainTex)

half4 c = tex2D (_MainTex, IN.uv_MainTex);

tex2D(sampler2D tex, float2 s)函数,这是CG程序中用来在一张贴图中对一个点进行采样的方法,返回一个float4。这里对 _MainTex在输入点上进行了采样,并将其颜色的rbg值赋予了输出的像素颜色,将a值赋予透明度。于是,着色器就明白了应当怎样工作:即找到贴图上 对应的uv点,直接使用颜色信息来进行着色

Scene Depth / Screen Position

Scene Depth 是除开透明模型之外的深度,Screen Position是所有模型的深度。这里如果用视线空间的 Scene Depth 减去 Screen Position(Raw Model) 的 alpha,就可以得到透明模型与不透明模型相交的边缘。

Posterize Node

使用该节点会生成的代码:

void Unity_Posterize_float4(float4 In, float4 Steps, out float4 Out)
{
    Out = floor(In / (1 / Steps)) * (1 / Steps);
}

将连续的值以 ( 1 / Steps ) 为单位向下取整,产生以 ( 1 / Steps ) 为单位标量的值。(说人话:Steps 值越大,新生成的值越接近原来的值;Steps 值越小,新生成的值越偏离原来的值,最终结果可能只剩下两个值。举例来说:一条函数曲线在 Sterps 越小的情况下越接近一条直线。)

Ellipse Node(Fragment)

使用该节点会生成的代码:

void Unity_Ellipse_float(float2 UV, float Width, float Height, out float4 Out)
{
    float d = length((UV * 2 - 1) / float2(Width, Height));
    Out = saturate((1 - d) / fwidth(d));
}

根据输入 UV 以输入宽度和高度指定的大小生成椭圆形状。

Twirl Node

使用该节点会生成的代码:

void Unity_Twirl_float(float2 UV, float2 Center, float Strength, float2 Offset, out float2 Out)
{
    float2 delta = UV - Center;
    float angle = Strength * length(delta);
    float x = cos(angle) * delta.x - sin(angle) * delta.y;
    float y = sin(angle) * delta.x + cos(angle) * delta.y;
    Out = float2(x + Center.x + Offset.x, y + Center.y + Offset.y);
}

将类似于黑洞的旋转扭曲效果应用于输入UV的值。 变形效果的中心参考点由输入Center定义,效果的整体强度由输入Strength的值定义。 输入偏移量可用于偏移结果的各个通道。