0
\$\begingroup\$

I am trying to use this shader in the game I am making with Game Maker Studio 2.

I tried to convert it for GM2 and here is my result:

Shader type I used on GM2 is GLSL ES

myshader.vsh

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)
attribute vec2 in_TextureCoord;              // (u,v)

varying vec2 v_vTexcoord;
varying vec4 v_vColour;

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;
    
    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
}

myshader.fsh

varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform vec2 resolution;
uniform float pixelSize;
uniform float gamma;

void main(){
    vec2 uv = gl_FragCoord.xy / resolution.xy; 
    float alpha = 1.0;
    vec4 color = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    gl_FragColor = color;
  
    float pixelSize = 3.0;
    float gamma = 3.0;
  
    vec2 pseudoResolution = floor(resolution.xy / pixelSize);
    vec2 pseudoPixel = floor(gl_FragCoord.xy / float(pixelSize));
    vec2 pseudoUv = pseudoPixel / pseudoResolution;
  
    vec3 tex = texture2D(gm_BaseTexture, pseudoUv).rgb;
    float bw = (tex.r + tex.g + tex.b) / gamma;
    float col = 0.0;
    
    if(bw > 0.8) {
        col = 1.0;} 
    else if (bw > 0.6) {
        col = float(!(int(pseudoPixel.x) % 2 == 0 && int(pseudoPixel.y) % 2 != 0));} 
        else if (bw > 0.4) {
        col = float((int(pseudoPixel.x) % 2 + int(pseudoPixel.y) % 2) % 2 == 0);} 
        else if(bw > 0.2) {
        col = float(int(pseudoPixel.x) % 2 == 0 && int(pseudoPixel.y) % 2 == 0);}
    gl_FragColor = color * vec4(col, col, col, alpha);}

But this is just throwing this compile error:

Fragment Shader: shd_1BitDithering at line 30 : ''

Line 30 is:

25    if(bw > 0.8) {
26      col = 1.0;} 
27  else if (bw > 0.6) {
28      col = float(!(int(pseudoPixel.x) % 2 == 0 && int(pseudoPixel.y) % 2 != 0));}
29      else if (bw > 0.4) {
-> 30   col = float((int(pseudoPixel.x) % 2 + int(pseudoPixel.y) % 2) % 2 == 0);} 
31      else if(bw > 0.2) {
32      col = float(int(pseudoPixel.x) % 2 == 0 && int(pseudoPixel.y) % 2 == 0);}
33  gl_FragColor = color * vec4(col, col, col, alpha);}

Coming from a Python background, I really have no idea how to debug that message.

Any clue on how could I make this shader work, or how could I understand what the problem is?

\$\endgroup\$
3
  • \$\begingroup\$ The code in the whole shader and the code you have pasted in to highlight the erroring line seem to differ as the latter one is using the word mod, what's going on there? Also my initial guess would be that the GLSL version does not support the modulo operator, does the error disappear if you replace x % a with mod(x, a)? \$\endgroup\$
    – Tyyppi_77
    Jul 11 at 17:36
  • \$\begingroup\$ That was the problem, % is not supported. I used mod(x,a) and everything went fine \$\endgroup\$
    – Kodeeo
    Jul 12 at 17:12
  • 2
    \$\begingroup\$ If that solved your problem, want to post the solution as an Answer below? \$\endgroup\$
    – DMGregory
    Jul 12 at 17:16
0
\$\begingroup\$

Ok, so I managed to get it working.

My code had many problems, first of all the modulus operand % which is not supported by GLSL ES.

I had to use the mod function and, as I found on the official docs, the function needs to be called with the two operands as parameters. As I can understand from the docs, I also had to give the value to divide for as a float.

Applied this, the code gets more and more confusing because of the many parentheses: on line 30 the original script is making a modulus of a modulus, which has been a bit confusing to convert with the mod function syntax.

Fixed this, it was giving out an error on the "==" operand, so I made any number involved in a comparison a float, this fixed it.

The updated code (only the if cycle) is here:

if (bw > 0.8) 
{
    col = 1.0;
}
else if (bw > 0.6)
{
    col = float(!(mod(pseudoPixel.x, 2.0) == 0.0) && (mod(pseudoPixel.y, 2.0) != 0.0));
}
else if (bw > 0.4)
{
    col = float(mod((mod(pseudoPixel.x, 2.0) + mod(pseudoPixel.y, 2.0)), 2.0) == 0.0);
} 
else if (bw > 0.2) 
{
    col = float((mod(pseudoPixel.x, 2.0) == 0.0) && (mod(pseudoPixel.y, 2.0) == 0.0));
}
\$\endgroup\$
1
  • \$\begingroup\$ You can simplify your nested moduli if you want. odd + odd = even, odd + even = odd, even + even = even. So mod(x + y, 2.0) will give you the same result as mod(mod(x, 2) + mod(y, 2), 2) \$\endgroup\$
    – DMGregory
    Jul 13 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.