SamplerState (采样器状态)
2026-01-30
1
0
SamplerState 详解
- 采样器状态对象 https://www.vaczh.com/article/detail-77.html
- 采样器sampler_state https://www.vaczh.com/article/detail-121.html
OBS中使用SamplerState实现的filter特效。不同的极样状态,实现不同的特效。
概念定义
SamplerState(采样器状态)是 DirectX 中用于控制纹理采样行为的状态对象。它定义了如何从纹理中读取像素值,包括过滤方式、寻址模式、各向异性过滤等参数。
在 OBS Studio 中,gs_sampler_state 类封装了 DirectX 11 的 ID3D11SamplerState 接口,提供了统一的采样器配置功能。
核心功能
1. 地址模式(Address Mode)
控制纹理坐标超出 [0,1] 范围时的行为:
| 模式 | 描述 | DirectX 对应值 |
|---|---|---|
GS_ADDRESS_WRAP |
环绕重复 | D3D11_TEXTURE_ADDRESS_WRAP |
GS_ADDRESS_CLAMP |
钳制到边缘 | D3D11_TEXTURE_ADDRESS_CLAMP |
GS_ADDRESS_MIRROR |
镜像重复 | D3D11_TEXTURE_ADDRESS_MIRROR |
GS_ADDRESS_BORDER |
使用边界颜色 | D3D11_TEXTURE_ADDRESS_BORDER |
GS_ADDRESS_MIRRORONCE |
镜像一次后钳制 | D3D11_TEXTURE_ADDRESS_MIRROR_ONCE |
2. 过滤模式(Filter Mode)
控制纹理采样时的插值方式:
| 模式 | 描述 | DirectX 对应值 |
|---|---|---|
GS_FILTER_POINT |
最近点采样 | D3D11_FILTER_MIN_MAG_MIP_POINT |
GS_FILTER_LINEAR |
三线性过滤 | D3D11_FILTER_MIN_MAG_MIP_LINEAR |
GS_FILTER_ANISOTROPIC |
各向异性过滤 | D3D11_FILTER_ANISOTROPIC |
| 其他组合模式 | 不同级别的过滤组合 | 相应的 D3D11_FILTER_* 值 |
3. 其他参数
- 各向异性等级:控制各向异性过滤的质量(1-16)
- 边界颜色:当使用
GS_ADDRESS_BORDER模式时的边界颜色 - MIP 级别范围:控制使用的 MIP 级别范围
代码实现分析
采样器状态创建
gs_sampler_state::gs_sampler_state(gs_device_t *device, const gs_sampler_info *info)
: gs_obj(device, gs_type::gs_sampler_state), info(*info)
{
// 1. 配置采样器状态描述
memset(&sd, 0, sizeof(sd));
sd.AddressU = ConvertGSAddressMode(info->address_u);
sd.AddressV = ConvertGSAddressMode(info->address_v);
sd.AddressW = ConvertGSAddressMode(info->address_w);
sd.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
sd.Filter = ConvertGSFilter(info->filter);
sd.MaxAnisotropy = info->max_anisotropy;
sd.MaxLOD = FLT_MAX;
// 2. 设置边界颜色
vec4 v4;
vec4_from_rgba(&v4, info->border_color);
memcpy(sd.BorderColor, v4.ptr, sizeof(v4));
// 3. 创建采样器状态
hr = device->device->CreateSamplerState(&sd, state.Assign());
if (FAILED(hr))
throw HRError("Failed to create sampler state", hr);
}
格式转换函数
// 地址模式转换
static inline D3D11_TEXTURE_ADDRESS_MODE ConvertGSAddressMode(gs_address_mode mode)
{
switch (mode) {
case GS_ADDRESS_WRAP:
return D3D11_TEXTURE_ADDRESS_WRAP;
case GS_ADDRESS_CLAMP:
return D3D11_TEXTURE_ADDRESS_CLAMP;
// ... 其他模式
}
return D3D11_TEXTURE_ADDRESS_WRAP;
}
// 过滤模式转换
static inline D3D11_FILTER ConvertGSFilter(gs_sample_filter filter)
{
switch (filter) {
case GS_FILTER_POINT:
return D3D11_FILTER_MIN_MAG_MIP_POINT;
case GS_FILTER_LINEAR:
return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
// ... 其他模式
}
return D3D11_FILTER_MIN_MAG_MIP_POINT;
}
使用方法
创建采样器状态
// 1. 配置采样器信息
gs_sampler_info samplerInfo;
samplerInfo.address_u = GS_ADDRESS_WRAP;
samplerInfo.address_v = GS_ADDRESS_WRAP;
samplerInfo.address_w = GS_ADDRESS_WRAP;
samplerInfo.filter = GS_FILTER_LINEAR;
samplerInfo.max_anisotropy = 1;
samplerInfo.border_color = 0; // 黑色边界
// 2. 创建采样器状态
gs_sampler_state_t *sampler = gs_samplerstate_create(&samplerInfo);
在着色器中使用
// 3. 设置采样器到着色器
gs_effect_set_texture(effect_param, texture);
gs_effect_set_next_sampler(effect, "sampler", sampler);
// 4. 绘制
gs_draw(GS_TRIS, 0, 3);
// 5. 清理
gs_samplerstate_destroy(sampler);
着色器代码示例
// 采样器声明
Texture2D texture;
SamplerState sampler;
// 像素着色器
float4 PSMain(float2 uv : TEXCOORD0) : SV_Target {
// 使用采样器采样纹理
return texture.Sample(sampler, uv);
}
技术原理
采样过程
- 纹理坐标计算:着色器生成纹理坐标 (u, v)
- 地址模式处理:根据地址模式处理超出范围的坐标
- MIP 级别选择:根据距离和过滤模式选择合适的 MIP 级别
- 采样过滤:根据过滤模式对纹理像素进行插值
- 返回采样值:将处理后的颜色值返回给着色器
性能影响
- 过滤模式:各向异性过滤质量越高,性能开销越大
- 地址模式:边界模式可能比环绕模式稍慢
- MIP 映射:使用 MIP 映射可以提高性能和质量
应用场景
1. 普通纹理映射
- 地址模式:
GS_ADDRESS_WRAP(重复纹理) - 过滤模式:
GS_FILTER_LINEAR(平滑过渡) - 用途:常规纹理贴图,如墙面、地面等
2. 法线贴图
- 地址模式:
GS_ADDRESS_WRAP - 过滤模式:
GS_FILTER_LINEAR或GS_FILTER_ANISOTROPIC - 用途:提高表面细节,增强真实感
3. 环境映射
- 地址模式:
GS_ADDRESS_CLAMP(避免边缘 artifacts) - 过滤模式:
GS_FILTER_LINEAR - 用途:模拟反射和折射效果
4. UI 元素
- 地址模式:
GS_ADDRESS_CLAMP(避免边缘重复) - 过滤模式:
GS_FILTER_POINT(像素完美,避免模糊) - 用途:清晰的用户界面元素
输入输出示例
输入输出示例
使用不同过滤模式的效果:
输入:
// 点采样(锐利但可能有锯齿)
gs_sampler_info pointSampler;
pointSampler.filter = GS_FILTER_POINT;
gs_sampler_state_t *pointSamplerState = gs_samplerstate_create(&pointSampler);
// 线性采样(平滑但可能模糊)
gs_sampler_info linearSampler;
linearSampler.filter = GS_FILTER_LINEAR;
gs_sampler_state_t *linearSamplerState = gs_samplerstate_create(&linearSampler);
// 各向异性过滤(高质量,适合倾斜表面)
gs_sampler_info anisotropicSampler;
anisotropicSampler.filter = GS_FILTER_ANISOTROPIC;
anisotropicSampler.max_anisotropy = 16;
gs_sampler_state_t *anisotropicSamplerState = gs_samplerstate_create(&anisotropicSampler);
输出:
- 点采样:纹理边缘锐利,但在倾斜角度可能出现锯齿
- 线性采样:纹理过渡平滑,但远处可能显得模糊
- 各向异性过滤:在所有角度都保持清晰,特别是倾斜表面
使用不同地址模式的效果:
输入:
// 环绕模式
gs_sampler_info wrapSampler;
wrapSampler.address_u = GS_ADDRESS_WRAP;
wrapSampler.address_v = GS_ADDRESS_WRAP;
// 钳制模式
gs_sampler_info clampSampler;
clampSampler.address_u = GS_ADDRESS_CLAMP;
clampSampler.address_v = GS_ADDRESS_CLAMP;
// 边界模式
gs_sampler_info borderSampler;
borderSampler.address_u = GS_ADDRESS_BORDER;
borderSampler.address_v = GS_ADDRESS_BORDER;
borderSampler.border_color = 0xFF0000FF; // 蓝色边界
输出:
- 环绕模式:纹理在边缘重复,适合无缝纹理
- 钳制模式:纹理在边缘拉伸,适合不需要重复的纹理
- 边界模式:纹理外显示指定边界颜色,适合需要明确边界的场景
总结
SamplerState 是 DirectX 中控制纹理采样行为的关键组件,它通过配置过滤方式、寻址模式等参数,直接影响纹理的显示质量和渲染性能。在 OBS Studio 中,gs_sampler_state 类提供了统一的采样器管理接口,使开发者能够根据不同场景选择合适的采样策略。
合理配置 SamplerState 可以:
- 提高纹理渲染质量
- 优化渲染性能
- 实现特定的视觉效果
- 避免采样相关的视觉 artifacts
通过灵活使用不同的采样器配置,OBS Studio 能够在各种场景下实现高质量的纹理渲染,为用户提供流畅的视觉体验。
OBS-Direct11数据结构





