Xor Shaders
  • Tutorials
  • About

Converting GlSLsandbox Shaders

3/9/2015

8 Comments

 
In the last tutorial we talked about converting ShaderToy shaders to GameMaker: Studio. Today we'll be converting GLSL Sandbox shaders. Today we'll convert this shader (the code can also be found below). The main differences are caused by undeclared variables. I will list the fixes to the most common ones.

Shaders on glslsandbox.com

Shaders on GLSL Sandbox have a few differences from shaders in GameMaker. Like on ShaderToy there are no textures most of the time. However GLSL Sandbox only supports frame buffers. If a shader uses theses, there will be a uniform sampler2D with the other uniforms. It can be named anything, but it is most often called "backbuffer" or "bb". Frame buffers must be made in GameMaker outside of the shader. These can be done with surfaces in GameMaker, but because these are very rarely used I will not get in too much detail. 

Varying vectors

Check out tutorial 4 if you haven't already for information about varying vectors. You will need to create a varying vec2 called "fragCoord". Then set it in the vertex shader to "in_Position.xy". You can also remove v_vColour and v_vTexcoord because they won' be used in this shader.
Some shaders also have a varying vec2 called "surfacePosition" (although it is not in this shader). This is used to make shaders where you can scroll and zoom. To make this in GameMaker you should another varying vector in vertex shader called "surfacePosition". Then you should be set like this: 

surfacePosition = in_Position.xy*Scroll.zw+Scroll.xy;

"Scroll" will be a vec4 uniform that we'll add next. That code will zoom with z and w components and offset with the x and y.

Uniforms

Make sure you see tutorial 5 part 2 for details about uniforms.
GLSL Sandbox shaders already have the uniforms setup. As long as you set them to the right values it should work fine. If the shader has "surfacePosition" then only thing you need to add is a vec4 uniform called "Scroll". This can be used in GameMaker to scroll and zoom.

Summary

Here's a final summary of what we have learned:
  • Change "gl_FragCoord" to "fragCoord"
  • Add "fragCoord" and  "surfacePosition" (if needed) to vertex shader
  • Add "Scroll" vec4 uniform if needed
  • Set all uniforms (may include time, resolution or mouse)
Here is the GLSL Sandbox code:

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 resolution;

