着色器参数的跟踪
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显卡空间中。