Skip to main content

Transforming python code to GLSL shaders.

Project description

shader-make

Drom project to make shader translator. shader-make currently only works with GLSL. It uses a decorator to transform itself into a GPU based function, here for OpenGL. You cannot currently reuse a shader function as a default function but we prepared the setup to do that. We haven't implemented every python feature that we don't think are usefull for the purpose of what we will be using it for, such as while loops that could be interesting.

Compiling a simple function to shader code

First you will need to import the decorator and the shader engine you want to use. We currently only support OpenGL with GLSL support. shader-make will then do type analysis on the variables to generate C code that you can compile to GLSL (you have to specify the type of your input for it to work). Here is a simple GLSL function that takes two coordinates a and b and creates a vec3 with (x, y, x + y) :

from shadermake.decorator import make_shader
from shadermake.engines.opengl import OpenGLEngine, vec3

@make_shader(OpenGLEngine, argument_types=[ float, float ])
def transform(x, y):
    return vec3(x, y, x + y)

And the resulting C code is the following when you do transform.c_code():

vec3 transform (float x, float y) {
        return vec3(x, y, x + y);
}

Linking multiple functions

We will admit you have a cool python function called magic that you would like to use in multiple shader functions. You can do that using the parameter bound_shaders. For this example we will use the cool function f(x) = x + 1 and add it to our transform function :

from shadermake.decorator import make_shader
from shadermake.engines.opengl import OpenGLEngine, vec3

@make_shader(OpenGLEngine, argument_types=[ float ])
def f(x):
    return x + 1

@make_shader(OpenGLEngine, argument_types=[ float, float ], bound_shaders=[ f ])
def transform(x, y):
    y = f(y)
    return vec3(x, y, x + y)
float f (float x) {
        return x + 1;
}
vec3 transform (float x, float y) {
        y = f(y);
        return vec3(x, y, x + y);
}

Inputs, outputs and uniforms

When you want to compile a shader, it can be needed to import existing inputs, setup outputs or use uniform variables shared between every vertex. For this you can use a ShaderOptions element and use addInput, addOutput and addUniform to append metadata. You can also generate the default vertex shader data or fragment shader data using the useVertex or useFragment functions. The following example generates a function with an uniform displacement :

from shadermake.decorator import make_shader
from shadermake.engines.opengl import OpenGLEngine, ShaderOptions, vec2, vec3, vec4

options = ShaderOptions() \
    .useVertex() \
    .addInput( vec4, "pos", 0 ) \
    .addUniform( vec4, "delta" )
@make_shader(OpenGLEngine, shader_options=options)
def shader():
    gl_Position = pos + delta
layout(location = 0) in vec4 pos;
uniform vec4 delta;

int shader () {
        gl_Position = pos + delta;
        return 0;
}

If statements

The usage of if statement is implemented by default but the usage of elif strongly increments the C final code size. Here is the example of the shader used in the testing and one of the following results (the one on the github actions architecture) :

@make_shader(OpenGLEngine)
def main():
    x = 0
    y = 1
    z = x + y
    if z > 0.5:
        y = 2
    elif z >= 1:
        y = 4
    else:
        y = 3
    u= 0
    if u + z > 0.2:
        a = u - z
    else: a = u + y
int main () {
    int x = 0;
    int y = 1;
    int z = x + y;
    if (z > 0.5) {
        y = 2;
    } else {
        if (z >= 1) {
            y = 4;
        } else {
            y = 3;
        }
    }
    int u = 0;
    if (u + z > 0.2) {
        int a = u - z;
    } else {
        int a = u + y;
    }
    return 0;
}

As you can see here, the a variable is only created in the if scope. This isn't the default behavior of python so you might have to create your variable and initialize it before the if statement with a placeholder value like 0 to avoid your data being destroyed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shadermake-0.0.5.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shadermake-0.0.5-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file shadermake-0.0.5.tar.gz.

File metadata

  • Download URL: shadermake-0.0.5.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.6

File hashes

Hashes for shadermake-0.0.5.tar.gz
Algorithm Hash digest
SHA256 04ca43cf94bf55ba879e5faa3b60b67ff1f4c1539adb2c809ca8d59c841d3e81
MD5 d607327d6f6329130f0bdca53853837c
BLAKE2b-256 97723b1bc7bae73c9455822c8f0ce486fe2da64d920793824f4cc6ca26882788

See more details on using hashes here.

File details

Details for the file shadermake-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: shadermake-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.6

File hashes

Hashes for shadermake-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 324a219c607c9fb7768ef890dbfbf6d423846fd61f33a449285034717cc9b22f
MD5 db938414aa87b24417e8403b3c25c5fc
BLAKE2b-256 ef124552edb4d231e2610bfbecad7781f6925ad5c835c6806e122eef29bd5a7f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page