2019-07-27 12:47:10 +00:00
|
|
|
uniform float4x4 ViewProj;
|
2019-09-22 21:19:10 +00:00
|
|
|
uniform float2 base_dimension;
|
2019-07-27 12:47:10 +00:00
|
|
|
uniform float2 base_dimension_i;
|
|
|
|
uniform texture2d image;
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
sampler_state textureSampler {
|
|
|
|
Filter = Linear;
|
|
|
|
AddressU = Clamp;
|
|
|
|
AddressV = Clamp;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct VertData {
|
2019-07-27 12:47:10 +00:00
|
|
|
float4 pos : POSITION;
|
|
|
|
float2 uv : TEXCOORD0;
|
|
|
|
};
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
struct VertInOut {
|
|
|
|
float2 uv : TEXCOORD0;
|
|
|
|
float4 pos : POSITION;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FragData {
|
|
|
|
float2 uv : TEXCOORD0;
|
|
|
|
};
|
|
|
|
|
|
|
|
VertInOut VSDefault(VertData vert_in)
|
2019-07-27 12:47:10 +00:00
|
|
|
{
|
|
|
|
VertInOut vert_out;
|
|
|
|
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
|
|
|
|
vert_out.uv = vert_in.uv;
|
|
|
|
return vert_out;
|
|
|
|
}
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
float4 DrawArea(float2 uv)
|
|
|
|
{
|
|
|
|
float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
|
|
|
|
|
|
|
|
// Handle potential OpenGL flip.
|
|
|
|
if (obs_glsl_compile)
|
|
|
|
uv_delta.y = abs(uv_delta.y);
|
|
|
|
|
|
|
|
float2 uv_min = uv - 0.5 * uv_delta;
|
|
|
|
float2 uv_max = uv_min + uv_delta;
|
|
|
|
|
|
|
|
float2 load_index_begin = floor(uv_min * base_dimension);
|
|
|
|
float2 load_index_end = ceil(uv_max * base_dimension);
|
|
|
|
|
|
|
|
float2 target_dimension = 1.0 / uv_delta;
|
|
|
|
float2 target_pos = uv * target_dimension;
|
|
|
|
float2 target_pos_min = target_pos - 0.5;
|
|
|
|
float2 target_pos_max = target_pos + 0.5;
|
|
|
|
float2 scale = base_dimension_i * target_dimension;
|
|
|
|
|
|
|
|
float4 total_color = float4(0.0, 0.0, 0.0, 0.0);
|
|
|
|
|
|
|
|
float load_index_y = load_index_begin.y;
|
|
|
|
do {
|
|
|
|
float source_y_min = load_index_y * scale.y;
|
|
|
|
float source_y_max = source_y_min + scale.y;
|
|
|
|
float y_min = max(source_y_min, target_pos_min.y);
|
|
|
|
float y_max = min(source_y_max, target_pos_max.y);
|
|
|
|
float height = y_max - y_min;
|
|
|
|
|
|
|
|
float load_index_x = load_index_begin.x;
|
|
|
|
do {
|
|
|
|
float source_x_min = load_index_x * scale.x;
|
|
|
|
float source_x_max = source_x_min + scale.x;
|
|
|
|
float x_min = max(source_x_min, target_pos_min.x);
|
|
|
|
float x_max = min(source_x_max, target_pos_max.x);
|
|
|
|
float width = x_max - x_min;
|
|
|
|
float area = width * height;
|
|
|
|
|
|
|
|
float4 color = image.Load(int3(load_index_x, load_index_y, 0));
|
|
|
|
total_color += area * color;
|
|
|
|
|
|
|
|
++load_index_x;
|
|
|
|
} while (load_index_x < load_index_end.x);
|
|
|
|
|
|
|
|
++load_index_y;
|
|
|
|
} while (load_index_y < load_index_end.y);
|
|
|
|
|
|
|
|
return total_color;
|
|
|
|
}
|
|
|
|
|
|
|
|
float4 PSDrawAreaRGBA(FragData frag_in) : TARGET
|
2019-07-27 12:47:10 +00:00
|
|
|
{
|
2019-09-22 21:19:10 +00:00
|
|
|
return DrawArea(frag_in.uv);
|
|
|
|
}
|
2019-07-27 12:47:10 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
float4 PSDrawAreaRGBADivide(FragData frag_in) : TARGET
|
|
|
|
{
|
|
|
|
float4 rgba = DrawArea(frag_in.uv);
|
|
|
|
float alpha = rgba.a;
|
|
|
|
float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0;
|
|
|
|
return float4(rgba.rgb * multiplier, alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
float4 PSDrawAreaRGBAUpscale(FragData frag_in) : TARGET
|
|
|
|
{
|
|
|
|
float2 uv = frag_in.uv;
|
|
|
|
float2 uv_delta = float2(ddx(uv.x), ddy(uv.y));
|
2019-07-27 12:47:10 +00:00
|
|
|
|
|
|
|
// Handle potential OpenGL flip.
|
2019-09-22 21:19:10 +00:00
|
|
|
if (obs_glsl_compile)
|
|
|
|
uv_delta.y = abs(uv_delta.y);
|
|
|
|
|
|
|
|
float2 uv_min = uv - 0.5 * uv_delta;
|
|
|
|
float2 uv_max = uv_min + uv_delta;
|
2019-07-27 12:47:10 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
float2 load_index_first = floor(uv_min * base_dimension);
|
|
|
|
float2 load_index_last = ceil(uv_max * base_dimension) - 1.0;
|
2019-07-27 12:47:10 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
if (load_index_first.x < load_index_last.x) {
|
|
|
|
float uv_boundary_x = load_index_last.x * base_dimension_i.x;
|
|
|
|
uv.x = ((uv.x - uv_boundary_x) / uv_delta.x) * base_dimension_i.x + uv_boundary_x;
|
|
|
|
} else
|
|
|
|
uv.x = (load_index_first.x + 0.5) * base_dimension_i.x;
|
|
|
|
if (load_index_first.y < load_index_last.y) {
|
|
|
|
float uv_boundary_y = load_index_last.y * base_dimension_i.y;
|
|
|
|
uv.y = ((uv.y - uv_boundary_y) / uv_delta.y) * base_dimension_i.y + uv_boundary_y;
|
|
|
|
} else
|
|
|
|
uv.y = (load_index_first.y + 0.5) * base_dimension_i.y;
|
|
|
|
|
|
|
|
return image.Sample(textureSampler, uv);
|
|
|
|
}
|
2019-07-27 12:47:10 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
technique Draw
|
|
|
|
{
|
|
|
|
pass
|
2019-07-27 12:47:10 +00:00
|
|
|
{
|
2019-09-22 21:19:10 +00:00
|
|
|
vertex_shader = VSDefault(vert_in);
|
|
|
|
pixel_shader = PSDrawAreaRGBA(frag_in);
|
2019-07-27 12:47:10 +00:00
|
|
|
}
|
2019-09-22 21:19:10 +00:00
|
|
|
}
|
2019-07-27 12:47:10 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
technique DrawAlphaDivide
|
|
|
|
{
|
|
|
|
pass
|
|
|
|
{
|
|
|
|
vertex_shader = VSDefault(vert_in);
|
|
|
|
pixel_shader = PSDrawAreaRGBADivide(frag_in);
|
|
|
|
}
|
2019-07-27 12:47:10 +00:00
|
|
|
}
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
technique DrawUpscale
|
2019-07-27 12:47:10 +00:00
|
|
|
{
|
|
|
|
pass
|
|
|
|
{
|
|
|
|
vertex_shader = VSDefault(vert_in);
|
2019-09-22 21:19:10 +00:00
|
|
|
pixel_shader = PSDrawAreaRGBAUpscale(frag_in);
|
2019-07-27 12:47:10 +00:00
|
|
|
}
|
|
|
|
}
|