• 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!

Shaders Using one rendered texture to change another

Erayd

Member
I'm trying to find a way to change the color of only the pixels on an object that are being overlapped by the pixels of another. For example, there is a house in a 2.5d environment, an NPC walks behind the house but their head is still visible.

At this point, the body is invisible, unless I get the pixels in the house that are being drawn at the same coordinate as the NPC's pixels and then change those pixels to show a shadow or a highlight of the npc.

It's hard to explain so if anyone has any questions, please ask. I feel like this is something I can accomplish in shaders I just can't think of how I'm to go about that. I can get the texture of the NPC and send it to the house shader but that doesn't tell me the room position right? I don't know :/
 

Erayd

Member
I'm still playing with it, it did get me closer but I'm still not quite there. What I need is to get the cut portion and then change the colors of those pixels, but leave the others that aren't being covered by anything, still there. I was able to get the portion not covered by the house to render and to get the pixels being covered using your method listed. Perhaps this is where I'm having my brain fart. Below, you can see my draw event as well as the shader.

Using just the masking effect: https://www.screencast.com/t/T3pVH8Ef4
Using the masking effect with the shader: https://www.screencast.com/t/2rE8QEVNXp
Using shader and only openGL pixel color, not base texture: https://www.screencast.com/t/tgLojwMc76dQ

The shader is giving me white pixels instead of a transparency. I figured if all of the pixels are rgb values at 1.0 then I could just not set the gl_FragColor if the pixel color is perfect white of 1.0, that didn't work either. Perhaps the blend mode is affecting the shader? What am I missing exactly? How do I drop those white pixels now that I have access to the portion covered by the house?

Edit: After some further research, I think my real question here it, "Why can't I get the same result when I pass the draw through the shader in the same location as without the shader?" Meaning, without a shader I get the bottom portion of the sword , with a shader with no changes to the system, I get white.

I'm in deep guys... Gonna be tough to dig out of this one.

Draw Event:
Code:
draw_self();

gpu_set_blendenable(false)
gpu_set_colorwriteenable(false, false, false, true);
draw_set_alpha(0);
draw_rectangle(0,0, room_width,room_height, false);

draw_set_alpha(1);
draw_sprite(covered_by.sprite_index, 0, covered_by.x, covered_by.y);
gpu_set_blendenable(true);
gpu_set_colorwriteenable(true, true, true, true);

gpu_set_blendmode_ext(bm_dest_alpha, bm_inv_dest_alpha);
gpu_set_alphatestenable(true);

shader_set(shd_Highlight);
var distance_to_player = point_distance(x, y - (sprite_height/2), obj_Player.x, player_center()) - 27;
var max_value = 20.0;
var value = clamp(distance_to_player, 0.0, max_value);
shader_set_uniform_f(shader_get_uniform(shd_Highlight, "value"), value);
draw_self();
shader_reset();

gpu_set_alphatestenable(false);
gpu_set_blendmode(bm_normal);
Fragment Shader:
Code:
varying vec2 texture_coord;
varying vec4 pixel_color;

void main() {
    vec4 color = texture2D(gm_BaseTexture, texture_coord);

    gl_FragColor = color * pixel_color;
}
Vertex Shader:
Code:
attribute vec4 in_Colour;
attribute vec2 in_TextureCoord;

varying vec2 texture_coord;
varying vec4 pixel_color;

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;
 
    pixel_color = in_Colour;
    texture_coord = in_TextureCoord;
}
 
Last edited:

Erayd

Member
That did it. Adding in the fog method worked. All I really needed once I had the framework from the first masking article was the ability to change the colors in the sprite. The lady you linked me to got me that and a bit better structure for it all, thank you so much! It's so hard to find good content/help with game design (Or I just suck at google), so this youtuber is going to help me with a lot of those types of topics people don't really touch on much.

Edit: After some further testing, I'm still having some graphical issues. I can't use shaders with this because it happens AFTER the shaders. So it pops up on top and kinda looks not so good. My issue is I have the house alpha around the player lowering, but the silhouette shows up right over the player. I'll spend more time thinking about it and tinkering, I'm sure there's still a solution to this and I'm getting closer.

I find this to be strange and I don't understand. Basically, after following both of those tutorials, I come up to a road block on both ends. What I just don't understand is why I cant get a shader to do this? Even in the yoyo dungeon tutorial they mention that using a simple shader is better than using gpu_set_fog. But using ANY shader in replace of that results in the entire sprite being rendered. Meaning, the 0 alpha is now an opaque white on all sprites. Exampled in my pictures.
 
Last edited:
Top