GameMaker: Studio

GameMaker: Studio

View Stats:
supware 21 Jan, 2022 @ 8:47am
Method for isometric reflections?
I'm working on an isometric game where the depth of each object is determined by a function of its (x,y,z), and I'd like to add a vertical reflection effect for e.g. water.

I don't think
with objects {draw own reflection}
is possible because I'd need to multiply their depths by -1 during the script. Do I just need to use a bunch of
for(var i = 0; i < instance_number(); i ++)
s, or is there a neat way to do this?
< >
Showing 1-11 of 11 comments
Blind 21 Jan, 2022 @ 9:45am 
First calculate "sea level" (pokemon uses 1 tile, but if you are using 3D isometrics then I can't assume you'll have a height of "1" at all times)

Next, in your draw step - include a low opacity vertically flipped draw of your sprite at a position equally below sea level as your character is currently above sea level.

That's the bare basics: There are more nuanced ways of doing this too such as drawing ALL objects onto a surface that's sole purpose is to be rendered under water effects
supware 21 Jan, 2022 @ 10:11am 
Even without the depth issue I'm afraid just flipping vertically isn't enough for isometric geometry, since the reflection is showing you a face of the cube you can't see in the non-reflected version and vice versa. I'll have to make a reflected sprite for every block type I want to reflect...!

Might as well mention that in my current attempt I'm using a "deco_water" object to draw reflected versions of all affected sprites onto a surface, apply a shader, then draw the surface at a high depth. In theory the only issue is that the reflected sprites' depths are negatives of what they should be

For reference: https://cdn.discordapp.com/attachments/664869553976901657/934149884691488768/unknown.png
Last edited by supware; 21 Jan, 2022 @ 10:18am
Blind 21 Jan, 2022 @ 3:54pm 
there's no need for such advanced trickery... just draw your entire gamefield as a surface and render it upside down using everything that isn't water as a mask.
Zappy 22 Jan, 2022 @ 12:45am 
Originally posted by Blind:
there's no need for such advanced trickery... just draw your entire gamefield as a surface and render it upside down using everything that isn't water as a mask.
Won't that make it so that something northwest of the character (on the same height) will appear southwest of the character in the reflection? (Remember, this is an isometric game, not a 2D sidescroller, so the game world isn't "flat".)

Originally posted by supware:
- Might as well mention that in my current attempt I'm using a "deco_water" object to draw reflected versions of all affected sprites onto a surface, apply a shader, then draw the surface at a high depth. In theory the only issue is that the reflected sprites' depths are negatives of what they should be -
Can you "sort" these objects while drawing them? If so, if we say that the depth of a non-reflected object is "-y - z", then the depth of a reflected object should be "-y + z" (not "+y + z" nor "+y - z"), I think.
Blind 22 Jan, 2022 @ 12:52am 
It's supposed to appear southwest, reflections are cast by the sun - not the camera. (unless i'm misunderstanding you.

I still think the best option will be with masking
Zappy 22 Jan, 2022 @ 2:57am 
Originally posted by Blind:
It's supposed to appear southwest, -
See this image: https://imgur.com/j6X13tW
Here, you're suggesting the middle "Vertically-flipped scene reflection", which doesn't look right compared to the "Proper scene reflection" on the right. In the latter, the green orb is northwest of the blue orb in the original scene and in the reflection.

The middle option would work in a 2D sidescroller, but not in anything resembling 3D.

Originally posted by Blind:
- reflections are cast by the sun - not the camera. -
What do you mean?
Last edited by Zappy; 22 Jan, 2022 @ 2:58am
Blind 22 Jan, 2022 @ 8:23am 
ok, i simply misunderstood what you were doing.

In this case just extend all your terrain manually (duplication, just like in 3D) and render that above your reflection object so they are obscured bu the terrain, and then render your primary object. (this is a brute force fast way and will run into problems if you have enough height that an object may appear into a different "lake")

Render order would be (all object reflections), (all terrain), (all reflectable objects)

You want something like, This, right? https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html
Last edited by Blind; 22 Jan, 2022 @ 8:24am
supware 22 Jan, 2022 @ 9:14am 
That looks like the same effect I'm after yeah. Ordering them somehow seems like the most sensible idea, but I still don't see exactly how it'd work (you'd have to order all reflectable objects by depth I guess...?)
And here's an image of my attempt where the character is facing the water;[cdn.discordapp.com] however I end up ordering the reflections I don't see a way around having to make new sprites for everything like how you can only see his face in the reflection
supware 22 Jan, 2022 @ 9:30am 
(I should probably clarify if it's not obvious that I'm not using any 3D stuff, the game is just hexagons and circles)
Blind 22 Jan, 2022 @ 2:22pm 
Yes, you'd have to draw reflections for the "underside" of any object being reflected. If you have some isometric dice jumping over the water and the 1 dot is on top, its reflection should cast the 6 dots.
supware 22 Jan, 2022 @ 11:42pm 
So I guess it boils down to "how do I efficiently make a ds_list/array of all instances ordered by depth"... I'll take a look at this today
Last edited by supware; 22 Jan, 2022 @ 11:42pm
< >
Showing 1-11 of 11 comments
Per page: 1530 50