内部函数
除了常见的 HLSL 函数外,DSHL 还支持特殊的**内在**函数,这些函数由着色器编译器处理。
Note
这些函数将在运行时由 stcode 系统进行评估(除非在编译时已知),因此不能在 Preshader 部分之外使用。
float time_phase(float period, float offset)
计算指定周期和偏移量的全局时间相位(范围 [0, 1) 中的数字)。
返回 frac((shadersGlobalTime + offset) / period) 或 period == 0 时的 shadersGlobalTime,其中 shadersGlobalTime 是游戏开始时的时间(以秒为单位)。
(ps) { current_time@f1 = time_phase(0, 0); }
float sin(float x)
计算 sin 函数。
(ps) { foo@f1 = sin(3.14); }
float cos(float x)
计算 cos 函数。
(ps) { foo@f1 = cos(3.14); }
float pow(float x, float y)
将 x 提高到 y 的幂。
(ps) { foo@f1 = pow(1.2, 3.4); }
float4 vecpow(float4 v, float a)
将向量 v 的每个分量提升为 a 的幂。
local float4 v = (1, 2, 3, 4);
local float a = 3.33;
(ps) { foo@f1 = vecpow(v, a); }
float sqrt(float x)
计算 x 的平方根。
(ps) { foo@f1 = sqrt(1.3); }
float min(float x, float y)
查找两个值的最小值。
(ps) { foo@f1 = min(-1, 1); }
float max(float x, float y)
求两个值的最大值。
(ps) { foo@f1 = max(-1, 1); }
float fsel(float a, float b, float c)
返回 (a >= 0.0f) ? b : c
(ps) { foo@f1 = fsel(1, 2, 3); }
float4 sRGBread(float4 v)
将 v 的 RGB 分量提高到 2.2 的幂。
返回 float4(pow(v.r, 2.2f), pow(v.g, 2.2f), pow(v.b, 2.2f), v.a)
(ps) { srgb_color@f3 = sRGBread(some_color); }
// 在转换为 float3 时将舍弃 alpha
float4 get_dimensions(texture t, int mip)
获取 mip 层的纹理 t 信息。
返回 float4(width, height, depth_or_array_slices, mip_levels)。
对于体积纹理, depth_or_array_slices 存储深度;对于纹理数组,depth_or_array_slices 存储数组切片数。
对于立方体纹理,depth_or_array_slices = 1。
texture ssao_tex;
(ps) { ssao_size@f4 = get_dimensions(ssao_tex, 0); }
float get_size(buffer b)
以元素为单位获取缓冲区 b 的大小。
返回 float(buffer_size_in_elements)。
buffer some_buf;
(ps) { buf_size@f1 = get_size(some_buf); }
Warning
(RW)ByteAddressBuffer``的 ``get_size 将返回缓冲区中 DWORD(4 字节块)的个数。
这与 (RW)ByteAddressBuffer::GetDimensions 纯 HLSL 函数相反,后者返回的是字节数。
float4 get_viewport()
获取视口信息。
返回 float4(top_left_x, top_left_y, width, height)。
(ps) { viewport@f4 = get_viewport(); }
int exists_tex(texture t)
运行时,检查纹理 t 是否存在(从 C++ 端绑定到着色器)。
可以将其视为运行时的 t != NULL 预着色器检查。
返回值可以保存到变量中,并用于统一的 HLSL 分支。
使用方法
texture example_texture;
(ps) {
example_texture@tex2d = example_texture;
example_texture_exists@i1 = exists_tex(example_texture);
}
hlsl(ps) {
if (example_texture_exists) { /* ... */ }
}
如果存在纹理,则返回 1,否则返回 0。
int exists_buf(buffer b)
类似于 exists_tex。
在运行时,检查缓冲区 b 是否存在(从 C++ 端绑定到着色器)。
你可以把它看作是运行时的 b != NULL 着色器前检查。
返回值可以保存到变量中,并用于统一的 HLSL 分支。
使用方法
buffer example_buffer;
(ps) {
example_buffer@buf = example_buffer hlsl {
StructuredBuffer<float> example_buffer@buf;
};
example_buffer_exists@i1 = exists_buf(example_buffer);
}
hlsl(ps) {
if (example_buffer_exists) { /* ... */ }
}
如果缓冲区存在,则返回 1,否则返回 0。