[Added] Stipple (aka Dither) Shader

Moderator: GZDoom Developers

Re: Stipple (aka Dither) Shader

Postby Rachael » Mon Aug 06, 2018 3:27 pm

I honestly don't think this shader is going to impact 2D elements in any meaningful way. In its current form it's drawn after the 2D elements anyhow, as the very last step before the scaling, and I haven't seen anything look funky with the menu or the status bar as a result of using it.

Since I turn off filtering, I doubt that screenshots are going to even show usage of the shader anyhow, even forensically, on my 2D elements, since the dithering happens so close to the rounding cut-offs that they make no impact. You'll probably see them on the tween-texels for Linear filtering, but again, nothing too significant.
User avatar
Rachael
Webmaster
 
Joined: 13 Jan 2004
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Graphics Processor: nVidia with Vulkan support

Re: Stipple (aka Dither) Shader

Postby dpJudas » Mon Aug 06, 2018 3:36 pm

Graf Zahl wrote:The screen blend which is done as the first thing in the 2D pass.


The screen blend is ColormapScene, right? That's done as a PP pass today and not by the 2D drawer. It is only the software renderer that uses the 2D drawer for it (*). I haven't checked where Rachael hooked it up, but the 'scene' custom post process slot is after the CM has been applied.

*) The software renderer could also use a PP pass here with just a couple of lines changed.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Stipple (aka Dither) Shader

Postby dpJudas » Mon Aug 06, 2018 3:38 pm

Rachael wrote:I honestly don't think this shader is going to impact 2D elements in any meaningful way. In its current form it's drawn after the 2D elements anyhow, as the very last step before the scaling, and I haven't seen anything look funky with the menu or the status bar as a result of using it.

You will only see it in the case where there's translucency behind it or there's some kind of special render style or alpha blending going on. In all the other cases the 2D graphics matches 8 bpc perfectly.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Stipple (aka Dither) Shader

Postby Rachael » Mon Aug 06, 2018 3:43 pm

And if that's the case, then the dithering can only be of benefit in those areas anyhow, in my opinion, because it does exactly what it was designed to do: dither out the low colour resolution of 8bpc which will definitely be visible when using translucent textures, especially with gradients.
User avatar
Rachael
Webmaster
 
Joined: 13 Jan 2004
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Graphics Processor: nVidia with Vulkan support

Re: Stipple (aka Dither) Shader

Postby dpJudas » Mon Aug 06, 2018 3:46 pm

I agree with that. I only mention it because it is the thing most likely to draw the attention of the eye as HUD stuff is a lot more static and in a fixed location on the screen. I haven't actually tried it with your shader to see if it is a problem in practice. Graf's mention of UT99's horrible 16-bit dithering was what made me think of it. :)
dpJudas
 
 
 
Joined: 28 May 2016

Re: Stipple (aka Dither) Shader

Postby Graf Zahl » Mon Aug 06, 2018 3:48 pm

dpJudas wrote:
Graf Zahl wrote:The screen blend which is done as the first thing in the 2D pass.


The screen blend is ColormapScene, right?


No. I mean the DrawBlend call in d_main.cpp, line 775. This may, depending on the color, darken or brighten the scene quite significantly.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Stipple (aka Dither) Shader

Postby Rachael » Mon Aug 06, 2018 10:43 pm

Well this got merged into master (accidentally, admittedly, but it was improved upon afterward).

So I am going to throw this one into the developer forums since it's mainline now, anyhow.

All that needs to be done is for a uniform to be passed to it that informs it of the display's current colour resolution, and whether the user even wants the dithering in the first place. (It should be possible to disable it, if it's in as an internal feature, both for performance reasons, and because a user may not actually want it)
User avatar
Rachael
Webmaster
 
Joined: 13 Jan 2004
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle
Graphics Processor: nVidia with Vulkan support

Re: Stipple (aka Dither) Shader

Postby Chris » Tue Aug 07, 2018 12:58 am

