• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

[SOLVED] Magnifying Shader

A

arirish

Guest
I am working on a magnifying effect in my game at the moment. I'm achieving this by creating a second view which doubles the port size of the area it's currently over. After playing around with the view variables for a loooong time, I think I've gotten it working nicely enough - I had some issues with this because I had to contend with my initial view, which led to a lot of funkiness.

Anyway, what I now have is a square I can move around the screen which essentially doubles the size of whatever is beneath it. I'd like a circle. I have no idea how to accomplish this. Presumably I'll have to use surfaces or some such?

Second question, I downloaded a free fisheye shader from the marketplace, which looks like it works pretty well, but I'd like it to only apply to view 1 (ie only the magnified square/circle), and not the whole thing. Possible? Going about things the wrong way?

Totally out of my depth on this one.
 
A

arirish

Guest
What shader from the marketplace are you using?
Haha, oh man. I was clearly not paying attention last night. I found it again, and it's called 'Simple FULLSCREEN Shaders': https://marketplace.yoyogames.com/assets/142/simple-fullscreen-shaders

EDIT: Turns out I already had this free shaders pack: https://marketplace.yoyogames.com/assets/261/free-shaders which includes a 'magnify' shader which applies the effect I want. I'm trying to understand the code now so I can make it work for what I want.

Okay, so no idea what I'm doing with this or how to make it work for what I want, BUT, I do see how I should be able to use the shader alone, without having to bother with a second view, and that as such the whole 'circular view' part of my question is irrelevant.
 
Last edited by a moderator:
I'm working on it cause I got curious on how to do it. This is my current and maybe final version. Wanna try one more thing though :)
I'll upload a GMS 2 file and code when I think I'm done if you're interested.
 
Last edited:
A

arirish

Guest
Oh, damn you sir! That is EXACTLY the effect I want, right down to the glass glare/metal ring sprite!

However, I'm using GM 1.4 - how easy will it be for me to modify it for that?
 
Last edited by a moderator:
A

arirish

Guest
Okay, great. I've been fiddling with this a bit, found values I like, and removed all the demo stuff for changing the values (since in game I only need one set of settings that can't be changed). The actual magnifying part works really well, I love it. Thank you so much!

What I'm having a little trouble with is the position of the glass in relation to what it's magnifying. I suspect this is because of my view (my viewport is double the size of my view). I tweaked the following line:

Code:
draw_surface_part(application_surface, left, top, size, size, 0, 0);
to this:

Code:
draw_surface_part(application_surface, left*2, top*2, size, size, 0, 0);
and that got me closer, but I don't want to just throw random numbers at it until it fits. Also it seems to have trouble if I'm in a room bigger than the view. I'll keep playing around.
 
Last edited by a moderator:
In Step Event I set:
x = mouse_x;
y = mouse_y;

And in draw end event I set:
var left = x - half_size;
var top = y - half_size;

Now if the room is not 1:1 on the application surface you'll need to fix the coordinates.
If you scale the game you need to consider the scale factor and if your room is larger than the view you'll also factor in the view's position in the room since both mouse_x/y and the instances x/y are in room space and not in view space.
So dont just try random numbers. Use stuff like view_xview (or whatever was used in GM:S 1) and the sdcale factor or your view if you're scaling.
 
A

arirish

Guest
Yeah, okay, I'm lost. Nothing I've tried is working.

I've got it to where I can use it in a room the same size as the view, compensating for the doubled view port, but nothing I do to any of the formulae gets it close to working in a larger room, and I'm stumped, because it seems really obvious what should work.

In a larger room, if I'm standing at the top-left edge (ie the view is at 0,0), it works, but as soon as I'm away from that, nothing.

EDIT: so I added some text code:

draw_sprite(sCharIdle,0,view_xview,view_yview)

and that works fine, so I don't know why the rest isn't.

EDIT EDIT: The glass draws in the right place, it's just the shader circle that doesn't.
 
Last edited by a moderator:
A

arirish

Guest
For the record, here's the last variant that worked in a view-sized room. I've been trying things since then, but no luck.

Code:
/// @description draw magnifying glass

var left=   view_xview+Difference(view_xview,x)-half_size;
var top=    view_yview+Difference(view_yview,y)-half_size;

// CREATE THE MAGNIFYING SURFACE:
if !surface_exists(srf)
srf = surface_create(size, size);
surface_set_target(srf);
//draw_surface_part(application_surface, x-half_size, y-half_size, size, size, view_xview, view_yview);
draw_surface_part(application_surface, left*2+half_size, top*2+half_size, size, size, view_xview[0], view_yview[0]);
surface_reset_target();

// DRAW THE MAGNIFYING EFFECT:
shader_set(shd_magnifying_glass);
shader_set_uniform_f(u_zoom1, zoom1);
shader_set_uniform_f(u_zoom2, zoom2);
shader_set_uniform_f(u_radius, radius);

texture_set_interpolation(true);
draw_surface(srf, left, top);
texture_set_interpolation(false);
shader_reset();

// DRAW THE MAGNIFYING GLASS:
draw_self();

// DRAW SPECULARS AND FOCUS:
draw_set_blend_mode(bm_add);
draw_sprite(spr_focal, 0, x, y);
draw_set_blend_mode(bm_normal);
 
If the room is larger than the view but the view is not scaled. Then this should be the only changes:

Code:
var left = x - half_size;
var top = y - half_size;

// CREATE THE MAGNIFYING SURFACE:
if !surface_exists(srf) srf = surface_create(size, size);
surface_set_target(srf);
draw_surface_part(application_surface, left - view_xview[0], top - view_yview[0], size, size, 0, 0);
surface_reset_target();
...
So you still need to draw to 0, 0 since that's the top left corner of the small magnifying glass surface.

Let me know if you're even scaling, then we'll further need to adapt the code.
 
A

arirish

Guest
I got it. Thank you so much for your patience on this. This tweak to your code has everything aligned nicely at any point in any size room, view scale accounted for.

Code:
draw_surface_part(application_surface, (left - view_xview[0])*2+half_size, (top - view_yview[0])*2+half_size, size, size, 0, 0);
Issue solved, and a beautiful magnifying effect. Thanks @The Reverend!
 

BithSnake

Member
Bump! I have a question. How do i go about if i want to use this magnifying glass shader on a object that does not follow the camera.x and camera.y (camera_get_view_x(view_camera[0]) & camera_get_view_y(view_camera[0])) ? Lets say i just want a magnifying glas that “looks” at another object. I am using the application_surface when I draw the surface atm and it’s an issue since I want it to focus on another object. The camera x and y is set on the player. So I get the magnifying effect on the other object. But it “looks” at the player.. I hope you understand what I mean ! And I would not want to use 2 camera views..thankfull for any help. @The Reverend
 
Top