how can I apply a saturation and size gradient on a room layer?

Hi!

I'm playing around with a sidescroller, but instead of having what's at a higher y than the player be underground I'm trying to use it as foreground and looking for ways to show perspective. I'm thinking that progressively increasing the saturation and the size of everything that's on my foreground room layer based on their y would do the trick, but I have no idea how to do that and I couldn't find a tutorial or post on the topic. Any thoughts?

Thanks!
 

Kyon

Member
something like
Code:
scale=(ystart-y)/100;
image_xscale=1+scale; image_yscale=1+scale;
Idk this would scale the object if it goes higher than it's starting y position.
Maybe this helps? idk
 
something like
Code:
scale=(ystart-y)/100;
image_xscale=1+scale; image_yscale=1+scale;
Idk this would scale the object if it goes higher than it's starting y position.
Maybe this helps? idk
It would work if the objects moved, but not for static ones like trees. What I need is something like if the object is on the foreground layer, then check its relative y position from the row at 1/2 of the viewport's height, and then scale the image proportionally up to, say, 150%, so something like
Code:
currentView_y = camera_get_view_y(view_camera[0]);
current_view_h = camera_get_view_height(view_camera[0]);
distance_to_center = round((current_view_h-currentView_y)/16);
scale_ratio = round(distance_to_center/50);
image_yscale = 1+(scale_ratio/100);
but how do I check which room layer the object is on to determine if this script should affect it or not? And that's only for the scaling part.

The other part is what I'm more confused about: applying a filter to the sprite, but at a different intensity based on the same row number relative to the row in the middle of the view. Can that be done?

EDIT: added the scaling code example
 
Last edited:
So I'm calling this script

Code:
currentView_y = camera_get_view_y(view_camera[0]); 
current_view_h = camera_get_view_height(view_camera[0]); 
distance_to_center = round((current_view_h-currentView_y)/16); 
scale_ratio = round(distance_to_center/50); 
image_yscale = 1+(scale_ratio/100);
in the create event of my foreground tree items

Code:
script_execute(scr_scaleForPerspective());
but seems like that doesn't work. I also still don't know how to apply the filter either. Any suggestions?

Edit:Typos
 
Last edited:

Yal

🐧 *penguin noises*
GMC Elder
Could you create a quick mockup of the effect you wanna create using the scale/blur tools in GIMP or something? I'm having a hard time picturing what effect you wanna create. Can the player move towards the foreground/background or do you just want layers to scale when they're used as foreground, even if they're using the same assets?

To desaturate sprites, I think the easiest way to achieve the effect would be using a shader and then blend the r, g and b values of the texture with some other color... either some gray shade (e.g. 0.5, 0.5, 0.5 for standard gray), or the color of the current background. Not sure if there's hue/saturation/luminosity values in OpenGL (the language GM's shader uses by default) or it only uses RGB values.
 
Doing a simple desaturation shader is about how far I got in programming shaders last time I tried. Here's a simple fragment shader:
Code:
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform float desaturation;

void main()
{
    vec4 baseCol = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    float value = ( baseCol.r + baseCol.g + baseCol.b ) / 3.0;
    gl_FragColor = vec4( mix( baseCol.rgb, vec3( value ), desaturation ), baseCol.a );
    //If you instead want a saturation shader, use the next line instead of the previous one:
    //gl_FragColor = vec4( mix( baseCol.rgb, vec3( value ), 1.0 - desaturation ), baseCol.a );
}
You can set the uniform like so:
Code:
// Create Event
desatShader = shd_desaturation;
desaturation = shader_get_uniform(shader, "desaturation");

// Draw Event
shader_set(desatShader);
shader_set_uniform_f(desaturation, [Value from 0.0 - 1.0]);
draw_sprite(sprite, subimg, x, y);
 

Yal

🐧 *penguin noises*
GMC Elder
Shader trivia thing: an "uniform" is an argument that's set outside the shader, it's called "uniform" because it has the same value for every pixel / vertex the shader draws (unlike most other variables which are unique for each run of the shader). Knowing that might make it feel less weird to use, that's my experiences at least.
 
Top