I'm not sure where the right place to ask about this is, but I noticed something with the current dither matrix:
Code: Select allExpand view
float halfstep = 1./65.;
float DitherMatrix[64] = float[](
    0.0 / 16.0 + halfstep * 1,  8.0 / 16.0 + halfstep * 1,  2.0 / 16.0 + halfstep * 1, 10.0 / 16.0 + halfstep * 1,
    0.0 / 16.0 + halfstep * 3,  8.0 / 16.0 + halfstep * 3,  2.0 / 16.0 + halfstep * 3, 10.0 / 16.0 + halfstep * 3,
   12.0 / 16.0 + halfstep * 1,  4.0 / 16.0 + halfstep * 1, 14.0 / 16.0 + halfstep * 1,  6.0 / 16.0 + halfstep * 1,
   12.0 / 16.0 + halfstep * 3,  4.0 / 16.0 + halfstep * 3, 14.0 / 16.0 + halfstep * 3,  6.0 / 16.0 + halfstep * 3,
    3.0 / 16.0 + halfstep * 1, 11.0 / 16.0 + halfstep * 1,  1.0 / 16.0 + halfstep * 1,  9.0 / 16.0 + halfstep * 1,
    3.0 / 16.0 + halfstep * 3, 11.0 / 16.0 + halfstep * 3,  1.0 / 16.0 + halfstep * 3,  9.0 / 16.0 + halfstep * 3,
   15.0 / 16.0 + halfstep * 1,  7.0 / 16.0 + halfstep * 1, 13.0 / 16.0 + halfstep * 1,  5.0 / 16.0 + halfstep * 1,
   15.0 / 16.0 + halfstep * 3,  7.0 / 16.0 + halfstep * 3, 13.0 / 16.0 + halfstep * 3,  5.0 / 16.0 + halfstep * 3,
    0.0 / 16.0 + halfstep * 4,  8.0 / 16.0 + halfstep * 4,  2.0 / 16.0 + halfstep * 4, 10.0 / 16.0 + halfstep * 4,
    0.0 / 16.0 + halfstep * 2,  8.0 / 16.0 + halfstep * 2,  2.0 / 16.0 + halfstep * 2, 10.0 / 16.0 + halfstep * 2,
   12.0 / 16.0 + halfstep * 4,  4.0 / 16.0 + halfstep * 4, 14.0 / 16.0 + halfstep * 4,  6.0 / 16.0 + halfstep * 4,
   12.0 / 16.0 + halfstep * 2,  4.0 / 16.0 + halfstep * 2, 14.0 / 16.0 + halfstep * 2,  6.0 / 16.0 + halfstep * 2,
    3.0 / 16.0 + halfstep * 4, 11.0 / 16.0 + halfstep * 4,  1.0 / 16.0 + halfstep * 4,  9.0 / 16.0 + halfstep * 4,
    3.0 / 16.0 + halfstep * 2, 11.0 / 16.0 + halfstep * 2,  1.0 / 16.0 + halfstep * 2,  9.0 / 16.0 + halfstep * 2,
   15.0 / 16.0 + halfstep * 4,  7.0 / 16.0 + halfstep * 4, 13.0 / 16.0 + halfstep * 4,  5.0 / 16.0 + halfstep * 4,
   15.0 / 16.0 + halfstep * 2,  7.0 / 16.0 + halfstep * 2, 13.0 / 16.0 + halfstep * 2,  5.0 / 16.0 + halfstep * 2
);

The thing that strikes me is that all these values are between 0 and 1. So when applied to the scene, the resulting pixel will only ever be greater than it's original value. As I understand it, dither is essentially a uniform distribution of random values between -1 and +1, so that it hides quantization error and the overall change is 0. By being between 0 and 1, it raises the overall image brightness since values only ever increase. Shouldn't the dither values be between -1 and +1 to avoid raising the overall brightness?
User avatar
Chris
 
Joined: 17 Jul 2003

Re: Stipple (aka Dither) Shader

Postby dpJudas » Tue Aug 07, 2018 3:41 am

