0x01.Shader函数step
在Shader编程里,step
函数是一个常用的内置函数,主要用于进行比较操作并产生阶跃输出。下面从基本语法、功能原理、使用场景等方面进行介绍。

Shader "ShaderLearning/Shader05"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_OnOff("OnOff", Range(0, 1)) = 0
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float _OnOff;
fixed4 frag(v2f i) : SV_Target
{
float r = step(0.5, _OnOff) * step(0.5, i.uv.x);
r += (1 - step(0.5, _OnOff)) * step(0.5, i.uv.y);
return fixed4(r, 0, 0, 1);
}
ENDCG
}
}
}
基本语法
在GLSL(OpenGL Shading Language)、HLSL(High-Level Shading Language)等常见Shader语言中,step
函数的语法是相同的:
float step(float edge, float x);
vec2 step(vec2 edge, vec2 x);
vec3 step(vec3 edge, vec3 x);
vec4 step(vec4 edge, vec4 x);
edge
:比较的边界值。x
:待比较的值。- 返回值:如果
x
小于edge
,返回0;如果x
大于或等于edge
,返回1。对于向量形式,会对向量的每个分量分别进行比较操作。
功能原理
step
函数本质上是一个阶跃函数。它在x
达到edge
这个边界值时,输出从0跃变为1。以下是一个简单的代码示例来说明其工作原理:
// 假设这是在片段着色器中
void main() {
float edge = 0.5;
float x = 0.3;
float result = step(edge, x);
// 因为 0.3 < 0.5,所以 result 为 0
}
使用场景
- 图形绘制:在绘制图形时,可借助
step
函数实现硬边界效果。例如,绘制一个颜色突变的矩形,只需比较像素坐标与矩形边界,当坐标超出边界时,颜色发生突变。
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
float left = 0.2;
float right = 0.8;
float bottom = 0.2;
float top = 0.8;
float mask = step(left, uv.x) * step(uv.x, right) * step(bottom, uv.y) * step(uv.y, top);
vec3 color = mix(vec3(0.0), vec3(1.0), mask);
gl_FragColor = vec4(color, 1.0);
}
- 阴影效果:在实现简单阴影效果时,可使用
step
函数。通过比较光线与物体的距离和某个阈值,来决定像素是否处于阴影中。
float shadow = step(light_distance, threshold);
注意事项
step
函数的输出只有0和1两种状态,产生的是硬边界效果。若需要软边界效果,可使用smoothstep
函数。- 在使用向量形式的
step
函数时,要确保向量的维度一致,避免出现意外结果。