OBS-Direct11数据结构
+ -

SamplerState (采样器状态)

2026-01-30 1 0

SamplerState 详解

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);
}

技术原理

采样过程

  1. 纹理坐标计算:着色器生成纹理坐标 (u, v)
  2. 地址模式处理:根据地址模式处理超出范围的坐标
  3. MIP 级别选择:根据距离和过滤模式选择合适的 MIP 级别
  4. 采样过滤:根据过滤模式对纹理像素进行插值
  5. 返回采样值:将处理后的颜色值返回给着色器

性能影响

  • 过滤模式:各向异性过滤质量越高,性能开销越大
  • 地址模式:边界模式可能比环绕模式稍慢
  • MIP 映射:使用 MIP 映射可以提高性能和质量

应用场景

1. 普通纹理映射

  • 地址模式GS_ADDRESS_WRAP(重复纹理)
  • 过滤模式GS_FILTER_LINEAR(平滑过渡)
  • 用途:常规纹理贴图,如墙面、地面等

2. 法线贴图

  • 地址模式GS_ADDRESS_WRAP
  • 过滤模式GS_FILTER_LINEARGS_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 能够在各种场景下实现高质量的纹理渲染,为用户提供流畅的视觉体验。

0 篇笔记 写笔记

作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!