obs格式输出
+ -

OBS画布与输出缩放

2024-12-20 5 0

使用D3D11渲染后的数据位于纹理video->render_texture或者video->output_texture中。

  • 如果不需要缩放,则render_texture就是输出的最终纹理
  • 如果需要缩放,则output_texture就是缩放后输出的纹理;

112847594001

缩放很简单,由于是RGBA格式,使用default.effect-DrawAlphaDivide着色器实现。输入参数为render_texture,输出为output_texture。具体过程详见render_output_texture。

static inline gs_texture_t *render_output_texture(struct obs_core_video *video)
{
    gs_texture_t *texture = video->render_texture;
    gs_texture_t *target = video->output_texture;
    uint32_t width = gs_texture_get_width(target);
    uint32_t height = gs_texture_get_height(target);

    gs_set_render_target(target, NULL);

    set_render_size(width, height);
    {
        gs_enable_depth_test(false);
        gs_set_cull_mode(GS_NEITHER);

        gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
        gs_set_viewport(0, 0, width, height);
    }

    //set paramter
    gs_effect_set_texture_srgb(image, texture);

    ...
}

VS着色器:

uniform float4x4 ViewProj;


struct VertInOut {
    float4 pos : POSITION;
    float2 uv : TEXCOORD0;
};

VertInOut VSDefault(VertInOut vert_in)
{
    VertInOut vert_out;
    vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
    vert_out.uv  = vert_in.uv;
    return vert_out;
}

VertInOut main(VertInOut vert_in)
{
    return VSDefault(vert_in);
}

PS着色器

uniform texture2d image;


sampler_state def_sampler {
    Filter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};

struct VertInOut {
    float4 pos : POSITION;
    float2 uv : TEXCOORD0;
};

float4 PSDrawAlphaDivide(VertInOut vert_in)
{
    float4 rgba = image.Sample(def_sampler, vert_in.uv);
    rgba.rgb *= (rgba.a > 0.) ? (1. / rgba.a) : 0.;
    return rgba;
}

float4 main(VertInOut vert_in) : TARGET
{
    return PSDrawAlphaDivide(vert_in);
}

解释:

uniform texture2d image;
sampler_state def_sampler {
    Filter = Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};
  • uniform texture2d image;声明一个名为 image 的2D纹理资源,用于存储输入图像。
  • sampler_state def_sampler:定义了一个采样器状态 def_sampler,它指定了纹理采样的方式:
    • Filter = Linear;:使用线性过滤(双线性插值),使得纹理在放大或缩小时平滑过渡。
    • AddressU = Clamp; 和 AddressV = Clamp;当纹理坐标超出 [0, 1] 范围时,使用边缘像素进行填充。

PSDrawAlphaDivide 函数的作用是:

  • 使用 def_sampler 从 image 纹理中采样得到当前片段的RGBA颜色值。
  • 对于每个像素,检查其 Alpha 值 (rgba.a) 是否大于0:
  • 如果 Alpha 值大于0,则将 RGB 分量除以 Alpha 值 (rgba.rgb *= 1. / rgba.a),以标准化颜色。
  • 如果 Alpha 值等于0,则将 RGB 分量设置为0 (rgba.rgb *= 0.),避免除以零的错误。
  • •返回处理后的 RGBA 颜色值。

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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