{"id":15168494,"url":"https://github.com/unknown6656-megacorp/unknown6656.cvglpixelshader","last_synced_at":"2025-07-11T17:34:11.641Z","repository":{"id":133170390,"uuid":"535575838","full_name":"Unknown6656-Megacorp/Unknown6656.CVGLPixelShader","owner":"Unknown6656-Megacorp","description":"A small package wich enables the modification of OpenCV or NumPy images using OpenGL pixel shaders written in GLSL.","archived":false,"fork":false,"pushed_at":"2022-11-06T09:30:41.000Z","size":182,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-18T21:08:26.929Z","etag":null,"topics":["cv2","glsl","glsl-shaders","image","image-processing","opencv","opencv-python","opengl","pixel-shader","python","shaders"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/Unknown6656.CVGLPixelShader/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Unknown6656-Megacorp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["unknown6656"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2022-09-12T08:31:50.000Z","updated_at":"2024-08-01T00:42:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"56dd44d7-144d-4f83-b718-590585dba983","html_url":"https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unknown6656-Megacorp%2FUnknown6656.CVGLPixelShader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unknown6656-Megacorp%2FUnknown6656.CVGLPixelShader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unknown6656-Megacorp%2FUnknown6656.CVGLPixelShader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unknown6656-Megacorp%2FUnknown6656.CVGLPixelShader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Unknown6656-Megacorp","download_url":"https://codeload.github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unknown6656-Megacorp%2FUnknown6656.CVGLPixelShader/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264862786,"owners_count":23675045,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cv2","glsl","glsl-shaders","image","image-processing","opencv","opencv-python","opengl","pixel-shader","python","shaders"],"created_at":"2024-09-27T06:04:29.328Z","updated_at":"2025-07-11T17:34:11.635Z","avatar_url":"https://github.com/Unknown6656-Megacorp.png","language":"Python","funding_links":["https://github.com/sponsors/unknown6656"],"categories":[],"sub_categories":[],"readme":"[![](https://img.shields.io/github/issues/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader)](https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/issues)\n[![](https://img.shields.io/github/forks/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader)](https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/network)\n[![](https://img.shields.io/github/stars/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader)](https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader)\n[![CodeFactor](https://www.codefactor.io/repository/github/unknown6656-megacorp/unknown6656.cvglpixelshader/badge)](https://www.codefactor.io/repository/github/unknown6656-megacorp/unknown6656.cvglpixelshader)\n[![](https://img.shields.io/github/downloads/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/total?label=GitHub%20downloads)](https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/releases)\n[![](https://img.shields.io/pypi/dm/Unknown6656.CVGLPixelShader?label=PyPI%20downloads)](https://pypi.org/project/Unknown6656.CVGLPixelShader/)\n\n# Unknown6656.CVGLPixelShader\n\nThis is a small package wich enables the modification of OpenCV or NumPy images using OpenGL pixel shaders written in GLSL. Pixel shaders are shader programs which are executed in parallel on each pixel of a given image or texture _(Note: As pixel shaders are implemented as fragement shaders in the context of this library, they are technically not executed on every pixel but rather on every fragment)_.\n\nYou can learn more about GLSL, as well as pixel and fragment shaders here:\n\n- https://en.wikipedia.org/wiki/OpenGL_Shading_Language\n- https://en.wikipedia.org/wiki/Shader\n- https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language\n- https://www.khronos.org/opengl/wiki/Fragment_Shader\n\n\n## Download / Installation\n\n1. Install the package using `pip install Unknown6656.CVGLPixelShader` or download it from [https://pypi.org/project/Unknown6656.CVGLPixelShader/](https://pypi.org/project/Unknown6656.CVGLPixelShader/)\n2. Insert the following import statements into your Python code:\n\n   ```python\n   import cv2\n   from Unknown6656.CVGL import *\n   ```\n\n   If you run into any issues regarding package dependencies, try installing all dependencies as listed in [requirements.txt](requirements.txt) using the command `pip install -r requirements.txt`.\n\n\n## Basic Example\n\nCreate a new shader by invoking the constructor `PixelShader(...)` as follows:\n\n```python\nmy_shader = PixelShader('''\n    vec4 color = texture(image, coords);\n\n    out_color = vec4(1 - color.xyz, 1);\n''')\n```\n\nThe code segment passed to the constructor is GLSL code and will be inserted into the fragment shader of the program. Have a look at the [official GLSL documentation pages](https://www.khronos.org/opengles/sdk/docs/manglsl/docbook4/) from Khronos for more information on how to use the shader language.\n\nThe shader can then be used as follows:\n\n```python\nimage_in = cv2.imread('.../path/to/image.png')   # read the input image from file\nimage_out = my_shader(image_in)                  # process the image using the pixel shader\ncv2.imwrite('.../path/to/output.png', image_out) # save the processed image\n\nmy_shader.close()                                # close the shader and free all\n                                                 # underlying resources\n```\n\nYou may want to replace a call to `PixelShader.close(self)` with the usage of `with`-statement blocks:\n\n```python\nwith PixelShader('''\n    vec4 color = texture(image, coords);\n\n    out_color = vec4(1 - color.xyz, 1);\n''') as my_shader:\n    image_in = cv2.imread('.../path/to/image.png')\n    image_out = my_shader(image_in)\n    cv2.imwrite('.../path/to/output.png', image_out)\n```\n\nAll Shaders created with `PixelShader(...)` expose the following variables to GLSL:\n\n- **`int32 width`**: The image width in pixel.\n- **`int32 height`**: The image height in pixels.\n- **`vec2 coords`**: The current pixel coordinates, normalized to [0..1]x[0..1].\n- **`sampler2D image`**: The image as a 2D texture sampler with four color channels (RGBA).\n- **`vec4 out_color`**: The output color at this position as an RGBA-vector with values ranging from 0 to 1 for each color channel. If this variable is unused, the input color will be copied to the output.\n\n\n## Using User-Defined Variables\n\nYou may sometimes want to pass variables to the shader. This can be performed as follows:\n\n1. **Create a new shader variable:**\n\n   ```python\n   my_variable = ShaderVariable('time', ShaderVariableType.FLOAT)\n   ```\n\n   This code creates a new variable with the name `'time'` and the type `float` (32-bit IEE754 floating-point value). Take a look at the enum `ShaderVariableType` for all supported shader variable types.\n\n2. **Create a new shader and pass all variables to the shader:**\n\n   ```python\n   my_shader = PixelShader('''\n       out_color = texture(image, coords);\n       out_color.x += sin(time);\n   ''', variables = [my_variable])\n   ```\n\n   Note that the GLSL code makes usage of the variable `time` in the line `out_color.x += sin(time);`.\n\n3. **Assign a value to the variable:**\n\n   ```python\n   my_shader[my_variable] = time.time()\n   ```\n\n4. **Use the shader:**\n\n   ```python\n   image_out = my_shader(image_in)\n   ```\n\n#### Complete example\n\n```python\nimage = cv2.imread('...../image.png')\nv_time = ShaderVariable('time', ShaderVariableType.FLOAT)\ntime = 0\n\nwith PixelShader('''\n    out_color = texture(image, coords);\n    out_color.x += sin(time * 2) * .5;\n''', '', [v_time]) as shader:\n    while True:\n        time += .01\n        shader[v_time] = time\n        image = shader(image)\n\n        cv2.imshow('image', image)\n        if cv2.waitKey(1) \u0026 0xff == ord('q'):\n            break\n```\n\n## Pre-defined Shaders\n\nFeel free to make usage of some pre-defined shaders which come with this library. These shaders include:\n\n- Vignetting\n- Hue\n- Saturation\n- Grayscale\n- Invert\n- Brightness\n- Contrast\n- Sepia\n- Bloom\n- Blur (Linear, Radial, Gaussian)\n- RGB Split (Linear, Radial)\n- Kernel Convolution (Single- and Double-Pass)\n- Embossing\n- Edge Detections (Sobel, Sobel-Feldman, Prewitt, Roberts, ...)\n\nTo use any of these shaders, add the following `import`-statement to your script:\n```python\nfrom Unknown6656.CVGL.Shaders import *\n```\nYou may then use the shaders as follows:\n```python\nimage = cv2.imread('/path/to/image.png')\n\nwith Blur(radius = 20) as blur: # \"Blur\" is a pre-defined shader\n    processed = blur(image)\n\ncv2.imshow('input', image)\ncv2.imshow('output', processed)\ncv2.waitKey(0)\n```\nThe pre-defined shaders allow variables to be set after initialization as well:\n```python\nimage = cv2.imread('/path/to/image.png')\n\nwith Blur(radius = 10) as blur:\n    processed_1 = blur(image)   # process the image with radius = 10\n    blur['radius'] = 20         # change the radius to 20\n    processed_2 = blur(image)   # re-process image with the new blur radius\n```\n\n## Performance\n\nLet me be clear. The performance of this library is dogshite. Pixel shaders usually have a great performace, however they are designed to be used inside of render pipelines of games -- not headless in some random botched-up code. Hoever, I tried to compare the performance of this library with equivalent \"traditional\" code (i.e. using mainly OpenCV and NumPy).\n\nThe following graph compares the runtime (in seconds) of executing x-times the \"vignetting\" effect on a bitmap using this library and a \"traditional\" method:\n\n![](https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/raw/main/performance-comparison-1.png)\n\nThe following graph compares the mean runtime (in seconds) averaged over 100 iterations of the following effects using this library and \"traditional\" implementations:\n\n![](https://github.com/Unknown6656-Megacorp/Unknown6656.CVGLPixelShader/raw/main/performance-comparison-2.png)\n\nBoth graphs have been created on a machine with the following hardware specifications:\n\n```text\nLENOVO Legion 5\nIntel i7-11800H @ 2.3Ghz, 8 Cores, 16 Threads\nNVIDIA RTX 3060 M (6GB VRAM)\n16GB RAM\n```\n\nOne can clearly see that effects implemented with this library have a baseline runtime of 5ms. However, this runtime does not increase significantly when implementing more complex effects using GLSL (in comparison to \"traditional\" implementations).\n\n\n## Notes\n\nPlease keep the following in mind:\n\n1. This library is still in beta. Some bugs may occur.\n2. You may declare multiple shaders and use them independently from each other. Please keep in mind that the image processing is still performed synchroniously in the background, meaning that two shaders cannot process an image at exactly the same time (at least on a per-process basis).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funknown6656-megacorp%2Funknown6656.cvglpixelshader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funknown6656-megacorp%2Funknown6656.cvglpixelshader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funknown6656-megacorp%2Funknown6656.cvglpixelshader/lists"}