Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(+1)

I don't understand your question, could you please elaborate?

If you mean turning the effect on/off: yes, obj_viewcontrol takes control over the application surface when it is created and returns it when it's destroyed / the room ends, so you should be able to just create one when you want the effect to happen and remove it when you don't want it anymore.

If you mean controlling the effect so the alternate view slowly slides in from outside the screen: I think the easiest way to do this would be adding a new uniform vec4 to the fragment shader which contains a "distance bias" for each of the 4 players. Subtract the corresponding value when calculating which player is nearest. This means if you set distance_bias[0] to (size of your view) and then gradually decrease it, player 1 will have the entire screen space to themselves because their view "bleeds over" the others, but as you decrease it the other views fade in.

Sorry for my lack of clarity.

Basically my game is a single player, what I want to achieve is very similar to the second option you told me.

I want a camera that focus on the main mission to do that slowly slide in from outside of the view when the player do some progress.

For example: to open the gate the player have to activate 2 terminals, when the player activate 1 of them, the view slowly slide to the center and show the progress, maybe the gate has 2 lights and I want to show that he turned ON one of them.

(1 edit) (+1)

OK, for cases like that the second option probably will work - basically manipulating how the "distance" is computed in the shader so you can overlay the views however you want. 

If you want the additional views to take precedence no matter what, it gets a bit more complicated, but I'm thinking something like this:

  • Add additional uniforms for "view size" parameters for all views (these could be vec2 if you want different aspect ratio horizontally or vertically or a single vec4 for them all if you want uniform size)
  • Rather than checking all positions to see which one is nearest, the loop checks the popins only (view 1-3) and if it's closer to the focal point than "view size", it uses that texture.
  • If it's NOT close enough to any focal point, it always uses the view 0 texture.

So basically you don't pick the nearest view, you check if you're in one of the popin views and just want a yes/no answer.

(Additionally, you can fade in/out the views by changing the view size that gets passed into the shader, and set it to 0 to disable the popin view entirely - and of course modifying the focal point moves the view around the screen as well, like before)

So basically i'm pretty bad with shaders, is there any chance to add the feature in this tool?

I can pay a supplement for the trouble, I tried a lot by myself without success and I think is the moment to ask people more good than me!

(+1)

Got a minimal example working with these changes:

Control Create event at the bottom:

u_voron_vsize = shader_get_uniform(        sh_voronoimerger,    "vsize"            )
p2size = 0

(+ added some keyboard events to let me increment/decrement p2size with 0.001 at a time - it's in screenspace coordinates so 1.0 means "100% of the screen width/height" so in-game you want small decimal values for a small pop-in view)


Control Post Draw event, line 14:

shader_set_uniform_f(        u_voron_vsize,    0,    p2size,    0,    0)

(note how vsize[0] doesn't matter so I always set it to 0, but player 3 and 4 are set to 0 because we wanna disable their views - so different reasons)


sh_voronoimerger (Fragment):

New line before main:

uniform vec4 vsize;

Lines 20~31 changed like so,

     //Go find the nearest screen position and use that
     float bestdist = 999999.99, dist;
     int bestid = 0;
     for(int c = 3; c > 0; c--){
         if(c < num_players){
             dist = distance(screenpos[c].xy,v_vTexcoord);
             if(dist < vsize[c]){
                 bestdist = dist;
                 bestid = c;
             }
        }
     }
     gl_FragColor = sampcol[bestid];

I.e. run the loop backwards, don't run it for 0, but default to 0 if you don't pass the distance check any time.

(5 edits)

Ok I made the changes you told me and added a keyDown event that increase the p2size and that's the result.

The other view appear from the top right (but I think is because the 2nd player was in that position) in a oval way while instead, I would like it in a circular way and in a fixed position, top right is ok to me.

Is there any chance to have even a black outline of the circular view?


(+1)

Your first guess is correct, the view is still centered around the 2nd player's relative position, but you can just explicitly change that (since you're not going to actually have a second player) to get the cut-in wherever you want.

The black outline is pretty simple, check if the distance is "close to the max value" (e.g. < 0.001 difference, change to a larger/smaller value to change thickness) and if so, set the gl_FragColor to black rather than any of the sampled colors.

Despite the simple idea it's a bit of a mess but I'm thinking two changes will be enough:

#1, the distance check

if(dist < vsize[c]){
      bestdist = dist;
      bestid = c;
      if(dist > vsize[c] - 0.0001){ //This part is new
           bestid = 9;
      }
}

#2, at the end

if(bestid < 9){
    gl_FragColor = sampcol[bestid];
}
else{
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}

Making it circular gets more complicated but I think you can "cheat" a bit to simplify this - instead of taking the distance between the actual pixels when doing the distance check, make two new vec2 variables which are copies of the player position / current fragment position but you multiply the x coordinate by 9.0/16.0 (the inverse of the aspect ratio).

So something like this might be enough, just replacing the dist check:

dist = distance(screenpos[c].xy*vec2(9.0/16.0, 1.0),v_vTexcoord*vec2(9.0/16.0, 1.0));

Thank you for your support! I made the changes you told me but the result seems strange.

The other view is still an oval, instead I think is more oval than before. 

 The black outline is present but is too much thin.

I'm not clear on how to keep the other camera's appearance fixed at the top right. 

 The oval camera appearance is not perfectly centered on player 2.

Thank you so much for the support!


(1 edit) (+1)

Oh right, multiplying by a smaller value makes distances shorter than they actually are - my bad, the 9/16 factor should probably go for the y value instead of the x value.

To make the outline thicker just increase the "0.0001" used for that comparison, 0.001 is probably too thick so maybe 0.0005 will look better? (If you have a specific pixel width you want, just divide that with the screen width to get the value to use here)

As you can see for both of these, I don't really know everything and a lot of this is trial and error :P You kinda can't get away from it with shaders, they're very visual compared to regular game logic code...


The "player 2 position" used in the shader is set in the control object's Post Draw event, it's the third and fourth row of the pos array and they're percentages (since they're coordinates in screen space). So for instance if you always want the pop-in in the top right corner, you could change it to something like this:

var pos = [
     global.voron_screenpos_x[0],
     global.voron_screenpos_y[0],
     0.85,
     0.15,
     global.voron_screenpos_x[2],
     global.voron_screenpos_y[2],
     global.voron_screenpos_x[3],
     global.voron_screenpos_y[3]
];
(+1)

Thank you a lot for the support I will try as soon as possible! 

I really appreciate your kindness!

Just one last thing! ( everything you told me works pretty well just the start point of the other view is not centered to player 2 )

 

If I want to import the tool in my project and have a camera that always points to the level target, what do I have to do?