Shader use for novices (e.g. myself)

223 views
Skip to first unread message

Erik Olson

unread,
Jul 18, 2016, 1:02:41 PM7/18/16
to pyglet-users
Hello! 

I am currently using pyglet for neuroscience research and have encountered an issue.  The program I currently have draws simple black primitives (triangle fans, etc.) to a blank white screen.  What I would like to do now is to be able to draw some of the primitives which represent a background, apply a gaussian blur using a shader, then draw the remaining objects on top, unblurred.  I have found extensive examples of shader classes to use in pyglet, along with resources stating how to write shaders in GLSL.  However, I have found practically nothing explaining how to use existing shaders to actually do things.  Currently I am working with Tristam McDonald's shader class, but I have no idea how I would actually get such shaders to apply to what appears on the screen. 

What should the code actually look like?  Are there any good resources or examples (which I seem to be completely unable to find)?  It seems like anywhere discussing how to use shaders glosses over this part, which makes me wonder if it's really obvious and I'm just an idiot.

Benjamin Moran

unread,
Jul 20, 2016, 4:57:32 AM7/20/16
to pyglet-users
Hi Erik,

I think the issue with shaders on pyglet at the moment is that you need some ctypes knowlege in order to make use of the OpenGL bindings. There aren't currently any built-in abstractions that make things easier.

However, Gabriel Dube has recently released a new shader library for pyglet: https://github.com/gabdube/pyshaders
That may do what you want. Have a look, and post back.

-Ben

Erik Olson

unread,
Jul 20, 2016, 4:14:31 PM7/20/16
to pyglet-users
Thanks for the suggestion!  I'm currently looking it over.  I tried inserting the strings for an example vertex and fragment shader I found, but I haven't been able to get pyshaders to work.  It keeps giving the following error:

Traceback (most recent call last):
  File "C:\Users\Erik\Documents\Programming\workspace\drawingLessons\src\draw.py", line 12, in <module>
    import pyshaders
  File "C:\Users\Erik\Anaconda2\lib\site-packages\pyshaders.py", line 167
    c_type, bcount, setter, *mat_size = UNIFORMS_DATA[type]
                                      ^
SyntaxError: invalid syntax
Not really sure what's going on there.  As far as I can tell the error seems to be an issue with pyshaders itself.

Benjamin Moran

unread,
Jul 21, 2016, 9:43:28 PM7/21/16
to pyglet-users
I'm not very familiar with the library yet, but from what I can see it requires activating some extensions for higher level GLSL support. If you can share a copy of the code you're trying to run, I can give it a try here. You might also consider just openening up a ticket on the project page if it turns out to be a bug.

Erik Olson

unread,
Jul 22, 2016, 12:13:43 PM7/22/16
to pyglet-users
As best I can tell, the error occurs purely from trying to import pyshaders.  I tried running solely "import pyshaders" with no other code, and it still gave the same error.  It appears to be taking issue with:


  File "C:\Users\Erik\Anaconda2\lib\site-packages\pyshaders.py", line 167
    c_type, bcount, setter, *mat_size = UNIFORMS_DATA[type]
and in particular once it reaches the asterisk (which makes it a rather annoying error to try to search for on google).  I might indeed report this as a bug, if looking into those extensions doesn't yield anything.

Erik Olson

unread,
Jul 22, 2016, 1:00:33 PM7/22/16
to pyglet-users
Actually, it probably would have helped if I were using the correct version of python.  Oops.  I was still on 2.7 due to working with some outdated libraries which I had long since abandoned, and just hadn't thought to switch back.  It imports just fine now.

Erik Olson

unread,
Jul 22, 2016, 1:51:57 PM7/22/16
to pyglet-users
The code I am currently trying to run is this, with the shader functions being examples I found on the internet:
gauss = pyshaders.from_string('''attribute vec4 a_position;
attribute vec2 a_texCoord;
 
varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
 
void main()
{
    gl_Position = a_position;
    v_texCoord = a_texCoord;
    v_blurTexCoords[ 0] = v_texCoord + vec2(-0.028, 0.0);
    v_blurTexCoords[ 1] = v_texCoord + vec2(-0.024, 0.0);
    v_blurTexCoords[ 2] = v_texCoord + vec2(-0.020, 0.0);
    v_blurTexCoords[ 3] = v_texCoord + vec2(-0.016, 0.0);
    v_blurTexCoords[ 4] = v_texCoord + vec2(-0.012, 0.0);
    v_blurTexCoords[ 5] = v_texCoord + vec2(-0.008, 0.0);
    v_blurTexCoords[ 6] = v_texCoord + vec2(-0.004, 0.0);
    v_blurTexCoords[ 7] = v_texCoord + vec2( 0.004, 0.0);
    v_blurTexCoords[ 8] = v_texCoord + vec2( 0.008, 0.0);
    v_blurTexCoords[ 9] = v_texCoord + vec2( 0.012, 0.0);
    v_blurTexCoords[10] = v_texCoord + vec2( 0.016, 0.0);
    v_blurTexCoords[11] = v_texCoord + vec2( 0.020, 0.0);
    v_blurTexCoords[12] = v_texCoord + vec2( 0.024, 0.0);
    v_blurTexCoords[13] = v_texCoord + vec2( 0.028, 0.0);
}''','''precision mediump float;
 
uniform sampler2D s_texture;
 
varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
 
void main()
{
    gl_FragColor = vec4(0.0);
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 0])*0.0044299121055113265;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 1])*0.00895781211794;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 2])*0.0215963866053;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 3])*0.0443683338718;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 4])*0.0776744219933;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 5])*0.115876621105;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 6])*0.147308056121;
    gl_FragColor += texture2D(s_texture, v_texCoord         )*0.159576912161;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 7])*0.147308056121;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 8])*0.115876621105;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 9])*0.0776744219933;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[10])*0.0443683338718;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[11])*0.0215963866053;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[12])*0.00895781211794;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[13])*0.0044299121055113265;
}''')

which gives the error
  File "C:\Users\Erik\Documents\Programming\workspace\drawingLessons\src\draw.py", line 150, in <module>
    }''')
  File "C:\Users\Erik\Anaconda3\lib\site-packages\pyshaders.py", line 791, in from_string
    raise ShaderCompilationError(prog.logs)
pyshaders.ShaderCompilationError: Shaders Errors:

ERROR: Definition for "void main()" not found.
Not sure what exactly is wrong here.
Message has been deleted

gdub...@gmail.com

unread,
Jul 22, 2016, 10:30:52 PM7/22/16
to pyglet-users
Pyshader developer here. Try to add "#version 130" at the top. The shader you are trying is for an old version of opengl and glsl. Without this, the compiler will try to use the most recent version.

 I was able to compile it on my computer once the version was added.

Erik Olson

unread,
Aug 4, 2016, 2:45:45 PM8/4/16
to pyglet-users
Like so?
gauss = pyshaders.from_string('''#version 130

attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
void main()
{
    gl_Position = a_position;
    v_texCoord = a_texCoord;
    v_blurTexCoords[ 0] = v_texCoord + vec2(-0.028, 0.0);
    v_blurTexCoords[ 1] = v_texCoord + vec2(-0.024, 0.0);
    v_blurTexCoords[ 2] = v_texCoord + vec2(-0.020, 0.0);
    v_blurTexCoords[ 3] = v_texCoord + vec2(-0.016, 0.0);
    v_blurTexCoords[ 4] = v_texCoord + vec2(-0.012, 0.0);
    v_blurTexCoords[ 5] = v_texCoord + vec2(-0.008, 0.0);
    v_blurTexCoords[ 6] = v_texCoord + vec2(-0.004, 0.0);
    v_blurTexCoords[ 7] = v_texCoord + vec2( 0.004, 0.0);
    v_blurTexCoords[ 8] = v_texCoord + vec2( 0.008, 0.0);
    v_blurTexCoords[ 9] = v_texCoord + vec2( 0.012, 0.0);
    v_blurTexCoords[10] = v_texCoord + vec2( 0.016, 0.0);
    v_blurTexCoords[11] = v_texCoord + vec2( 0.020, 0.0);
    v_blurTexCoords[12] = v_texCoord + vec2( 0.024, 0.0);
    v_blurTexCoords[13] = v_texCoord + vec2( 0.028, 0.0);
}''','''#version 130

precision mediump float;
 
uniform sampler2D s_texture;
 
varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
void main()
{
    gl_FragColor = vec4(0.0);
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 0])*0.0044299121055113265;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 1])*0.00895781211794;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 2])*0.0215963866053;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 3])*0.0443683338718;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 4])*0.0776744219933;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 5])*0.115876621105;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 6])*0.147308056121;
    gl_FragColor += texture2D(s_texture, v_texCoord         )*0.159576912161;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 7])*0.147308056121;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 8])*0.115876621105;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[ 9])*0.0776744219933;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[10])*0.0443683338718;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[11])*0.0215963866053;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[12])*0.00895781211794;
    gl_FragColor += texture2D(s_texture, v_blurTexCoords[13])*0.0044299121055113265;
}''')

Tried the above, with a few variations.  No luck; the error message is the same.

Erik Olson

unread,
Aug 15, 2016, 5:24:27 PM8/15/16
to pyglet-users
Alright.  After working with Gabriel Dube a bit, he figured out what was keeping pyshaders from running on my computer (Thanks!).  Now that this works, I'm looking more again into the actual how of getting a decent shader setup working.  Most everything I can find regarding gaussian blurs recommends the use of a two-pass system, blurring the image first horizontally and then vertically.  This seems to necessitate the use of FBOs.  What support exists for using FBOs with pyglet?  I've been trying to get GLETools up and running, but I keep getting the following error when trying to import it:


Traceback (most recent call last):
  File "C:\Users\Erik\Documents\Programming\workspace\dsafsa\src\tdytd.py", line 7, in <module>
    import gletools
  File "C:\Users\Erik\Anaconda3\lib\site-packages\gletools-0.1.0-py3.5.egg\gletools\__init__.py", line 8, in <module>
  File "C:\Users\Erik\Anaconda3\lib\site-packages\gletools-0.1.0-py3.5.egg\gletools\framebuffer.py", line 12, in <module>
ImportError: cannot import name 'nested'

Any ideas?

Benjamin Moran

unread,
Aug 16, 2016, 12:44:07 AM8/16/16
to pyglet-users
Hi Erik,

It looks like gletools hasn't been updated in a long time, and probably doesn't work anymore with the recent pyglet versions. Pyglet basically just lets you use raw OpenGL, so you can follow along with any standard tuturial if you wish, providing you're not scared of ctypes.

There is a nice writeup here by Leonhard Vogt that shows rendering to a texture at a low level with pyglet, that might be useful:
https://leovt.wordpress.com/2015/10/04/render-to-texture-with-python-3-and-pyglet/
You likely don't need most of that code thanks to Gabriel's shader library, but it might be worth a look to see what's going on at a lower level.

I haven't done any woth with gaussian blurs myself, so I'm not sure if this is useful. If you have some example code in a github/bitbucket repo somewhere, it might be easier for people to have a look to see if you're making any simple mistakes.

-Ben

Erik Olson

unread,
Aug 16, 2016, 12:30:49 PM8/16/16
to pyglet-users
Thanks for the pointers!  I have found basic tutorials for gaussian blurs using opengl, but in other languages, so I've just been figuring out how to replicate the same ideas in python.  I haven't written any code yet, aside from what exists for my actual pyglet program itself.  Once I actually have something to show I'll look into setting up a repository.
Reply all
Reply to author
Forward
0 new messages