claygraffix Posted June 17, 2020 Share Posted June 17, 2020 Hi all, i've been messing with something for a couple days. I'm passing in a transparent blurred PNG to a shader, as well as a solid PNG background, and running it through a grayscale shader. If I simply display the pixels of the blurred PNG, it is output on top of the solid background as expected. The grayscale part of the shader works fine. However, the grayscale portion of the photo has a harsh transition to the background. It doesn't fade nicely and follow the alpha of the blurred PNG, like a blendMode would. I realize they are different things, but I feel like I am missing something obvious, and that it should work as I'm expecting. I have a playground setup to demonstrate the issue. Ignore the ugliness of the assets, it gets the point across better https://www.pixiplayground.com/#/edit/0ZaLP0UrUIPKfyHU_S3-o In the photo attached, the desired result is on the left (from Photoshop Color BlendMode). The right is the result from the playground. You can tell that the grayscale area on the right is much larger, since I believe that any alpha that is NOT 0, it being set to 1. I would like to try and maintain the alpha from the original blurred PNG. It may not seem like much but it really kills what I'm going for with the aliased edge like that. Thank you! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted June 17, 2020 Share Posted June 17, 2020 grayMask = 0.299 * target.r + 0.587 * target.g + 0.114 * target.b just for your knowledge, those values (r g b) are premultiplied by alpha in pixi, so this gray is actually gray*target.a. Yet it should work because you need premultiplied color in "grayed" the real fix is here, its usual normal blendmode: gl_FragColor = source * (1.0 - grayed.a) + grayed; Quote Link to comment Share on other sites More sharing options...
claygraffix Posted June 17, 2020 Author Share Posted June 17, 2020 Hi, I tried putting this in the playground and it looks like the same result. The same as the image attached above on the right side. gl_FragColor = source * (1.0 - grayed.a) + grayed; I've tried playing around and I can get the solid border to shrink if I check for the alpha == 1, then only return those pixels. This may be enough, but it's not optimal. if (source.a == 1.0) { gl_FragColor = source * (1.0 - grayed.a) + grayed; return; } Just can't get anything that is less than 1.0 alpha to really blend properly. I actually get the same result if it just returns only "grayed". Still hacking around in the playground! I greatly appreciate your response. Side note: the playgrounds are awesome... Quote Link to comment Share on other sites More sharing options...
claygraffix Posted June 17, 2020 Author Share Posted June 17, 2020 Ooooooh, I think I got it. Confirming when I put it in my actual project, will follow up! Quote Link to comment Share on other sites More sharing options...
claygraffix Posted June 17, 2020 Author Share Posted June 17, 2020 This did the trick, thanks! void main(void) { vec4 source = texture2D(color, vUvs); vec4 target = texture2D(base, vtestUvs); if (source.a > 0.0) { float grayMask = 0.299 * target.r + 0.587 * target.g + 0.114 * target.b; gl_FragColor = vec4(grayMask*source.a, grayMask*source.a, grayMask*source.a, source.a); } else { gl_FragColor = vec4(0, 0, 0, 0); } } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.