diff options
author | Benjamin Otte <otte@redhat.com> | 2023-05-07 01:06:52 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2023-05-17 02:25:32 +0200 |
commit | 53c04ca39ce4dc5f34f8d84ffccbf3f839cff830 (patch) | |
tree | 8d6e0f7bb904a9cc051d86337cb52ea34262dc6f /gsk/vulkan/resources | |
parent | 0e5d48ea39530188cab6c3cc6d490f7acca368b4 (diff) | |
download | gtk+-53c04ca39ce4dc5f34f8d84ffccbf3f839cff830.tar.gz |
vulkan: Start rework on shaders to allow antialiased drawing
This introduces the rect object and adds a rect_distance() and
rect_coverage() function.
_distance() returns the signed distance tp the rectangle.
_coverage() returns the coverage of a pixel centered at that position.
Note that the pixel size is computed using dFdx/dFdy.
Diffstat (limited to 'gsk/vulkan/resources')
-rw-r--r-- | gsk/vulkan/resources/clip.vert.glsl | 31 | ||||
-rw-r--r-- | gsk/vulkan/resources/color.frag | 7 | ||||
-rw-r--r-- | gsk/vulkan/resources/color.vert | 9 | ||||
-rw-r--r-- | gsk/vulkan/resources/meson.build | 3 | ||||
-rw-r--r-- | gsk/vulkan/resources/rect.frag.glsl | 16 | ||||
-rw-r--r-- | gsk/vulkan/resources/rect.glsl | 46 | ||||
-rw-r--r-- | gsk/vulkan/resources/rect.vert.glsl | 6 |
7 files changed, 111 insertions, 7 deletions
diff --git a/gsk/vulkan/resources/clip.vert.glsl b/gsk/vulkan/resources/clip.vert.glsl index 0dce1a0fb7..ae5c75a39d 100644 --- a/gsk/vulkan/resources/clip.vert.glsl +++ b/gsk/vulkan/resources/clip.vert.glsl @@ -1,4 +1,5 @@ #include "constants.glsl" +#include "rect.vert.glsl" #ifndef _CLIP_ #define _CLIP_ @@ -14,21 +15,47 @@ vec4 intersect(vec4 a, vec4 b) } #ifdef CLIP_ROUNDED_RECT -vec4 clip(vec4 rect) + +vec4 +clip(vec4 rect) { /* rounded corner clipping is done in fragment shader */ return intersect(rect, push.clip_bounds); } + +Rect +clip_rect (vec4 xywh) +{ + /* rounded corner clipping is done in fragment shader */ + return rect_intersect (rect_from_gsk (xywh), rect_to_int (rect_from_gsk (push.clip_bounds))); +} + #elif defined(CLIP_RECT) -vec4 clip(vec4 rect) + +vec4 +clip(vec4 rect) { return intersect(rect, push.clip_bounds); } + +Rect +clip_rect (vec4 xywh) +{ + return rect_intersect (rect_from_gsk (xywh), rect_to_int (rect_from_gsk (push.clip_bounds))); +} + #elif defined(CLIP_NONE) vec4 clip(vec4 rect) { return rect; } + +Rect +clip_rect (vec4 xywh) +{ + return rect_from_gsk (xywh); +} + #else #error "No clipping define given. Need CLIP_NONE, CLIP_RECT or CLIP_ROUNDED_RECT" #endif diff --git a/gsk/vulkan/resources/color.frag b/gsk/vulkan/resources/color.frag index 6b299dffd0..1f988b6517 100644 --- a/gsk/vulkan/resources/color.frag +++ b/gsk/vulkan/resources/color.frag @@ -1,13 +1,16 @@ #version 420 core #include "clip.frag.glsl" +#include "rect.frag.glsl" layout(location = 0) in vec2 inPos; -layout(location = 1) in vec4 inColor; +layout(location = 1) in Rect inRect; +layout(location = 2) in vec4 inColor; layout(location = 0) out vec4 color; void main() { - color = clip (inPos, vec4(inColor.rgb * inColor.a, inColor.a)); + float alpha = inColor.a * rect_coverage (inRect, inPos); + color = clip (inPos, vec4(inColor.rgb, 1) * alpha); } diff --git a/gsk/vulkan/resources/color.vert b/gsk/vulkan/resources/color.vert index 1e1618aef9..7601b7d82a 100644 --- a/gsk/vulkan/resources/color.vert +++ b/gsk/vulkan/resources/color.vert @@ -1,12 +1,14 @@ #version 420 core #include "clip.vert.glsl" +#include "rect.vert.glsl" layout(location = 0) in vec4 inRect; layout(location = 1) in vec4 inColor; layout(location = 0) out vec2 outPos; -layout(location = 1) out flat vec4 outColor; +layout(location = 1) out flat Rect outRect; +layout(location = 2) out flat vec4 outColor; vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 0.0), @@ -16,10 +18,11 @@ vec2 offsets[6] = { vec2(0.0, 0.0), vec2(1.0, 1.0) }; void main() { - vec4 rect = clip (inRect); + Rect rect = rect_to_int (clip_rect (inRect)); - vec2 pos = rect.xy + rect.zw * offsets[gl_VertexIndex]; + vec2 pos = mix (rect.bounds.xy, rect.bounds.zw, offsets[gl_VertexIndex]); gl_Position = push.mvp * vec4 (pos, 0.0, 1.0); outPos = pos; + outRect = rect_from_gsk (inRect); outColor = inColor; } diff --git a/gsk/vulkan/resources/meson.build b/gsk/vulkan/resources/meson.build index 86e98acb9e..802f391b4d 100644 --- a/gsk/vulkan/resources/meson.build +++ b/gsk/vulkan/resources/meson.build @@ -2,6 +2,9 @@ gsk_private_vulkan_include_shaders = [ 'clip.frag.glsl', 'clip.vert.glsl', 'constants.glsl', + 'rect.glsl', + 'rect.frag.glsl', + 'rect.vert.glsl', 'rounded-rect.glsl', ] diff --git a/gsk/vulkan/resources/rect.frag.glsl b/gsk/vulkan/resources/rect.frag.glsl new file mode 100644 index 0000000000..73e9db9fd5 --- /dev/null +++ b/gsk/vulkan/resources/rect.frag.glsl @@ -0,0 +1,16 @@ +#ifndef _RECT_FRAG_ +#define _RECT_FRAG_ + +#include "rect.glsl" + +float +rect_coverage (Rect r, vec2 p) +{ + vec2 dFdp = abs(fwidth (p)); + Rect prect = Rect(vec4(p - 0.5 * dFdp, p + 0.5 * dFdp)); + Rect coverect = rect_intersect (r, prect); + vec2 coverage = rect_size(coverect) / dFdp; + return coverage.x * coverage.y; +} + +#endif diff --git a/gsk/vulkan/resources/rect.glsl b/gsk/vulkan/resources/rect.glsl new file mode 100644 index 0000000000..ba07a05a98 --- /dev/null +++ b/gsk/vulkan/resources/rect.glsl @@ -0,0 +1,46 @@ +#ifndef _RECT_ +#define _RECT_ + +struct Rect +{ + /* x,y and y,w make up the 2 points of this rect, + note that this is not containing width or height */ + vec4 bounds; +}; + +Rect +rect_from_gsk (vec4 xywh) +{ + return Rect(xywh.xyxy + vec4(0,0,xywh.zw)); +} + +float +rect_distance (Rect r, vec2 p) +{ + vec4 distance = (r.bounds - p.xyxy) * vec4(1.0, 1.0, -1.0, -1.0); + vec2 max2 = max (distance.xy, distance.zw); + return length (max (max2, 0)) + min (max(max2.x, max2.y), 0); +} + +vec2 +rect_size (Rect r) +{ + return r.bounds.zw - r.bounds.xy; +} + +Rect +rect_to_int (Rect r) +{ + return Rect (vec4 (floor(r.bounds.xy), ceil (r.bounds.zw))); +} + +Rect +rect_intersect (Rect a, Rect b) +{ + vec4 result = vec4(max(a.bounds.xy, b.bounds.xy), min(a.bounds.zw, b.bounds.zw)); + if (any (greaterThanEqual (result.xy, result.zw))) + return Rect (vec4(0.0)); + return Rect(result); +} + +#endif diff --git a/gsk/vulkan/resources/rect.vert.glsl b/gsk/vulkan/resources/rect.vert.glsl new file mode 100644 index 0000000000..e6f90b8dd1 --- /dev/null +++ b/gsk/vulkan/resources/rect.vert.glsl @@ -0,0 +1,6 @@ +#ifndef _RECT_VERT_ +#define _RECT_VERT_ + +#include "rect.glsl" + +#endif |