The Daily Click ::. Forums ::. Digital Works ::. Dithering Experiment (Pixel shaders)
 

Post Reply  Post Oekaki 
 

Posted By Message

Sketchy

Cornwall UK

Registered
  06/11/2004
Points
  1970

VIP MemberWeekly Picture Me This Round 43 Winner!Weekly Picture Me This Round 47 WinnerPicture Me This Round 49 Winner!
9th September, 2014 at 09/09/2014 11:50:03 -

I've been experimenting with pixel shaders again...
This time, I wanted to make a shader that could create a dithering effect. Unfortunately, I can't figure out any way to handle a full color palette, so I'm limited to greyscale.
Still, if you ever dreamed of making a grainy, atmospheric film-noire style game, but with gameboy style graphics, maybe this could help?

Note: Click on images to see them full size.


Original image:
Image

With ordered dithering:
Image

A Gameboy game with lighting effects? (graphics not by me)
Image


Pixel shader download: http://1drv.ms/1qILfOY

Edited by Sketchy

 
n/a

Pan-tosser



Registered
  24/10/2008
Points
  520

Has Donated, Thank You!
9th September, 2014 at 09/09/2014 15:37:27 -

Your shader did a great job. Lots of time dithering can create to many artifacts with in the picture.

 
https://www.facebook.com/nathon.brown.7

Sketchy

Cornwall UK

Registered
  06/11/2004
Points
  1970

VIP MemberWeekly Picture Me This Round 43 Winner!Weekly Picture Me This Round 47 WinnerPicture Me This Round 49 Winner!
9th September, 2014 at 09/09/2014 18:13:11 -

Yeah, it worked out okay, but it's a bit "messy" looking, I think.
It seems to make quite a big difference which patterns you use - in some cases, the pattern becomes far more noticeable, but it also makes the image look "cleaner" somehow.
For example:

Image

Image

Image

Image



 
n/a

The_Antisony

At least I'm not Circy

Registered
  01/07/2002
Points
  1341

VIP MemberStarSnow
10th September, 2014 at 10/09/2014 00:54:49 -

Image
I kind of like how it looks a little messy and disorganized.

Image
This one is interesting, too. I think that out of all of them, this one looks the cleanest, but it also texturizes everything. Considering the shader will probably be most useful in a 8-bit grayscale game, the pixel-y look is an advantage. As always, awesome work Sketchy!


Edited by The_Antisony

 
ChrisD> Employer: Say, wanna see a magic trick?
ChrisD> Employee: Uhh… sure, boss.
ChrisD> Employer: Your job! It just disappeared! Pack your things and leave! Pretty good trick, huh?

s-m-r

Slow-Motion Riot

Registered
  04/06/2006
Points
  1078

Candle
10th September, 2014 at 10/09/2014 01:39:40 -

Yes, this all looks fantastic, Sketchy!

 
n/a

Sketchy

Cornwall UK

Registered
  06/11/2004
Points
  1970

VIP MemberWeekly Picture Me This Round 43 Winner!Weekly Picture Me This Round 47 WinnerPicture Me This Round 49 Winner!
12th September, 2014 at 12/09/2014 04:15:10 -

Thanks
Not sure how useful any of this will turn out to be though...
Anyway, here's the last few:

Random noise:
Image

Horizontal lines:
Image

Obama-fication
Image

 
n/a

Sketchy

Cornwall UK

Registered
  06/11/2004
Points
  1970

VIP MemberWeekly Picture Me This Round 43 Winner!Weekly Picture Me This Round 47 WinnerPicture Me This Round 49 Winner!
26th May, 2016 at 26/05/2016 15:31:32 -

I've made another shader...
This time, it simulates alpha channel transparency using uniform dithering - potentially useful if you want quick and easy fading/transparency effects in a retro styled game, where the real thing would look too modern and out of place.

Opacity can vary in increments of 1/8th, and can use the object's own alpha channel (eg. if the object is to fade gradually at the edges), or a single adjustable value (eg. if the whole object is to fade over time), or a combination of the two.

Download: https://onedrive.live.com/redir?resid=B1E7EE094271BBDA!668&authkey=!AL0atbthZHCrKLM&ithint=file%2czip

Image

Edited by Sketchy

 
n/a

Sketchy

Cornwall UK

Registered
  06/11/2004
Points
  1970

VIP MemberWeekly Picture Me This Round 43 Winner!Weekly Picture Me This Round 47 WinnerPicture Me This Round 49 Winner!
28th May, 2016 at 28/05/2016 14:03:56 -

I fixed a bug with 50% dithering, so if anyone downloaded it before, they will need to get the fixed version from here:
https://onedrive.live.com/redir?resid=B1E7EE094271BBDA!668&authkey=!AL0atbthZHCrKLM&ithint=file%2czip

