diff options
author | ozwaldorf <[email protected]> | 2024-01-03 12:38:44 -0500 |
---|---|---|
committer | GitHub <[email protected]> | 2024-01-03 12:38:44 -0500 |
commit | 04b657b58cf54ac611f73723ec44f51feba16b15 (patch) | |
tree | e8c310f8957ded3304503dc1d908b8a233bbae20 /sway/desktop | |
parent | 1c5c60d9280eb0b13d9884366bdeaf3748b04308 (diff) |
feat: blur tweaks (#258)
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/fx_renderer/fx_renderer.c | 61 | ||||
-rw-r--r-- | sway/desktop/fx_renderer/shaders/blur_effects.frag | 54 | ||||
-rw-r--r-- | sway/desktop/fx_renderer/shaders/meson.build | 1 | ||||
-rw-r--r-- | sway/desktop/render.c | 17 |
4 files changed, 133 insertions, 0 deletions
diff --git a/sway/desktop/fx_renderer/fx_renderer.c b/sway/desktop/fx_renderer/fx_renderer.c index 7196bb0e..089e1693 100644 --- a/sway/desktop/fx_renderer/fx_renderer.c +++ b/sway/desktop/fx_renderer/fx_renderer.c @@ -23,6 +23,7 @@ // shaders #include "blur1_frag_src.h" #include "blur2_frag_src.h" +#include "blur_effects_frag_src.h" #include "box_shadow_frag_src.h" #include "common_vert_src.h" #include "corner_frag_src.h" @@ -107,6 +108,25 @@ static bool link_blur_program(struct blur_shader *shader, const char *shader_pro return true; } +static bool link_blur_effects_program(struct effects_shader *shader, const char *shader_program) { + GLuint prog; + shader->program = prog = link_program(shader_program); + if (!shader->program) { + return false; + } + shader->proj = glGetUniformLocation(prog, "proj"); + shader->tex = glGetUniformLocation(prog, "tex"); + shader->pos_attrib = glGetAttribLocation(prog, "pos"); + shader->tex_attrib = glGetAttribLocation(prog, "texcoord"); + shader->noise = glGetUniformLocation(prog, "noise"); + shader->brightness = glGetUniformLocation(prog, "brightness"); + shader->contrast = glGetUniformLocation(prog, "contrast"); + shader->saturation = glGetUniformLocation(prog, "saturation"); + + return true; + +} + static bool link_box_shadow_program(struct box_shadow_shader *shader) { GLuint prog; shader->program = prog = link_program(box_shadow_frag_src); @@ -305,6 +325,10 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl, struct wlr_output *w if (!link_blur_program(&renderer->shaders.blur2, blur2_frag_src)) { goto error; } + // effects shader + if (!link_blur_effects_program(&renderer->shaders.blur_effects, blur_effects_frag_src)) { + goto error; + } // box shadow shader if (!link_box_shadow_program(&renderer->shaders.box_shadow)) { goto error; @@ -365,6 +389,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl, struct wlr_output *w error: glDeleteProgram(renderer->shaders.blur1.program); glDeleteProgram(renderer->shaders.blur2.program); + glDeleteProgram(renderer->shaders.blur_effects.program); glDeleteProgram(renderer->shaders.box_shadow.program); glDeleteProgram(renderer->shaders.corner.program); glDeleteProgram(renderer->shaders.quad.program); @@ -899,3 +924,39 @@ void fx_render_blur(struct fx_renderer *renderer, const float matrix[static 9], glDisableVertexAttribArray(shader->tex_attrib); } + +void fx_render_blur_effects(struct fx_renderer *renderer, const float matrix[static 9], + struct fx_framebuffer **buffer, float blur_noise, float blur_brightness, + float blur_contrast, float blur_saturation) { + struct effects_shader shader = renderer->shaders.blur_effects; + + glEnable(GL_BLEND); + glActiveTexture(GL_TEXTURE0); + glBindTexture((*buffer)->texture.target, (*buffer)->texture.id); + glTexParameteri((*buffer)->texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glUseProgram(shader.program); + + // OpenGL ES 2 requires the glUniformMatrix3fv transpose parameter to be set + // to GL_FALSE + float gl_matrix[9]; + wlr_matrix_transpose(gl_matrix, matrix); + glUniformMatrix3fv(shader.proj, 1, GL_FALSE, gl_matrix); + + glUniform1i(shader.tex, 0); + glUniform1f(shader.noise, blur_noise); + glUniform1f(shader.brightness, blur_brightness); + glUniform1f(shader.contrast, blur_contrast); + glUniform1f(shader.saturation, blur_saturation); + + glVertexAttribPointer(shader.pos_attrib, 2, GL_FLOAT, GL_FALSE, 0, verts); + glVertexAttribPointer(shader.tex_attrib, 2, GL_FLOAT, GL_FALSE, 0, verts); + + glEnableVertexAttribArray(shader.pos_attrib); + glEnableVertexAttribArray(shader.tex_attrib); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(shader.pos_attrib); + glDisableVertexAttribArray(shader.tex_attrib); +} diff --git a/sway/desktop/fx_renderer/shaders/blur_effects.frag b/sway/desktop/fx_renderer/shaders/blur_effects.frag new file mode 100644 index 00000000..2fc16c15 --- /dev/null +++ b/sway/desktop/fx_renderer/shaders/blur_effects.frag @@ -0,0 +1,54 @@ +precision mediump float; +varying vec2 v_texcoord; +uniform sampler2D tex; + +uniform float noise; +uniform float brightness; +uniform float contrast; +uniform float saturation; + +mat4 brightnessMatrix() { + float b = brightness - 1.0; + return mat4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + b, b, b, 1); +} + +mat4 contrastMatrix() { + float t = (1.0 - contrast) / 2.0; + return mat4(contrast, 0, 0, 0, + 0, contrast, 0, 0, + 0, 0, contrast, 0, + t, t, t, 1); +} + +mat4 saturationMatrix() { + vec3 luminance = vec3(0.3086, 0.6094, 0.0820); + float oneMinusSat = 1.0 - saturation; + vec3 red = vec3(luminance.x * oneMinusSat); + red+= vec3(saturation, 0, 0); + vec3 green = vec3(luminance.y * oneMinusSat); + green += vec3(0, saturation, 0); + vec3 blue = vec3(luminance.z * oneMinusSat); + blue += vec3(0, 0, saturation); + return mat4(red, 0, + green, 0, + blue, 0, + 0, 0, 0, 1); +} + +// Fast generative noise function +float hash(vec2 p) { + return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); +} + +void main() { + vec4 color = texture2D(tex, v_texcoord); + color *= brightnessMatrix() * contrastMatrix() * saturationMatrix(); + float noiseHash = hash(v_texcoord); + float noiseAmount = (mod(noiseHash, 1.0) - 0.5); + color.rgb += noiseAmount * noise; + + gl_FragColor = color; +} diff --git a/sway/desktop/fx_renderer/shaders/meson.build b/sway/desktop/fx_renderer/shaders/meson.build index 7a27de80..19f76dc2 100644 --- a/sway/desktop/fx_renderer/shaders/meson.build +++ b/sway/desktop/fx_renderer/shaders/meson.build @@ -3,6 +3,7 @@ embed = find_program('./embed.sh', native: true) shaders = [ 'blur1.frag', 'blur2.frag', + 'blur_effects.frag', 'box_shadow.frag', 'common.vert', 'corner.frag', diff --git a/sway/desktop/render.c b/sway/desktop/render.c index c054b3a5..391533c5 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -258,6 +258,23 @@ struct fx_framebuffer *get_main_buffer_blur(struct fx_renderer *renderer, struct &renderer->shaders.blur2, box, blur_radius); } + float blur_noise = config->blur_params.noise; + float blur_brightness = config->blur_params.brightness; + float blur_contrast = config->blur_params.contrast; + float blur_saturation = config->blur_params.saturation; + + if (pixman_region32_not_empty(&damage)) { + int nrects; + pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); + for (int i = 0; i < nrects; ++i) { + const pixman_box32_t box = rects[i]; + struct wlr_box new_box = { box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1 }; + fx_renderer_scissor(&new_box); + fx_render_blur_effects(renderer, gl_matrix, ¤t_buffer, blur_noise, + blur_brightness, blur_contrast, blur_saturation); + } + } + pixman_region32_fini(&tempDamage); pixman_region32_fini(&damage); |