• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

Grayscale Shader

A

atxgamedesigner

Guest
So I want to dynamically cut color saturation and fade my enter view to black/white.
I figured a shader could handle this?

I've never worked with shaders, and I'm not sure how to manipulate a shader every step (decrementing the saturation from full color to full grayscale).

Any tips would be greatly appreciated!
 
A

atxgamedesigner

Guest
So I figured out how to create a shader.
But I cant figure out how I can adjust the saturation over time.
Is this done by using multiple shaders (turning one off, then turning another on).
Or can this be done dynamically with the one shader?
 

FrostyCat

Member
Use uniforms, see the Manual entry for shaders.

Starting with a grayscale shader, add one more uniform to its fragment shader. Return the linear interpolation between the original colour (0) and the resulting colour (1) using that uniform. Set up a variable that transitions from 0 to 1 over time, then set the uniform to it when applying the shader.
 
D

Drewster

Guest
So I figured out how to create a shader.
But I cant figure out how I can adjust the saturation over time.
Is this done by using multiple shaders (turning one off, then turning another on).
Or can this be done dynamically with the one shader?

You want to use uniforms to pass data into the shader, like a time element, or perhaps a saturation level that you are looking for.
A uniform is just a variable that's populated from outside the shader -- in your regular GML code.

For example, I've got a simple shader where I pass in a variable (uniform) called "iTime" -- which is just a number that increments by 1 each second. Or rather, in my case, it increments by 1/room_speed each step. So I've got.

CREATE EVENT:
Code:
if (shaders_are_supported())
    if (shader_is_compiled(shad_GameBackground)) 
        uni_time = shader_get_uniform(shad_GameBackground, "iTime");

bgTimeTicks = 0;
STEP EVENT:
Code:
bgTimeTicks += (1/room_speed);
DRAW EVENT:
Code:
if (shaders_are_supported())  {
    if (shader_is_compiled(shad_GameBackground))  {
        shader_set(shad_GameBackground);
        shader_set_uniform_f(uni_time, bgTimeTicks);
    }
}
// Regular drawing stuff goes here
if (shaders_are_supported())  {
    if (shader_is_compiled(shad_GameBackground))  {
        shader_reset();
    }
}

SHADER -- shad_GameBackground

Vertex shader just has the uniform iTime added:
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)
attribute vec2 in_TextureCoord;              // (u,v)

uniform float   iTime;      // VARIABLE FROM GML

varying vec2 v_vTexcoord;
varying vec4 v_vColour;
varying vec2 v_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;
  
    v_vColour = in_Colour;
    v_vTexcoord = in_TextureCoord;
    v_fragCoord = in_Position.xy;
}
Fragment shader declares the same iTime uniform:
Code:
// this is right at the top..
uniform float   iTime;

// then just use it in your main() like an other variable
 
Top