mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-15 07:44:10 +00:00
libobs: Render main texture for active color space
Preview will draw SDR white luminance from settings (default 300 nits) when displayed on an HDR monitor rather than CCCS 80 nits.
This commit is contained in:
parent
5748ab7e0d
commit
87ab39c412
|
@ -1,5 +1,6 @@
|
|||
uniform float4x4 ViewProj;
|
||||
uniform texture2d image;
|
||||
uniform float multiplier;
|
||||
|
||||
sampler_state def_sampler {
|
||||
Filter = Linear;
|
||||
|
@ -69,6 +70,48 @@ float4 PSDrawSrgbDecompress(VertInOut vert_in) : TARGET
|
|||
return rgba;
|
||||
}
|
||||
|
||||
float4 PSDrawMultiply(VertInOut vert_in) : TARGET
|
||||
{
|
||||
float4 rgba = image.Sample(def_sampler, vert_in.uv);
|
||||
rgba.rgb *= multiplier;
|
||||
return rgba;
|
||||
}
|
||||
|
||||
float3 rec709_to_rec2020(float3 v)
|
||||
{
|
||||
float r = dot(v, float3(0.6274040f, 0.3292820f, 0.0433136f));
|
||||
float g = dot(v, float3(0.0690970f, 0.9195400f, 0.0113612f));
|
||||
float b = dot(v, float3(0.0163916f, 0.0880132f, 0.8955950f));
|
||||
return float3(r, g, b);
|
||||
}
|
||||
|
||||
float3 rec2020_to_rec709(float3 v)
|
||||
{
|
||||
float r = dot(v, float3(1.6604910, -0.5876411, -0.0728499));
|
||||
float g = dot(v, float3(-0.1245505, 1.1328999, -0.0083494));
|
||||
float b = dot(v, float3(-0.0181508, -0.1005789, 1.1187297));
|
||||
return float3(r, g, b);
|
||||
}
|
||||
|
||||
float reinhard_channel(float x)
|
||||
{
|
||||
return x / (x + 1.0);
|
||||
}
|
||||
|
||||
float3 reinhard(float3 rgb)
|
||||
{
|
||||
return float3(reinhard_channel(rgb.r), reinhard_channel(rgb.g), reinhard_channel(rgb.b));
|
||||
}
|
||||
|
||||
float4 PSDrawTonemap(VertInOut vert_in) : TARGET
|
||||
{
|
||||
float4 rgba = image.Sample(def_sampler, vert_in.uv);
|
||||
rgba.rgb = rec709_to_rec2020(rgba.rgb);
|
||||
rgba.rgb = reinhard(rgba.rgb);
|
||||
rgba.rgb = rec2020_to_rec709(rgba.rgb);
|
||||
return rgba;
|
||||
}
|
||||
|
||||
technique Draw
|
||||
{
|
||||
pass
|
||||
|
@ -104,3 +147,21 @@ technique DrawSrgbDecompress
|
|||
pixel_shader = PSDrawSrgbDecompress(vert_in);
|
||||
}
|
||||
}
|
||||
|
||||
technique DrawMultiply
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vert_in);
|
||||
pixel_shader = PSDrawMultiply(vert_in);
|
||||
}
|
||||
}
|
||||
|
||||
technique DrawTonemap
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSDefault(vert_in);
|
||||
pixel_shader = PSDrawTonemap(vert_in);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,6 +256,7 @@ struct obs_core_video {
|
|||
#endif
|
||||
gs_texture_t *render_texture;
|
||||
gs_texture_t *output_texture;
|
||||
enum gs_color_space render_space;
|
||||
bool texture_rendered;
|
||||
bool textures_copied[NUM_TEXTURES];
|
||||
bool texture_converted;
|
||||
|
|
|
@ -133,7 +133,8 @@ static inline void render_main_texture(struct obs_core_video *video)
|
|||
struct vec4 clear_color;
|
||||
vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
gs_set_render_target(video->render_texture, NULL);
|
||||
gs_set_render_target_with_color_space(video->render_texture, NULL,
|
||||
video->render_space);
|
||||
gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0);
|
||||
|
||||
set_render_size(video->base_width, video->base_height);
|
||||
|
|
36
libobs/obs.c
36
libobs/obs.c
|
@ -268,19 +268,24 @@ static bool obs_init_textures(struct obs_video_info *ovi)
|
|||
}
|
||||
}
|
||||
|
||||
enum gs_color_format format = GS_RGBA;
|
||||
enum gs_color_space space = GS_CS_SRGB;
|
||||
|
||||
video->render_texture = gs_texture_create(ovi->base_width,
|
||||
ovi->base_height, GS_RGBA, 1,
|
||||
ovi->base_height, format, 1,
|
||||
NULL, GS_RENDER_TARGET);
|
||||
if (!video->render_texture)
|
||||
success = false;
|
||||
|
||||
video->output_texture = gs_texture_create(ovi->output_width,
|
||||
ovi->output_height, GS_RGBA,
|
||||
1, NULL, GS_RENDER_TARGET);
|
||||
ovi->output_height, format, 1,
|
||||
NULL, GS_RENDER_TARGET);
|
||||
if (!video->output_texture)
|
||||
success = false;
|
||||
|
||||
if (!success) {
|
||||
if (success) {
|
||||
video->render_space = space;
|
||||
} else {
|
||||
for (size_t i = 0; i < NUM_TEXTURES; i++) {
|
||||
for (size_t c = 0; c < NUM_CHANNELS; c++) {
|
||||
if (video->copy_surfaces[i][c]) {
|
||||
|
@ -1807,18 +1812,37 @@ static void obs_render_main_texture_internal(enum gs_blend_type src_c,
|
|||
if (!video->texture_rendered)
|
||||
return;
|
||||
|
||||
const enum gs_color_space source_space = video->render_space;
|
||||
const enum gs_color_space current_space = gs_get_color_space();
|
||||
const char *tech_name = "Draw";
|
||||
float multiplier = 1.0f;
|
||||
if ((current_space == GS_CS_SRGB) &&
|
||||
(source_space == GS_CS_709_EXTENDED)) {
|
||||
tech_name = "DrawTonemap";
|
||||
} else if (current_space == GS_CS_709_SCRGB) {
|
||||
tech_name = "DrawMultiply";
|
||||
multiplier = obs_get_video_sdr_white_level() / 80.0f;
|
||||
}
|
||||
|
||||
const bool previous = gs_framebuffer_srgb_enabled();
|
||||
gs_enable_framebuffer_srgb(true);
|
||||
|
||||
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);
|
||||
gs_effect_set_texture_srgb(param, tex);
|
||||
param = gs_effect_get_param_by_name(effect, "multiplier");
|
||||
gs_effect_set_float(param, multiplier);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function_separate(src_c, dest_c, src_a, dest_a);
|
||||
|
||||
while (gs_effect_loop(effect, "Draw"))
|
||||
while (gs_effect_loop(effect, tech_name))
|
||||
gs_draw_sprite(tex, 0, 0, 0);
|
||||
|
||||
gs_blend_state_pop();
|
||||
|
||||
gs_enable_framebuffer_srgb(previous);
|
||||
}
|
||||
|
||||
void obs_render_main_texture(void)
|
||||
|
|
Loading…
Reference in a new issue