Porting glsl shader to blender?

Ok so I found a shader at shadertoy… and I need some help porting it… more over I would like to learn how to port it over as I have never really played with glsl shaders at all… here is the shader

I believe there is already a sobel shader integrated in blender 2d filters. You just need to find(or ask for) its script and edit it,until it start looking like that on the video you’ve shown.

Its not Really the shader that I need… I just need to know who to port it. For future shaders.

There are two (ok, three) types of shaders in blender game engine:

  1. Vertex shaders. These are attached to an object, and operate on a per-vertex level. Unless you want to distort vertex geometry to display it (eg for dynamic heightmaps, water effects, geometry slicing etc), this shader generally doesn’t do much
  2. Fragment shaders: THis shader is attached to the object, and operates per pixel of screen-space that the object occupies. It is used to do complex operations on an object surface. Materials made with blenders node editor are fragment shaders behind the scenes.
  3. 2d filters. A 2d filter operates on the entire scene, and is used to do post processing: bloom, blur, and so on.

Your example shader looks to be a 2d filter, and will operate on every object visible

As to how you port them, generally you throw it in, and see what errors the compiler shows.
In this case, variables like “iGlobalTime” will come up as being undefined, and will have to be created as a uniform and have the value passed in to the shader. Other variables will have to be traded for things like:


uniform sampler2D bgl_RenderedTexture;
uniform sampler2D bgl_DepthTexture;

which give you access to the image and depth.

Ah ok… so ill work on it and see if i can get it to work… there is something that says iResolution and it supposed to give the screen’s resolution in a vec3… is there a way that I can send the resolution to the shader in blender?

EDIT:
Ok so i found bgl_RenderedTextureWidth and bgl_RenderedTextureHeight… is there a way to use this in place of the iResolution in the following code?


uniform sampler2D bgl_RenderedTexture;
uniform float bgl_RenderedTextureWidth;
uniform float bgl_RenderedTextureHeight;
uniform float timer;






float d = sin(timer * 5.0)*0.5 + 1.5; // kernel offset

float lookup(vec2 p, float dx, float dy)
{
    vec2 uv = (p.xy + vec2(dx * d, dy * d)) / iResolution.xy;
    vec4 c = texture2D(bgl_RenderedTexture, uv.xy);
    
    // return as luma
    return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = fragCoord.xy;
    
    // simple sobel edge detection
    float gx = 0.0;
    gx += -1.0 * lookup(p, -1.0, -1.0);
    gx += -2.0 * lookup(p, -1.0,  0.0);
    gx += -1.0 * lookup(p, -1.0,  1.0);
    gx +=  1.0 * lookup(p,  1.0, -1.0);
    gx +=  2.0 * lookup(p,  1.0,  0.0);
    gx +=  1.0 * lookup(p,  1.0,  1.0);
    
    float gy = 0.0;
    gy += -1.0 * lookup(p, -1.0, -1.0);
    gy += -2.0 * lookup(p,  0.0, -1.0);
    gy += -1.0 * lookup(p,  1.0, -1.0);
    gy +=  1.0 * lookup(p, -1.0,  1.0);
    gy +=  2.0 * lookup(p,  0.0,  1.0);
    gy +=  1.0 * lookup(p,  1.0,  1.0);
    
    // hack: use g^2 to conceal noise in the video
    float g = gx*gx + gy*gy;
    float g2 = g * (sin(timer) / 2.0 + 0.5);
    
    vec4 col = texture2D(bgl_RenderedTexture, p / iResolution.xy);
    col += vec4(0.0, g, g2, 1.0);
    
    fragColor = col;
}

iResolution is a vector and bgl_RenderedTextureWidth and bgl_RenderedTextureHeight are floats so you easy can make it to a vector (vec2):

vec2 iResolution = vec2(bgl_RenderedTextureWidth, bgl_RenderedTextureHeight)