Chris wrote:The thing that strikes me is that all these values are between 0 and 1. So when applied to the scene, the resulting pixel will only ever be greater than it's original value. As I understand it, dither is essentially a uniform distribution of random values between -1 and +1, so that it hides quantization error and the overall change is 0. By being between 0 and 1, it raises the overall image brightness since values only ever increase. Shouldn't the dither values be between -1 and +1 to avoid raising the overall brightness?

You're right the distribution should be uniform around zero. The reason the values are higher is because the rounding is baked into the value. The full code looks like this:

Code: Select allExpand view
vec4 Dither(vec4 c, float colorscale)
{
   ivec2 pos = ivec2(gl_FragCoord.xy) & 7;
   float threshold = DitherMatrix[pos.x + (pos.y << 3)];
   return vec4(floor(c.rgb * colorscale + threshold) / colorscale, c.a);
}

The floor() and the colorscale effectively converts this into doing integer math with floating point. If the values in DitherMatrix are balanced around 0 then it needs a +0.5 for the rounding to be correct.

Whether it is actually still uniformly distributed even when taking that into account I'm not 100% sure. This table fiddling was done in the middle of the night by me and Rachael - there's certainly the possibility we did some error when typing in the table.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Stipple (aka Dither) Shader

Postby Chris » Tue Aug 07, 2018 4:55 am

dpJudas wrote:The floor() and the colorscale effectively converts this into doing integer math with floating point. If the values in DitherMatrix are balanced around 0 then it needs a +0.5 for the rounding to be correct.

Oh, right. Missed that. Though in that case, that would mean the dither values effectively goes between -0.5 and +0.5 rather than -1 and +1. Maybe that's preferred for image dithering, though.
User avatar
Chris
 
Joined: 17 Jul 2003

Re: Stipple (aka Dither) Shader

Postby Marisa Kirisame » Tue Aug 07, 2018 8:14 am

Wouldn't it be more efficient to use a texture for the dither pattern rather than an array?
User avatar
Marisa Kirisame
ZScript Magician
 
 
 
Joined: 08 Feb 2008
Location: Vigo, Galicia
Discord: Marisa Kirisame#4689
Twitch ID: magusmarisa
Github ID: OrdinaryMagician
Operating System: Other Linux 64-bit
Graphics Processor: nVidia with Vulkan support

Re: Stipple (aka Dither) Shader

Postby dpJudas » Tue Aug 07, 2018 8:31 am

I have no idea. Might depend on the GPU architecture (the older the more likely you'll be right). The static array will be uploaded to local memory of the shader workgroup when the shader runs, so the lookup should be pretty fast. Is it faster than using the texture unit? I'm not volunteering coding a test for that as it requires a lot more effort to set up. Currently it is all embedded in the shader itself.
dpJudas
 
 
 
Joined: 28 May 2016

Re: Stipple (aka Dither) Shader

Postby Graf Zahl » Tue Aug 07, 2018 9:39 am

I'd say no. As it is it's just some direct memory access of a simple array but no matter how a texture is set up, there has to be more logic attached - it has to query the sampler for its settings plus the texture for its data to get a value out.
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

Re: Stipple (aka Dither) Shader

Postby Marisa Kirisame » Tue Aug 07, 2018 10:04 am

Sometimes I forget that GLSL is more sane than HLSL.
User avatar
Marisa Kirisame
ZScript Magician
 
 
 
Joined: 08 Feb 2008
Location: Vigo, Galicia
Discord: Marisa Kirisame#4689
Twitch ID: magusmarisa
Github ID: OrdinaryMagician
Operating System: Other Linux 64-bit
Graphics Processor: nVidia with Vulkan support

Re: Stipple (aka Dither) Shader

Postby Graf Zahl » Tue Aug 07, 2018 1:08 pm

Is it? What made you think about efficiency here?
User avatar
Graf Zahl
Lead GZDoom Developer
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

PreviousNext

Return to Closed Feature Suggestions

Who is online

Users browsing this forum: No registered users and 3 guests