From 40f45d7b7e35dd4937abe6b5ce16b6256b4f1eeb Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 29 Sep 2022 10:52:58 -0700 Subject: Adds linear gradient support to 2D meshes in the canvas widget. --- glow/src/shader/common/gradient.frag | 48 ++++++++++++++++++++++++++++++++++++ glow/src/shader/common/triangle.frag | 4 +-- glow/src/shader/common/triangle.vert | 6 ++--- 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 glow/src/shader/common/gradient.frag (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag new file mode 100644 index 00000000..588f63e0 --- /dev/null +++ b/glow/src/shader/common/gradient.frag @@ -0,0 +1,48 @@ +// GLSL does not support dynamically sized arrays without SSBOs +#define MAX_STOPS 64 + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + +#ifdef HIGHER_THAN_300 +layout (location = 0) out vec4 fragColor; +#define gl_FragColor fragColor +#endif + +in vec2 raw_position; + +uniform vec2 gradient_start; +uniform vec2 gradient_end; + +uniform uint color_stops_size; +uniform float color_stop_offsets[MAX_STOPS]; +uniform vec4 color_stop_colors[MAX_STOPS]; + +void main() { + vec2 gradient_vec = vec2(gradient_end - gradient_start); + vec2 current_vec = vec2(raw_position.xy - gradient_start); + vec2 unit = normalize(gradient_vec); + float coord_offset = dot(unit, current_vec) / length(gradient_vec); + + for (uint i = 0; i < color_stops_size - 1; i++) { + float stop_offset = color_stop_offsets[i]; + float next_stop_offset = color_stop_offsets[i + 1]; + + if (stop_offset <= coord_offset && coord_offset <= next_stop_offset) { + fragColor = mix(color_stop_colors[i], color_stop_colors[i+1], smoothstep( + stop_offset, + next_stop_offset, + coord_offset + )); + } else if (coord_offset < color_stop_offsets[0]) { + fragColor = color_stop_colors[0]; + } else if (coord_offset > color_stop_offsets[color_stops_size - 1]) { + fragColor = color_stop_colors[color_stops_size - 1]; + } + } +} \ No newline at end of file diff --git a/glow/src/shader/common/triangle.frag b/glow/src/shader/common/triangle.frag index e8689f2e..0ee65239 100644 --- a/glow/src/shader/common/triangle.frag +++ b/glow/src/shader/common/triangle.frag @@ -11,8 +11,8 @@ out vec4 fragColor; #define gl_FragColor fragColor #endif -in vec4 v_Color; +uniform vec4 color; void main() { - gl_FragColor = v_Color; + fragColor = color; } \ No newline at end of file diff --git a/glow/src/shader/common/triangle.vert b/glow/src/shader/common/triangle.vert index d0494a5f..09a4e324 100644 --- a/glow/src/shader/common/triangle.vert +++ b/glow/src/shader/common/triangle.vert @@ -1,11 +1,9 @@ uniform mat4 u_Transform; in vec2 i_Position; -in vec4 i_Color; - -out vec4 v_Color; +out vec2 raw_position; void main() { gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); - v_Color = i_Color; + raw_position = i_Position; } \ No newline at end of file -- cgit From 6e7b3ced0b1daf368e44e181ecdb4ae529877eb6 Mon Sep 17 00:00:00 2001 From: shan Date: Tue, 4 Oct 2022 18:24:46 -0700 Subject: Reworked wgpu buffers, updated glow side to have proper transform location storage, attempting to fix visibility modifiers, implemented some of the feedback received in initial PR. --- glow/src/shader/common/gradient.frag | 1 + 1 file changed, 1 insertion(+) (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 588f63e0..1afb557d 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -23,6 +23,7 @@ uniform uint color_stops_size; uniform float color_stop_offsets[MAX_STOPS]; uniform vec4 color_stop_colors[MAX_STOPS]; +//TODO: rewrite without branching to make ALUs happy void main() { vec2 gradient_vec = vec2(gradient_end - gradient_start); vec2 current_vec = vec2(raw_position.xy - gradient_start); -- cgit From 1eb8d972ba60592da7bfc27fe7ec80138e64dd7b Mon Sep 17 00:00:00 2001 From: shan Date: Wed, 5 Oct 2022 16:07:43 -0700 Subject: Reduced memory transfer of OpenGL gradient uniform upload. Rearranged gradient uniforms on OpenGL side to be more performant. --- glow/src/shader/common/gradient.frag | 43 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 1afb557d..89d2d398 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -1,6 +1,3 @@ -// GLSL does not support dynamically sized arrays without SSBOs -#define MAX_STOPS 64 - #ifdef GL_ES #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; @@ -16,34 +13,38 @@ layout (location = 0) out vec4 fragColor; in vec2 raw_position; -uniform vec2 gradient_start; -uniform vec2 gradient_end; - +uniform vec4 gradient_direction; uniform uint color_stops_size; -uniform float color_stop_offsets[MAX_STOPS]; -uniform vec4 color_stop_colors[MAX_STOPS]; +// GLSL does not support dynamically sized arrays without SSBOs so this is capped to 16 stops +//stored as color(vec4) -> offset(vec4) sequentially; +uniform vec4 color_stops[32]; //TODO: rewrite without branching to make ALUs happy void main() { - vec2 gradient_vec = vec2(gradient_end - gradient_start); - vec2 current_vec = vec2(raw_position.xy - gradient_start); + vec2 start = gradient_direction.xy; + vec2 end = gradient_direction.zw; + vec2 gradient_vec = vec2(end - start); + vec2 current_vec = vec2(raw_position.xy - start); vec2 unit = normalize(gradient_vec); float coord_offset = dot(unit, current_vec) / length(gradient_vec); - for (uint i = 0; i < color_stops_size - 1; i++) { - float stop_offset = color_stop_offsets[i]; - float next_stop_offset = color_stop_offsets[i + 1]; + for (uint i = 0; i < color_stops_size - 2; i += 2) { + vec4 color = color_stops[i]; + float offset = color_stops[i+1].x; + + vec4 next_color = color_stops[i+2]; + float next_offset = color_stops[i+3].x; - if (stop_offset <= coord_offset && coord_offset <= next_stop_offset) { - fragColor = mix(color_stop_colors[i], color_stop_colors[i+1], smoothstep( - stop_offset, - next_stop_offset, + if (offset <= coord_offset && coord_offset <= next_offset) { + fragColor = mix(color, next_color, smoothstep( + offset, + next_offset, coord_offset )); - } else if (coord_offset < color_stop_offsets[0]) { - fragColor = color_stop_colors[0]; - } else if (coord_offset > color_stop_offsets[color_stops_size - 1]) { - fragColor = color_stop_colors[color_stops_size - 1]; + } else if (coord_offset < color_stops[1].x) { + fragColor = color_stops[0]; + } else if (coord_offset > color_stops[color_stops_size - 1].x) { + fragColor = color_stops[color_stops_size - 2]; } } } \ No newline at end of file -- cgit From cb7c4676543cd508dfae8d4dcbd9cc8b61b1a94e Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 6 Oct 2022 07:28:05 -0700 Subject: Fixed lint issues & cleaned up some documentation. --- glow/src/shader/common/gradient.frag | 2 +- glow/src/shader/common/triangle.frag | 2 +- glow/src/shader/common/triangle.vert | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 89d2d398..ade9c4a1 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -47,4 +47,4 @@ void main() { fragColor = color_stops[color_stops_size - 2]; } } -} \ No newline at end of file +} diff --git a/glow/src/shader/common/triangle.frag b/glow/src/shader/common/triangle.frag index 0ee65239..ead40fe5 100644 --- a/glow/src/shader/common/triangle.frag +++ b/glow/src/shader/common/triangle.frag @@ -15,4 +15,4 @@ uniform vec4 color; void main() { fragColor = color; -} \ No newline at end of file +} diff --git a/glow/src/shader/common/triangle.vert b/glow/src/shader/common/triangle.vert index 09a4e324..fe505997 100644 --- a/glow/src/shader/common/triangle.vert +++ b/glow/src/shader/common/triangle.vert @@ -6,4 +6,4 @@ out vec2 raw_position; void main() { gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); raw_position = i_Position; -} \ No newline at end of file +} -- cgit From 12a87c54eb68b992676060c80e518ffb29445cfc Mon Sep 17 00:00:00 2001 From: shan Date: Fri, 7 Oct 2022 11:41:50 -0700 Subject: Added support for relative positioning of gradient fills. Addressed some PR feedback. --- glow/src/shader/common/gradient.frag | 3 +++ 1 file changed, 3 insertions(+) (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index ade9c4a1..3c701af7 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -45,6 +45,9 @@ void main() { fragColor = color_stops[0]; } else if (coord_offset > color_stops[color_stops_size - 1].x) { fragColor = color_stops[color_stops_size - 2]; + } else { + //This use case can happen if a gradient's start & end position are the same + fragColor = vec4(0.0, 0.0, 0.0, 0.0); } } } -- cgit From 87371ce93411ba900c83cd8230a5814b59092c4b Mon Sep 17 00:00:00 2001 From: shan Date: Fri, 7 Oct 2022 13:06:06 -0700 Subject: Fixed an edge case where when gradient start/end are identical the GL fragment shader was not choosing the appropriate color. --- glow/src/shader/common/gradient.frag | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 3c701af7..82c7e251 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -27,27 +27,33 @@ void main() { vec2 current_vec = vec2(raw_position.xy - start); vec2 unit = normalize(gradient_vec); float coord_offset = dot(unit, current_vec) / length(gradient_vec); + //if a gradient has a start/end stop that is identical, the mesh will have a transparent fill + fragColor = vec4(0.0, 0.0, 0.0, 0.0); - for (uint i = 0; i < color_stops_size - 2; i += 2) { - vec4 color = color_stops[i]; - float offset = color_stops[i+1].x; + float min_offset = color_stops[1].x; + float max_offset = color_stops[color_stops_size - 1].x; - vec4 next_color = color_stops[i+2]; + for (uint i = 0; i < color_stops_size - 2; i += 2) { + float curr_offset = color_stops[i+1].x; float next_offset = color_stops[i+3].x; - if (offset <= coord_offset && coord_offset <= next_offset) { - fragColor = mix(color, next_color, smoothstep( - offset, + if (coord_offset <= min_offset) { + //current coordinate is before the first defined offset, set it to the start color + fragColor = color_stops[0]; + } + + if (curr_offset <= coord_offset && coord_offset <= next_offset) { + //current fragment is between the current offset processing & the next one, interpolate colors + fragColor = mix(color_stops[i], color_stops[i+2], smoothstep( + curr_offset, next_offset, coord_offset )); - } else if (coord_offset < color_stops[1].x) { - fragColor = color_stops[0]; - } else if (coord_offset > color_stops[color_stops_size - 1].x) { + } + + if (coord_offset >= max_offset) { + //current coordinate is before the last defined offset, set it to the last color fragColor = color_stops[color_stops_size - 2]; - } else { - //This use case can happen if a gradient's start & end position are the same - fragColor = vec4(0.0, 0.0, 0.0, 0.0); } } } -- cgit From bb8d46a3fdf925b4b2fa9e7db76e48caf020b212 Mon Sep 17 00:00:00 2001 From: bungoboingo Date: Mon, 10 Oct 2022 20:55:43 -0700 Subject: Fixed fragment shader compatibility issues with GLES 3.0+ --- glow/src/shader/common/gradient.frag | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'glow/src/shader') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 82c7e251..42d0201f 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -1,14 +1,14 @@ #ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif + #ifdef GL_FRAGMENT_PRECISION_HIGH + precision highp float; + #else + precision mediump float; + #endif #endif #ifdef HIGHER_THAN_300 -layout (location = 0) out vec4 fragColor; -#define gl_FragColor fragColor + layout (location = 0) out vec4 fragColor; + #define gl_FragColor fragColor #endif in vec2 raw_position; @@ -31,11 +31,11 @@ void main() { fragColor = vec4(0.0, 0.0, 0.0, 0.0); float min_offset = color_stops[1].x; - float max_offset = color_stops[color_stops_size - 1].x; + float max_offset = color_stops[color_stops_size - 1u].x; - for (uint i = 0; i < color_stops_size - 2; i += 2) { - float curr_offset = color_stops[i+1].x; - float next_offset = color_stops[i+3].x; + for (uint i = 0u; i < color_stops_size - 2u; i += 2u) { + float curr_offset = color_stops[i+1u].x; + float next_offset = color_stops[i+3u].x; if (coord_offset <= min_offset) { //current coordinate is before the first defined offset, set it to the start color @@ -44,7 +44,7 @@ void main() { if (curr_offset <= coord_offset && coord_offset <= next_offset) { //current fragment is between the current offset processing & the next one, interpolate colors - fragColor = mix(color_stops[i], color_stops[i+2], smoothstep( + fragColor = mix(color_stops[i], color_stops[i+2u], smoothstep( curr_offset, next_offset, coord_offset @@ -53,7 +53,7 @@ void main() { if (coord_offset >= max_offset) { //current coordinate is before the last defined offset, set it to the last color - fragColor = color_stops[color_stops_size - 2]; + fragColor = color_stops[color_stops_size - 2u]; } } } -- cgit