135 lines
4.0 KiB
Plaintext
135 lines
4.0 KiB
Plaintext
ConstantBuffer<UI_RectSig> UI_rect_sig : register (b0);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Rect
|
|
|
|
Struct(UI_RectPS_Input)
|
|
{
|
|
|
|
Semantic(Vec4, sv_position);
|
|
Semantic(nointerpolation u32, rect_idx);
|
|
Semantic(Vec4, background_lin);
|
|
Semantic(Vec4, border_lin);
|
|
Semantic(Vec4, tint_lin);
|
|
Semantic(Vec2, rect_uv);
|
|
Semantic(Vec2, tex_uv);
|
|
};
|
|
|
|
Struct(UI_RectPS_Output)
|
|
{
|
|
Semantic(Vec4, sv_target0);
|
|
};
|
|
|
|
//- Vertex shader
|
|
|
|
UI_RectPS_Input VSDef(UI_RectVS, Semantic(u32, sv_instanceid), Semantic(u32, sv_vertexid))
|
|
{
|
|
ConstantBuffer<UI_RectSig> sig = UI_rect_sig;
|
|
StructuredBuffer<UI_RectInstance> rects = UniformResourceFromRid(sig.rects);
|
|
UI_RectInstance rect = rects[sv_instanceid];
|
|
|
|
Vec2 rect_uv = RectUvFromVertexId(sv_vertexid);
|
|
Vec2 tex_uv = lerp(rect.tex_uv0, rect.tex_uv1, rect_uv);
|
|
Vec2 screen_vert = lerp(rect.p0, rect.p1, rect_uv);
|
|
|
|
UI_RectPS_Input result;
|
|
result.sv_position = Vec4(NdcFromViewport(sig.viewport_size, screen_vert).xy, 0, 1);
|
|
result.background_lin = rect.background_lin;
|
|
result.border_lin = rect.border_lin;
|
|
result.tint_lin = rect.tint_lin;
|
|
result.rect_idx = sv_instanceid;
|
|
result.rect_uv = rect_uv;
|
|
result.tex_uv = tex_uv;
|
|
|
|
return result;
|
|
}
|
|
|
|
//- Pixel shader
|
|
UI_RectPS_Output PSDef(UI_RectPS, UI_RectPS_Input input)
|
|
{
|
|
ConstantBuffer<UI_RectSig> sig = UI_rect_sig;
|
|
StructuredBuffer<UI_RectInstance> rects = UniformResourceFromRid(sig.rects);
|
|
UI_RectInstance rect = rects[input.rect_idx];
|
|
|
|
Vec2 p = input.sv_position.xy;
|
|
Vec2 rect_uv = input.rect_uv;
|
|
Vec2 p0 = rect.p0;
|
|
Vec2 p1 = rect.p1;
|
|
|
|
/* Calculate rect sdf (negative means pixel is inside of rect) */
|
|
f32 rect_dist = min(min(p.x - p0.x, p1.x - p.x), min(p.y - p0.y, p1.y - p.y));
|
|
{
|
|
f32 tl_radius = rect.tl_rounding;
|
|
f32 tr_radius = rect.tr_rounding;
|
|
f32 br_radius = rect.br_rounding;
|
|
f32 bl_radius = rect.bl_rounding;
|
|
Vec2 tl = Vec2(p0.x + tl_radius, p0.y + tl_radius);
|
|
Vec2 tr = Vec2(p1.x - tr_radius, p0.y + tr_radius);
|
|
Vec2 br = Vec2(p1.x - br_radius, p1.y - br_radius);
|
|
Vec2 bl = Vec2(p0.x + bl_radius, p1.y - bl_radius);
|
|
if (p.x < tl.x && p.y < tl.y) { rect_dist = min(rect_dist, tl_radius - length(tl - p)); }
|
|
if (p.x > tr.x && p.y < tr.y) { rect_dist = min(rect_dist, tr_radius - length(tr - p)); }
|
|
if (p.x > br.x && p.y > br.y) { rect_dist = min(rect_dist, br_radius - length(br - p)); }
|
|
if (p.x < bl.x && p.y > bl.y) { rect_dist = min(rect_dist, bl_radius - length(bl - p)); }
|
|
}
|
|
rect_dist = -rect_dist;
|
|
|
|
/* Calculate border sdf (negative means pixel is inside of border) */
|
|
f32 border_width = 0;
|
|
f32 border_dist = 0;
|
|
Vec4 border_color = 0;
|
|
{
|
|
if (rect.border > 0)
|
|
{
|
|
border_width = rect.border;
|
|
border_color = input.border_lin;
|
|
}
|
|
else
|
|
{
|
|
border_width = 0;
|
|
border_color = input.background_lin;
|
|
}
|
|
border_dist = abs(rect_dist);
|
|
if (rect_dist <= 0)
|
|
{
|
|
border_dist -= border_width;
|
|
}
|
|
}
|
|
|
|
/* Background color */
|
|
Vec4 background_color = 0;
|
|
{
|
|
if (rect_dist <= 0)
|
|
{
|
|
if (border_dist <= 0)
|
|
{
|
|
background_color = border_color;
|
|
}
|
|
else if (rect.flags & UI_RectFlag_DrawTexture)
|
|
{
|
|
SamplerState sampler = UniformSamplerFromRid(sig.sampler);
|
|
Texture2D<Vec4> tex = NonUniformResourceFromRid(rect.tex);
|
|
background_color = tex.Sample(sampler, input.tex_uv);
|
|
}
|
|
else
|
|
{
|
|
background_color = input.background_lin;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Final color */
|
|
Vec4 final_color = background_color;
|
|
final_color *= input.tint_lin;
|
|
|
|
/* Debug color */
|
|
if (sig.debug_enabled)
|
|
{
|
|
final_color = rect.debug_lin;
|
|
}
|
|
|
|
UI_RectPS_Output output;
|
|
output.sv_target0 = final_color;
|
|
return output;
|
|
}
|