My Bloom Shader sucks.

95 views
Skip to first unread message

Thomas Chen

unread,
Nov 30, 2015, 6:10:53 PM11/30/15
to Kivy users support
I wrote(copied) a fragment shader to put into an EffectWidget. I wanted to emulate the look/feel of this ui:


More here.
So here's my BloomEffect widget code:
import kivy
kivy
.require('1.9.0') 
from kivy.uix.effectwidget import EffectBase 
from kivy.properties import (StringProperty, ObjectProperty, ListProperty, 
                             
NumericProperty, DictProperty)
 
effect_bloom_h 
= ''' 
float luminance(vec3 color) 

    return color.x*0.299 + color.y * 0.587 + color.z * 0.114; 


 
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords) 

    vec4 sum = vec4(0); 
    vec4 result = vec4(0); 
    vec4 temp = vec4(0); 
    int j; 
    int i; 
     
    float dt = (5.0 / 4.0) * 1.0 / resolution.x; 
    for( i= -4 ;i < 4; i++) 
    { 
        for (j = -3; j < 3; j++) 
        { 
            temp = texture2D(texture, tex_coords + vec2(j, i)*dt); 
            sum += temp * 0.25; 
        } 
    } 
    if (luminance(texture2D(texture, tex_coords).xyz) < 0.3) 
    { 
        result = sum*sum*0.012 + color*0.9; 
    } 
    else 
    { 
        if (luminance(texture2D(texture, tex_coords).xyz) < 0.5) 
        { 
            result = sum*sum*0.009 + color*0.9; 
        } 
        else 
        { 
            result = sum*sum*0.0075 + color*0.9; 
        } 
    } 
    return result; 

'''
 


class BloomEffect(EffectBase): 
    
#size = NumericProperty(4.0) 
    
'''The bloom radius in pixels. 
    size is a :class:`~kivy.properties.NumericProperty` and defaults to 
    4.0. 
    '''
 

    
def __init__(self, *args, **kwargs): 
        
super(BloomEffect, self).__init__(*args, **kwargs) 
        
self.do_glsl() 

    
def on_size(self, *args): 
        
self.do_glsl() 

    
def do_glsl(self):
        
self.glsl = effect_bloom_h


So this works, but it doesn't look so good. Can anyone recommend a better approach? I can mostly understand the fragment shader just by looking at the code, but real opengl programming is currently outside my area of expertise.

I've looked up how to write bloom shaders and most of the articles suggest that you use multiple passes: create a glow filter (only pixels that represent a glowing object), gaussian blur it with 2 passes (horizontal and vertical), then add it back to the original texture.

This seems to be problematic for EffectWidgets because they seem to only allow one pass. I can stack 2 blurs, but then I cant figure out how to pass the original image to the next step. So the way the bloom effect works in the code above is to calculate blur at a pixel by determining the color influence from neighboring pixels using a gaussian fall-off, then add that to the original color. However, this seems to create a lot of artifacts and weirdness in the final outcome. So is there any way to stack effects, then in a later effect get the original image along with shader image to combine them?

Alexander Taylor

unread,
Nov 30, 2015, 6:28:54 PM11/30/15
to Kivy users support
The problem here is essentially that what you're trying with the EffectWidget doesn't fit in its one-by-one shader application. You can instead handle things manually, constructing Fbos for what you want (the same way the EffectWidget does) but passing textures around differently so that shaders receive the ones you want them to. The EffectWidget source will be a good starting point for this, but you'll also need to experiment.

Thomas Chen

unread,
Nov 30, 2015, 11:54:08 PM11/30/15
to kivy-...@googlegroups.com
Thanks for the guidance! I'll give it a try.

-Thomas
--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/AVQOkDLBN2Q/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages