Topic: [Feature] Gamma Correction On Front Page Elements

Posted under Site Bug Reports & Feature Requests

Requested feature overview description.
Use SVG filters on certain elements of the front page to implement gamma correct text rendering, backdrop blurring, and/or background image alpha blending.

Why would it be useful?
It would improve the appearance of various elements by providing more realistic blurring, clearer and smoother text (especially since it's light text on a dark background), and — in the case of the background image's alpha blending — greatly improve how semi-transparent items blend against the background.

The lattermost is especially apparent with the Christmas season's mascot image; the lack of gamma correct alpha blending is causing the red 'glow' around the lights on the smol Christmas tree to actually look darker than the surrounding background color!

In fact, I've actually taken the liberty of (sort of) implementing this for you. Only 'sort of' because I was trying my best to keep it compatible with the existing HTML/CSS on the front page, so that the <svg> and <style> elements can just be tacked on at the end of the <body> tag. To do this properly, you'd probably want to rework the CSS and maybe some of the HTML as well.

Also, the code uses the CSS backdrop-filter property, which until recently didn't work on Firefox. There's actually an easier way to write the code I wrote, but it causes Firefox to bug out (or at least, the Linux version of Firefox does), so I've opted to just use a workaround. Both variations work fine in Chrome and its derivatives.

Code I've Implemented
<svg xmlns="http://www.w3.org/2000/svg" style="width: 0; height: 0; position: fixed; visibility: hidden;">
	<filter id="toLin" color-rendering="optimizeQuality" color-interpolation-filters="sRGB">
		<feComponentTransfer>
			<feFuncR type="gamma" amplitude="1" exponent="2.2" offset="0"></feFuncR>
			<feFuncG type="gamma" amplitude="1" exponent="2.2" offset="0"></feFuncG>
			<feFuncB type="gamma" amplitude="1" exponent="2.2" offset="0"></feFuncB>
		</feComponentTransfer>
	</filter>
	<filter id="toGam" color-rendering="optimizeQuality" color-interpolation-filters="sRGB">
		<feComponentTransfer>
			<feFuncR type="gamma" amplitude="1" exponent="0.4545454545454545" offset="0"></feFuncR>
			<feFuncG type="gamma" amplitude="1" exponent="0.4545454545454545" offset="0"></feFuncG>
			<feFuncB type="gamma" amplitude="1" exponent="0.4545454545454545" offset="0"></feFuncB>
		</feComponentTransfer>
	</filter>
</svg>
<style>
	/* Various colors need to be in linear light from the start. I could've
	   just used 'filter: url("#toLin")', but that'd remove subpixel AA */
	a, a:link, a:visited {
		color: #7794B3;
	}

	.mascotbox input:focus, .mascotbox select:focus, .mascotbox textarea:focus {
		background-color: #FFFF9C;
	}

	/* The below works better and is more performant, but has rendering bugs
	   on the Linux version of Firefox */
	/*.mascotbox {
		background-image: none !important;
		background-color: transparent !important;
	}

	.mascotbox::before {
		backdrop-filter: url('#toLin');
		filter: blur(8px);
	}/**/

	/* This version is slower when you have to scroll (such as when using a
	   small browser window), but works far more consistently */
	.mascotbox::before {
		top: -24px;
		left: -24px;
		width: calc(100% + 48px);
		height: calc(100% + 48px);
		filter: url('#toLin') blur(8px);
	}/**/

	/* The gamma correction causes the text shadows to be much lighter, so
	   to compensate for that I perform both text shadows 2.2 times (since
	   I use a gamma of 2.2) */
	.mascotbox {
		text-shadow: 0 0 2px black, 0 0 2px black, 0 0 2px #00000033,
		             0 0 6px black, 0 0 6px black, 0 0 6px #00000033;
	}

	.mascotbox img {
		filter: url('#toLin');
	}

	/* Use of backdrop-filter lets Firefox keep subpixel antialiasing, so I
	   create an element that covers each box and gamma corrects it */
	.mascotbox::after {
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		pointer-events: none;
		backdrop-filter: url('#toGam');
	}


	/**************************************************
	 * Background Image Transparency Gamma Correction *
	 **************************************************/

	html {
		background: #000618;
		backdrop-filter: url(#toLin);
	}

	html::before {
		content: '';
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		pointer-events: none;
		background: url('https://static1.e621.net/data/mascots/7500bdb80bdc353585896fa8a9aaabd3.png') fixed no-repeat 50% 0;
		filter: url(#toLin);
	}

	body {
		background-image: none !important;
		background-color: transparent !important;
	}

	body::before {
		content: '';
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		pointer-events: none;
		backdrop-filter: url(#toGam);
	}
</style>
How To Try For Yourself
Firefox
  • First, press F12 to open up the developer tools, and click on the 'Inspector' tab (if it's not already the current tab).
  • Right-click the <body> tag (should be selected by default already, so you shouldn't have to hunt it down), and click 'Create New Node' in the menu.
  • Right-click the new <div></div> that appeared at the bottom (the moment it's created, it'll be highlighted in pale yellow for about a second), and click 'Edit As HTML'. It will turn into an editable text field with only <div></div> in it.
  • Delete the <div></div> text, and replace it with all of the code in the above section.
  • Click on the blank area next to the text box to apply the changes.
Chrome
  • First, press F12 to open up the developer tools, and click on the 'Elements' tab (if it's not already the current tab).
  • Chrome doesn't have a 'Create New Node' feature, but e621's existing HTML has an empty div at the very bottom of the <body> element, with a role="status" property. Right-click it and click 'Edit as HTML'.
  • Move the cursor to the end of the appearing text box (you can use your mouse, press the 'End' key on your keyboard, hold down the right arrow key on your keyboard, or any other method you prefer), press 'Enter' to make a new line, and paste the above code into the box after the existing <div>. Don't delete the div, as it's intended to be there.
  • Click on the blank area next to the text box to apply the changes.

Note: the SVG and CSS both go together into the same box, one right after the other. Literally just copy all the contents of the code block in the previous section, and paste everything you copied into the text box.

Note: I actually wrote most of that code months ago, and didn't notice the problems with background image transparency. That particular problem became most pronounced when e621 decided to force the mascot image for the Christmas season (which I don't mind, honestly; it's a cute, and fitting, picture), which inspired me to tack on the stuff at the end. Everything after the Background Image Transparency Gamma Correction comment is new and specific to that (which is also why it hard-codes the background image URL).

Because I hadn't planned that from the start, I haven't yet figured out how to get the blurred version of the background image to also have gamma-correct alpha blending. However, I do know what I'd do if I were to approach this 'from scratch':

  • Use a combination of the #toLin filter and manually computed color values to turn everything on the page into linear light values,
  • Use backdrop-filter for the blur effect from the very start (which was avoided in your original code due to backdrop-filter not working in most browsers until very recently), and finally
  • Have an empty div (or use body::after) that uses #toGam across the entire page, gamma-correcting all of it with backdrop-filter.

If you want to only get the mascot to have gamma-correct alpha blending (so that the fire doesn't have a pale green glow, and the red Christmas tree lights don't glow with an ominous darkness that threatens reality), you can get rid of all the CSS that comes before the Background Image Transparency Gamma Correction comment (though the SVG at the start is still required).

What part(s) of the site page(s) are affected?
Front page

  • 1