[Effect] Outline

Share your Construct 2 effect files

Post » Sat Nov 22, 2014 6:30 pm

Any ideas why this effect breaks my project when exporting with crosswalk (black screen on startup)?
Image
B
59
S
21
G
11
Posts: 481
Reputation: 10,716

Post » Fri Jan 23, 2015 8:55 pm

Hi, R0J0, you said edits are welcome - for my purposes the effect didn't suffice because it didn't have the expanded draw rectangle and had all the extra parameters for colors, size, etc.

So I went ahead a kinda re-purposed it to do a single thing - fill the original image with black and add a 2px outline. This lets use create a neat selection effect if the shapes are placed on an additive layer:

Image

I have but one question - does this seem to be the optimal way to do it?

Code: Select all
/////////////////////////////////////////////////////////
// Selection outline effect
//
varying mediump vec2 vTex;
uniform lowp sampler2D samplerFront;

precision lowp float;
uniform lowp float pixelWidth;
uniform lowp float pixelHeight;
uniform lowp float width;

void main(void)
{
   lowp vec4 front = texture2D(samplerFront, vTex);
   
   front = vec4(0.0,0.0,0.0,front.a);

   float dx = pixelWidth*2.0;
   float dy = pixelHeight*2.0;
    float dxdiag = 0.7071*dx;
   float dydiag = 0.7071*dy;
   
    float a0 = texture2D(samplerFront, vTex + vec2(-dxdiag, dydiag)).a;
    float a1 = texture2D(samplerFront, vTex + vec2(dxdiag, -dydiag)).a;
    float a2 = texture2D(samplerFront, vTex + vec2(-dxdiag, -dydiag)).a;
    float a3 = texture2D(samplerFront, vTex + vec2(dxdiag, dydiag)).a;
    float a4 = texture2D(samplerFront, vTex + vec2(-dx, 0.0)).a;
    float a5 = texture2D(samplerFront, vTex + vec2(dx, 0.0)).a;
    float a6 = texture2D(samplerFront, vTex + vec2(0.0, dy)).a;
    float a7 = texture2D(samplerFront, vTex + vec2(0.0, -dy)).a;
   
    float ina=max(max(max(max(max(max(max(a0,a1),a2),a3),a4),a5),a6),a7)-front.a;

    float outa = ina + front.a*(1.0-ina);
    vec3 outrgb = (vec3(1.0,1.0,1.0)*ina + front.rgb*front.a*(1.0-ina));
    gl_FragColor = vec4(outrgb, outa);
}


I did extensive performance testing and despite my perceived "performance optimizations" (2x less multiplication, etc) it doesn't really change. And expanding the draw rectangle instantly cuts fps in half. Still, it gets teen fps on my modest machine with 1000 objects, that's more than enough for its intended use.

Any feedback is welcome.
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Sat Feb 21, 2015 11:42 am

shinkan wrote:@R0J0hound
There is an issue, but not sure if it's with your fx or Node-Webkit, so I thought I ask You first.
This is how it looks in Node-Webkit preview:
Image

and here's how it looks after exporting to Node-Webkit:
Image

Outline width is set to 0.2.

Edit: Actually it's same with normal html5: Fine in preview, different after export.


Is there a solution to this yet?
Works great no problem in preview, but does this in export.

Image
B
15
S
5
G
2
Posts: 154
Reputation: 3,076

Post » Sat Feb 21, 2015 1:02 pm

I wouldn't be too surprised if it has to do with one or two bugs (?) that seem to exist within C2's rendering engine:

need-help-with-a-shader-coordinate-weirdness-2nd-post_t124440
discussion-shader-coordinate-changes-with-transparency_t124665

I have submitted a bug report and, hopefully, something will come of it.
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Mon Feb 23, 2015 7:17 pm

Put images of plugin work
B
45
S
9
G
10
Posts: 194
Reputation: 8,165

Post » Mon Feb 23, 2015 7:26 pm

luisgmolina wrote:Put images of plugin work por favor.


ftfy.
Image
B
13
S
3
G
1
Posts: 61
Reputation: 968

Post » Mon Feb 23, 2015 8:40 pm

@blackcrypt Thanks you for fix my text.

Sorry for my bad english.
B
45
S
9
G
10
Posts: 194
Reputation: 8,165

Post » Wed Jun 08, 2016 12:11 am

@R0J0hound

Great plugin/effect as always bud!

One request if it's at all possible... can you add an opacity setting and/or blending modes for the outline?

