Using a texture as a LUT

18 views
Skip to first unread message

Yves Surrel

unread,
Oct 2, 2018, 6:08:02 PM10/2/18
to Kivy users support
Hi 

I try to use a lookup table (LUT) in a shader. (I went to that because I discovered that on my android device, I could not use a regular buffer 

In the shader, I added the lines:

{
// uniform float[256]; 
uniform sampler2D lut;

void main() {
    float color = texture2D(lut, tex_coord0).r / 255.0;
    gl_FragColor = vec4(vec3(color), 1.0);
}

expecting to have a horizontal gray variation as the LUT size will be (1, 256), increasing from 0 to 255.

and in my widget code I put:

{
    def __init__(self, **kwargs):
        # Instead of using canvas, we will use a RenderContext,
        # and change the default shader used.
        self.canvas = RenderContext(use_parent_projection=True,
                                    use_parent_modelview=True,
                                    use_parent_frag_modelview=True)
                                    
        # call the constructor of parent
        # if they are any graphics object, they will be added on our new canvas
        super(ShaderWidget, self).__init__(**kwargs)

        # Linear LUT
        self.lut = range(256)
        
        self.tex = Texture.create(size=(1,256), colorfmt='luminance')
        BindTexture(texture=self.tex, index=1)
        self.tex.add_reload_observer(self.populate_texture)
        self.populate_texture(self.tex)
        self.canvas['lut'] = 1
        
    def populate_texture(self, texture):
        # data = b''.join(map(bytes,self.lut))
        data = struct.pack('h'*len(self.lut), *self.lut)
        texture.blit_buffer(data, size=(1,256), colorfmt='luminance')
        

}

My widget remains desperately black. What am I missing ? (Elsewhere in the code I set the shader, this has already been tested without the LUT and is working fine.)
It is not clear what the index in BindTexture should be. Could it be arbitrary (e.g. 4 in this example) ? I think that at least it should be the same as in the line self.canvas['lut'] = 

Thanks in advance.


Gabriel Pettier

unread,
Oct 4, 2018, 1:32:43 AM10/4/18
to kivy-...@googlegroups.com
I *think* the multitexture example might help you :)

https://github.com/kivy/kivy/blob/master/examples/canvas/multitexture.py

from a quick look, i think you need to put the BindTexture in a canvas
block.
>--
>You received this message because you are subscribed to the Google Groups "Kivy users support" group.
>To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
>To post to this group, send email to kivy-...@googlegroups.com.
>Visit this group at https://groups.google.com/group/kivy-users.
>To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/68738d53-a1f9-4d89-9680-d6d9443e8c66%40googlegroups.com.
>For more options, visit https://groups.google.com/d/optout.

Yves Surrel

unread,
Oct 4, 2018, 4:16:58 AM10/4/18
to Kivy users support
Hi tshirtman

Yes, you are perfectly right.

I indeed had solved my issue after comparing with multi texture.py, and yes, the BindTexture has to be put within a canvas block.

There were two other flaws: the string to use in struct.pack() should be 'B' (unsigned byte) and not 'h', and in the shader the color returned by texture2D does not need be divided by 255, as it is already normalized to 1.0

Anyway, thanks for your time.
Reply all
Reply to author
Forward
0 new messages