内部函数

除了常见的 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