I also have a question regarding how the outline is drawn around objects, since when applied to an entire layer it outlines a whole object (when it's made of smaller parts) but if applied to the individual objects itself it wraps each individual sprite instead. I was wondering if it's possible to achieve the same effect as applying it to the entire layer, but using it on individual sprites instead. The reason for this is to be able to change the outline colour of specific parts at runtime, while leaving other parts alone. Currently it draws an outline that overlaps the other body parts/segments of the container object so the only way around it is to apply to the entire layer - but then I have to colour the whole layer at once.

Thanks again for taking the time to make this - it's super helpful even in it's current state.

~Sol
Tired of crappy file hosts that are crappy? Get DROPBOX - https://db.tt/uwjysXJF
Moderator
B
45
S
17
G
37
Posts: 2,853
Reputation: 25,966

Post » Wed Jun 08, 2016 3:47 am

@Soldjahboy
Webgl doesn't get along with my PC so I'm not really working on shaders anymore.

The shader works by taking the source texture's alpha and making a colored silhouette. Then that is duplicated eight times and each one is moved in a different direction. The first to the right, the second down-right, the third down, and so on...

To make it outline multiple objects as if they were one object you need to Make them one image first. That's what layers do, so a layer per multi-part object could be one solution?

You could instead use the paster object. Basically by drawing each group of objects to their own paster instance and applying the outline effect to that.


I've become rusty with making shaders and since I can't test them I can't come up with ways to change the blend mode or opacity of them. However the outline can be done with the paster object without webgl and the end result is an the paster object will have the outline as a texture so you can draw it any way you'd like.

I'm not able to make a capx right now but here's how to do it:
First create a paster object and rename it outline. Make sure it's a little bigger than the object you want to draw and make it's origin centered.

For simplicity we'll outline a Sprite. The events would look like this:

Global number linewidth=4

Every tick
--- outline: clear to rgba(0,0,0,0)
--- outline: set quad color to rgba(0,0,0,1)

Repeat 8 times
--- outline: set position to Sprite
--- outline: move linewidth pixels at loopindex*45 degrees
--- outline: paste Sprite

Every tick
--- outline: set position to Sprite
--- Sprite: set blend mode to destination-out
--- outline: paste Sprite
--- Sprite: set blend mode to normal
--- outline: draw quad (0,0, 640,0, 640,480, 0,480) with blend mode destination-in


That should do it. The quad color is whatever color you want to use and when the quad is drawn on the paster with the destination-in blend it colors the outline. I was a tad lazy with the corners of the quad, it just needs to cover the outline object so you could use the bbox expressions instead. Anyways barring anything I overlooked that should give you a way to do a outline with the paster object. I'll try to make up a more re-useable example later.
B
79
S
24
G
54
Posts: 4,743
Reputation: 40,749

Post » Wed Jun 08, 2016 5:03 am

@R0J0hound

Thanks for the super detailed reply :) Massively helpful as always!

The problem I have with putting different "parts" on different layers is (again, the C2 bane of game making;) because of instance picking of the same objects. I used a container to get around my issues - since using loops to resolve the picking problems because very CPU intensive and I was getting major fps drop with only 15-20 characters (now I can make 60 or 70 before fps starts dropping). Anyway, the issue with having say, an arm or leg on another layer is;

Explaination: I have a "character" who is made up of several components - this "character" however is being created multiple times to create *every* character in the game. Think of it as a "blank" I guess, mannequin? These blank characters can be visualised differently using animations and specific frame settings - so one characters arm might have different colours to another. Changing the outline colour for the layer itself would obviously change the colour for all instances of the "arm" or whatever - which would mean everything would be the same outline colour regardless of intended design/colour. Each arm and leg is made of 10 segments (giving a "noodle" style appearance) with which I can change the appearance/colour/texture of any segment independently. I could have long sleeves or short sleeves for example - requiring a different coloured outline for multiple parts of the same "object".

I think paster may work for all intents and purposes, however I think it may over-complicate what I'm trying to do. I'm also not sure what impact (if any) it will have on performance since there can/will/may be up to 40-50 instances of a "character" present on-screen simultaneously at any given time.

I would just simply "bake" the outline into the graphical content itself, but since there is a form of zordering/rotation to the character, and the limbs are animated using qarp and lerp mathematics - baked outlines would subsequently appear "on top" of stuff that I don't want. If I made a 2nd sprite to match each instance in a container (always placed behind the character) to act as the outline... that would work - but I suspect the extra CPOU overhead for placing instances (to make sure the correct colours are being placed behind the corresponding parts) would cut my fps in half or more.

As is stands, the way my character "blank" is being created already chews up a fair bit of CPU time since it's running a qarp equation for 40 separate parts (per instance of the character) - and I'm not even sure that this will be suitable in the long run. Adding any extra loops (even for basic/simple placement or comparisons) that are related to the character already dramatically affect the performance.

My final resort would be to just ignore the idea of using an outline at all - but it's a look that I particularly like and being able to incorporate it in an elegant manner would be ideal.

Feel free to let me know if you have any thoughts about it - since you're a wizard and all that.

Don't stress about making an example cap though, unless you really want something to do to pass the time - I'm confident I can work out paster with the example pseudo-code you've supplied.

Much appreciated as always!

~Sol
Tired of crappy file hosts that are crappy? Get DROPBOX - https://db.tt/uwjysXJF
Moderator
B
45
S
17
G
37
Posts: 2,853
Reputation: 25,966

PreviousNext

Return to Effects

Who is online

Users browsing this forum: No registered users and 1 guest