With “.xy” behind the vector you get the first two components of the vector
If your vector is not bigger than 2 the “.xy” is not necessary.

Maybe this his helpful (category: Swizzling):https://www.opengl.org/wiki/Data_Type_(GLSL)

I’ve tried with varied success to port stuff from there.
If you click the tab that says “shader inputs” you can get more info about the variables in the script.

I’m always reading that texcoord is out and we should be using fragcoord but that doesn’t seem to be the case with blender’s shaders.
Find another shader and try to match up the variables.

here’s a simple one:

uniform sampler2D bgl_RenderedTexture;
uniform float timer;
const float screen_x = 0.5;
const float screen_y = 0.3;

const float vignette_size = 0.4;
const float tolerance = 0.2;


void main(void)
{    
        
    vec4 vignette_color = vec4 (0.5,0.4,0.3,1.0);     
                    
    vec2 deltaTexCoord = vec2(screen_x,screen_y) - gl_TexCoord[0].st;
    vec2 powers = pow(deltaTexCoord,vec2(2.0)); 
    
    float radiusSqrd = pow(vignette_size,2.0);    
    float gradient = smoothstep(radiusSqrd-tolerance, radiusSqrd+tolerance, powers.x+powers.y*0.3);
    
    gl_FragColor = mix(texture2D(bgl_RenderedTexture, gl_TexCoord[0].st), vignette_color, gradient*0.4);
    
    gl_FragColor.a = 1.0;   

}

Here is the ported code:

uniform sampler2D bgl_RenderedTexture;

uniform float bgl_RenderedTextureWidth;
uniform float bgl_RenderedTextureHeight;
uniform float Timer; //you need an Timer property in the logic with the name after uniform float (you can change the name) 

float iGlobalTime = Timer;
vec2 iResolution = vec2(bgl_RenderedTextureWidth, bgl_RenderedTextureHeight);
vec2 fragCoord = vec2(gl_TexCoord[0].x * bgl_RenderedTextureWidth, gl_TexCoord[0].y * bgl_RenderedTextureHeight);


// only things changed in the code: iChannel0 to bgl_RenderedTexture and fragColor to gl_FragColor and made line 23 to void main()

float d = sin(iGlobalTime * 5.0)*0.5 + 1.5; // kernel offset

float lookup(vec2 p, float dx, float dy)
{
    vec2 uv = (p.xy + vec2(dx * d, dy * d)) / iResolution.xy;
    vec4 c = texture2D(bgl_RenderedTexture, uv.xy);
    
    // return as luma
    return 0.2126*c.r + 0.7152*c.g + 0.0722*c.b;
}

void main()
{
    vec2 p = fragCoord.xy;
    
    // simple sobel edge detection
    float gx = 0.0;
    gx += -1.0 * lookup(p, -1.0, -1.0);
    gx += -2.0 * lookup(p, -1.0,  0.0);
    gx += -1.0 * lookup(p, -1.0,  1.0);
    gx +=  1.0 * lookup(p,  1.0, -1.0);
    gx +=  2.0 * lookup(p,  1.0,  0.0);
    gx +=  1.0 * lookup(p,  1.0,  1.0);
    
    float gy = 0.0;
    gy += -1.0 * lookup(p, -1.0, -1.0);
    gy += -2.0 * lookup(p,  0.0, -1.0);
    gy += -1.0 * lookup(p,  1.0, -1.0);
    gy +=  1.0 * lookup(p, -1.0,  1.0);
    gy +=  2.0 * lookup(p,  0.0,  1.0);
    gy +=  1.0 * lookup(p,  1.0,  1.0);
    
    // hack: use g^2 to conceal noise in the video
    float g = gx*gx + gy*gy;
    float g2 = g * (sin(iGlobalTime) / 2.0 + 0.5);
    
    vec4 col = texture2D(bgl_RenderedTexture, p / iResolution.xy);
    col += vec4(0.0, g, g2, 1.0);
    
    gl_FragColor = col;
}