OBS图形及渲染
+ -

着色器参数的跟踪

2024-12-12 6 0

VS着色器

default.effect-Draw[0].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);
}

VS常量参数只有一个就是uniform float4x4 ViewProj,其是一个齐次坐标系。
VS常量设置于device_load_vertexshader中,其参数来源于gs_shader_t *vertshader。

void device_load_vertexshader(gs_device_t *device, gs_shader_t *vertshader)
{
    ID3D11VertexShader *shader = NULL;
    ID3D11InputLayout *layout = NULL;
    ID3D11Buffer *constants = NULL;

    shader = vs->shader;
    layout = vs->layout;
    constants = vs->constants;

    device->context->VSSetShader(shader, NULL, 0);
    device->context->IASetInputLayout(layout);
    device->context->VSSetConstantBuffers(0, 1, &constants);
}

其中shader和layout都是固定的,在创建着着色器时就可以指定.常量参数ViewProj使用device_draw中通过UpdateViewProjMatrix()更新内容,最终在device->curVertexShader->UploadParams()映射内容到着色器空间中。

顶点

顶点更新设置见gs_draw_sprite

    while (gs_effect_loop(effect, "Draw"))
        gs_draw_sprite(tex, 0, 0, 0);

gs_draw_sprite函数中获取其顶点缓冲区的反映针,更新设置

void gs_draw_sprite(gs_texture_t *tex, uint32_t flip, uint32_t width, uint32_t height)
{
    fcx = width ? (float)width : (float)gs_texture_get_width(tex);
    fcy = height ? (float)height : (float)gs_texture_get_height(tex);
    data = gs_vertexbuffer_get_data(graphics->sprite_buffer);
    if (tex && gs_texture_is_rect(tex))
        build_sprite_rect(data, tex, fcx, fcy, flip);
    else
        build_sprite_norm(data, fcx, fcy, flip);

    gs_vertexbuffer_flush(graphics->sprite_buffer);
    gs_load_vertexbuffer(graphics->sprite_buffer);
    gs_load_indexbuffer(NULL);

    gs_draw(GS_TRISTRIP, 0, 0);
}

最终在device_draw中调用

    device->curPixelShader->UploadParams();

PS着色器

default.effect-Draw[0].PS

uniform texture2d image;

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

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

float4 PSDrawBare(VertInOut vert_in)
{
    return image.Sample(def_sampler, vert_in.uv);
}

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

PS常量空间参数为:uniform texture2d image

只有常量参数constants随时会发生变化。故其设置如下:

    struct obs_core_video *video;
    tex = video->render_texture;
    video = &obs->video;
    tex = video->render_texture;

    effect = obs_get_base_effect(OBS_EFFECT_DEFAULT);
    param = gs_effect_get_param_by_name(effect, "image");
    gs_effect_set_texture(param, tex);

注意,这里的参数只是记录到effect的param参数中,还没有更新至HLSL的常量空间中。实际更新是在device_draw函数的gs_effect_update_params中,其本质是当在device_load_vertexshader绑定了常量空间之后,将effect中的参数值通过map更新至HLSL显卡空间中。

0 篇笔记 写笔记

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

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

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