Need help with a Shader - coordinate weirdness [2nd post]

Share your Construct 2 effect files

Post » Sat Feb 07, 2015 6:30 pm

Hi, shaderheads!

I have been learning my way around shaders, but all this premultiplied alpha business is still going over my head.

Here's what I want to do - make an "inline" effect - base the brightness of a given pixel on the inverse alpha value of nearby pixels. My code looks like this at the moment:

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

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

void main(void)
{
   lowp vec4 front = texture2D(samplerFront, vTex);
   
    float A = 1.0 - texture2D(samplerFront, vTex + vec2(0, pixelHeight)).a;
   float B = 1.0 - texture2D(samplerFront, vTex + vec2(0, -pixelHeight)).a;
   float C = 1.0 - texture2D(samplerFront, vTex + vec2(pixelWidth, 0)).a;
   float D = 1.0 - texture2D(samplerFront, vTex + vec2(-pixelWidth, 0)).a;
   
    float M = clamp(A+B+C+D,0.0,1.0);

   front.rgb = vec3(M,M,M);
   
   gl_FragColor = front;
}


But the values don't work out the way one might expect. What needs to be done so we basically keep the same alpha of the original image AND change the pixel colors?
Last edited by Somebody on Mon Feb 09, 2015 6:51 am, edited 2 times in total.
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Sun Feb 08, 2015 8:32 am

All right, after doing some research (basically reading some other posts here) it looks like I managed to make a working version:

Code: Select all
/////////////////////////////////////////////////////////
// Selection inline effect
//
varying lowp 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 float Alpha = texture2D(samplerFront, vTex).a;
   
    lowp float A = 1.0 - texture2D(samplerFront, vTex + vec2(0.0, pixelHeight*width)).a;
   lowp float B = 1.0 - texture2D(samplerFront, vTex + vec2(0.0, -pixelHeight*width)).a;
   lowp float C = 1.0 - texture2D(samplerFront, vTex + vec2(pixelWidth*width, 0.0)).a;
   lowp float D = 1.0 - texture2D(samplerFront, vTex + vec2(-pixelWidth*width, 0.0)).a;
   
    lowp float M = clamp(A+B+C+D,0.0,1.0);
   
   gl_FragColor = vec4(vec3(M,M,M)*Alpha,Alpha);
}


Initially it works just as expected:
Image

But should the sprite be moved strange artefacts appear:
Image

And if it's rotated forward and back the artefacts get even worse:
Image

I tried changing all the precision settings, but it didn't help. Perhaps someone can explain why this is happening? Perhaps that someone could be @Ashley (I realise you are very busy, but I really would like to understand the Shader behaviour). I'm attaching the Shader itself for easier testing if necessary.
You do not have the required permissions to view the files attached to this post.
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Sun Feb 08, 2015 8:42 am

It looks like you need to premultiply by your calculated alpha value M, not the original alpha value from the pixel.
Scirra Founder
B
362
S
216
G
75
Posts: 23,067
Reputation: 180,321

Post » Sun Feb 08, 2015 8:51 am

But I need to keep the same Alpha as the original image - only change the colours. If I multiply with the calculated alpha then everything gets filled, which isn't desired:
Image

Besides if the sprite is moved the same artefacts appear:
Image
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Sun Feb 08, 2015 11:07 am

Here's an additional demonstration - could it be that either the pixelWidth and pixelHeight values are acting weird or something is equally weird with alpha when a sprite is moved?

Image

In theory the sprite gets moved exactly a given amount of pixels - 128 or 64 or so. As we see the effect acts different when a sprite is moved somewhere and then comes back. Any idea why that is?

I would do further research, but since there's no way to debug a Shader I have to ask here...

Edit: More info:
The strangeness happens if there is any other Shader present - it seems as if having a different Shader in the stack also "adds" some extra space around the sprite, even without the expand properties being used - here's the "inline" with a Shader in the stack: http://i.imgur.com/XVNqScz.png - it seems like it is able to "detect" the surrounding pixels and properly mark the inside of the sprite since there's 0 alpha around.

And without any other Shader it looks like this - http://i.imgur.com/LXMbyP5.png - nothing is drawn since, apparently, the Shader cannot read the 0 alpha from outside of the sprite bounds.
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Sun Feb 08, 2015 4:22 pm

Looks like subpixel interpolation to me. No way around that.
You might see what it looks like in other browsers however.
Image Image
B
163
S
48
G
99
Posts: 7,435
Reputation: 71,492

Post » Tue Feb 10, 2015 7:51 am

Shameless bump in the hopes that @Ashley might shed some light on why the results differ seemingly randomly...
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Tue Feb 10, 2015 1:32 pm

I don't know, can you reproduce it on other systems or browsers? It looks like the type of glitch which sometimes comes down to a driver quirk or some aspect of ANGLE (Chrome/Firefox's WebGL wrapper - IE11 uses a different engine)
Scirra Founder
B
362
S
216
G
75
Posts: 23,067
Reputation: 180,321

Post » Tue Feb 10, 2015 1:42 pm

Ashley wrote:I don't know, can you reproduce it on other systems or browsers? It looks like the type of glitch which sometimes comes down to a driver quirk or some aspect of ANGLE (Chrome/Firefox's WebGL wrapper - IE11 uses a different engine)


Thanks for the reply - so far I have tested on Chrome/Firefox on two different systems and the weird behaviour is present on both. Will try IE11.

Since it uses the PixelWidht and PixelHeight values - is there a slim chance that those get iffy somewhere along the way?
B
19
S
6
G
6
Posts: 1,101
Reputation: 5,646

Post » Tue Feb 10, 2015 1:58 pm

You should test on as many WebGL-supporting browsers as possible as your very first port of call. This is all essential information and without that we can only speculate.
Scirra Founder
B
362
S
216
G
75
Posts: 23,067
Reputation: 180,321

Next

Return to Effects

Who is online

Users browsing this forum: No registered users and 1 guest