Image

Edited by Sketchy

 
n/a

nim



Registered
  17/05/2002
Points
  7233
29th May, 2016 at 29/05/2016 16:19:35 -

This is great, Sketchy. Really nice work, and thanks for making it available. I love this effect, especially when it's applied to 3D objects in games.

 
//

Fifth

Quadruped

Registered
  07/05/2003
Points
  5815

VIP MemberGOTW JULY 2010 WINNER!Kliktober Special Award TagGOTW HALLOWEEN 2011 WINNERPicture Me This Round 51 Winner!
1st June, 2016 at 01/06/2016 08:16:18 -

Ooh man, that's really cool! Is this using a sort of multi-step dither-map like the color-based ones?

 
Go Moon!

Sketchy

Cornwall UK

Registered
  06/11/2004
Points
  1970

VIP MemberWeekly Picture Me This Round 43 Winner!Weekly Picture Me This Round 47 WinnerPicture Me This Round 49 Winner!
1st June, 2016 at 01/06/2016 14:04:40 -

Thanks
Yes, it works in basically the same way, except that the old dithering shader got the pattern by sampling from an image, while this version just stores the pattern as an array inside the shader itself, which is simpler and ought to be much more efficient. And of course, the pattern is selected based on the source alpha rather than its lightness.

sampler2D img;

int width, height;
float alpha;

int4x4 ptn1 = { 0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 0,
1, 0, 0, 0 };

int4x4 ptn2 = { 1, 0, 1, 0,
0, 0, 0, 0,
1, 0, 1, 0,
0, 0, 0, 0 };

int4x4 ptn3 = { 0, 0, 1, 0,
0, 1, 0, 1,
1, 0, 0, 0,
0, 1, 0, 1 };

int4x4 ptn5 = { 1, 1, 0, 1,
1, 0, 1, 0,
0, 1, 1, 1,
1, 0, 1, 0 };

int4x4 ptn6 = { 0, 1, 0, 1,
1, 1, 1, 1,
0, 1, 0, 1,
1, 1, 1, 1 };

int4x4 ptn7 = { 1, 1, 1, 1,
1, 1, 0, 1,
1, 1, 1, 1,
0, 1, 1, 1 };


float4 ps_main(in float2 In : TEXCOORD0) : COLOR0 {
float4 pixel = tex2D(img,In);
float xIn = (In.x * width) % 4;
float yIn = (In.y * height) % 4;
float pattern = round(pixel.a * alpha * 8.0);
pixel.a = 1;
if (pattern == 0) { pixel.a = 0; }
else if (pattern == 1) { pixel.a = ptn1[xIn][yIn]; }
else if (pattern == 2) { pixel.a = ptn2[xIn][yIn]; }
else if (pattern == 3) { pixel.a = ptn3[xIn][yIn]; }
else if (pattern == 4) { pixel.a = abs(((xIn % 2) - (yIn % 2))); }
else if (pattern == 5) { pixel.a = ptn5[xIn][yIn]; }
else if (pattern == 6) { pixel.a = ptn6[xIn][yIn]; }
else if (pattern == 7) { pixel.a = ptn7[xIn][yIn]; }

return pixel;
}

technique tech_main { pass P0 { PixelShader = compile ps_2_a ps_main(); } }


Each "int4x4" (or "float4x4" in previous versions) is an array representing a 4x4 pattern of pixels, where 0 = transparent, and 1 = opaque.
The 50% pattern is handled a little differently, just because the limitations of pixel shaders in MMF2 made it impossible to have that many arrays, and a 50% pattern is the easiest to calculate using just maths.
I have a feeling there is still room to simplify it quite a bit...

 
n/a

Fifth

Quadruped

Registered
  07/05/2003
Points
  5815

VIP MemberGOTW JULY 2010 WINNER!Kliktober Special Award TagGOTW HALLOWEEN 2011 WINNERPicture Me This Round 51 Winner!
2nd June, 2016 at 02/06/2016 00:38:10 -

Ah, that makes sense.
I guess if you wanted to simplify things, you could use a single array that kind of combines the different patterns at different levels. As long as any one pixel only goes from 0 to 1 as opacity changes (and not like, 0 -> 1 -> 0 -> 1), then you can put together something that encompasses all the different opacity levels, and just pick whatever value you're at as a threshold.

Something like this might work:

int4x4 ptn1 = {  4, 12,  6, 14,

8, 0, 10, 2,
7, 15, 5, 13,
11, 3, 9, 1 };


Edited by Fifth

 
Go Moon!
   

Post Reply



 



Advertisement

Worth A Click