void main( void ) {

vec2 uv = ( gl_FragCoord.xy / resolution.y );

vec3 color = vec3(fract(sin(dot(floor(uv.xy*32.0+time*2.0),vec2(5.364,6.357)))*357.536));
gl_FragColor = vec4( color, 1.0 );


Converted GameMaker fragment code:

#ifdef GL_ES
precision mediump float;
#endif
varying vec2 FragCoord;
uniform float time;
uniform vec2 resolution;

void main( void )
{
    vec2 uv = ( FragCoord.xy / resolution.y );
    vec3 color = vec3(fract(sin(dot(floor(uv.xy*32.0+time*2.0),vec2(5.364,6.357)))*357.536));
    gl_FragColor = vec4( color, 1.0 );
}


Converted vertex code:

attribute vec3 in_Position;                  // (x,y,z)
//attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
//attribute vec4 in_Colour;                    // (r,g,b,a) unused in this shader.
//attribute vec2 in_TextureCoord;              // (u,v)     unused in this shader.

varying vec2 FragCoord;

void main()
{
    vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
    
    FragCoord = in_Position.xy;
}


Here is the example file:
DOWNLOAD EXAMPLE
8 Comments
ze
9/11/2016 11:31:38 am

Hello! I tried converting this shader http://glslsandbox.com/e#35135.0 to GMS and everything worked... except the clouds are upside down in my test project. What did I miss?
Here's the code:

Vertex code:

//
// Simple passthrough vertex shader
//
attribute vec3 in_Position; // (x,y,z)
//attribute vec3 in_Normal; // (x,y,z) unused in this shader.
//attribute vec4 in_Colour; // (r,g,b,a) unused in this shader.
//attribute vec2 in_TextureCoord; // (u,v) unused in this shader.

varying vec2 FragCoord;

void main()
{
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;

FragCoord = in_Position.xy;
}




Fragment code:

// ----------------------------------------------------------------------------------------
//"Toon Cloud" by Antoine Clappier - March 2015
//
//Licensed under:
// A Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
//http://creativecommons.org/licenses/by-nc-sa/4.0/
// ----------------------------------------------------------------------------------------
// original from https://www.shadertoy.com/view/4t23RR
// ----------------------------------------------------------------------------------------

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 resolution;
uniform float time;

#define TAU 6.28318530718


const vec3 BackColor= vec3(0.0, 0.4, 0.58);
const vec3 CloudColor= vec3(0.18,0.70,0.87);


varying vec2 FragCoord;


float Func(float pX)
{
return 0.6*(0.5*sin(0.1*pX) + 0.5*sin(0.553*pX) + 0.7*sin(1.2*pX));
}


float FuncR(float pX)
{
return 0.5 + 0.25*(1.0 + sin(mod(40.0*pX, TAU)));
}


float Layer(vec2 pQ, float pT)
{
vec2 Qt = 3.5*pQ;
pT *= 0.5;
Qt.x += pT;

float Xi = floor(Qt.x);
float Xf = Qt.x - Xi -0.5;

vec2 C;
float Yi;
float D = 1.0 - step(Qt.y, Func(Qt.x));

// Disk:
Yi = Func(Xi + 0.5);
C = vec2(Xf, Qt.y - Yi );
D = min(D, length(C) - FuncR(Xi+ pT/80.0));

// Previous disk:
Yi = Func(Xi+1.0 + 0.5);
C = vec2(Xf-1.0, Qt.y - Yi );
D = min(D, length(C) - FuncR(Xi+1.0+ pT/80.0));

// Next Disk:
Yi = Func(Xi-1.0 + 0.5);
C = vec2(Xf+1.0, Qt.y - Yi );
D = min(D, length(C) - FuncR(Xi-1.0+ pT/80.0));

return min(1.0, D);
}

void main(void){
vec2 uv = 1.2*(2.0*FragCoord.xy - resolution.xy) / resolution.y;

// Render:
vec3 Color= BackColor;

for(float J=0.0; J<=1.0; J+=0.2)
{
// Cloud Layer:
float Lt = time*(0.5 + 2.0*J)*(1.0 + 0.1*sin(226.0*J)) + 17.0*J;
vec2 Lp = vec2(0.0, 0.3+1.5*( J - 0.5));
float L = Layer(uv + Lp, Lt);

// Blur and color:
float Blur = 4.0*(0.5*abs(2.0 - 5.0*J))/(11.0 - 5.0*J);

float V = mix( 0.0, 1.0, 1.0 - smoothstep( 0.0, 0.01 +0.2*Blur, L ) );
vec3 Lc= mix( CloudColor, vec3(1.0), J);

Color =mix(Color, Lc, V);
}
gl_FragColor = vec4(Color,1.);
}




The draw event that calls the shader:

shader_set(shd_clouds);

time += .05
_shadervar=shader_get_uniform(shd_clouds,"resolution");
shader_set_uniform_f(_shadervar, room_width, room_height);


_shadervar2=shader_get_uniform(shd_clouds,"time");
shader_set_uniform_f(_shadervar2, time);

draw_background_stretched(bg_test, 0, 0, room_width, room_height)
shader_reset();


draw_set_color(c_black)
draw_text(32, 32, "FPS = " + string(fps));

Reply
ze
9/11/2016 11:34:17 am

And here's an image of the result

http://i.imgur.com/kyEGDoF.png

Reply
Xor link
9/11/2016 02:27:12 pm

You can flip the image by flipping your "uv" vec2's y component.
In your case you might do something like this (after "uv" is defined):
uv.y = 1.2-uv.y;
Normally you would do 1.0-uv.y, but because you multiplied it by 1.2 I used 1.2.
I hope this helps!

ze
9/11/2016 02:48:01 pm

That fixed the problem, thanks! :D
But I still can't help but to think I'm doing something wrong. All other shaders from that website I've tried also become upside down in GMS

Xor link
9/26/2016 05:20:00 pm

I should at that to the tutorial then. It must be flipped every time.

Rianon
1/25/2017 08:15:06 am

Actually, I found that "uv.y = -uv.y" is working better, flipping picture and preserving just the same amount of clouds. Then using "uv.y = 1.2 - uv.y", clouds was cutted just below the half of screen.

P.S.: forgive me my bad English, it's not my native :)

batkin
9/25/2016 02:17:43 pm

I'm trying to convert http://glslsandbox.com/e#35480.0 and I'm running into an error 'array reference cannot be used as an l-value' which seems to happen when I try to set the value of an element of array mbPos inside the for loop. Any idea what needs to be done with that to make it work?

Reply
Xor link
9/26/2016 05:17:53 pm

GameMaker doesn't support dynamic for loops. All of the variables should set once in the shader and then used in the loop. If this doesn't work, you can email me (at [email protected]).

Reply



Leave a Reply.

    Tutorials

    New tutorial at GMshaders.com!

    Categories

    All
    3D
    Beginner
    Intermediate

    Archives

    October 2021
    November 2019
    January 2019
    May 2016
    August 2015
    June 2015
    March 2015
    February 2015
    January 2015
    December 2014

    RSS Feed

Powered by Create your own unique website with customizable templates.