{"author_link":"\/users\/brusi","author_name":"Brusi","author_uid":"brusi","comments":[],"epoch":1620152495,"event":"LD48","format":"md","ldjam_node_id":256178,"likes":44,"metadata":{"p_key":"157656","p_author":"Brusi","p_authorkey":"1056661","p_urlkey":"377903","p_title":"Autumn Hike Dithering Explained","p_cat":"LDJam ","p_event":"LD48","p_time":"1620152495","p_likes":"44","p_comments":"0","p_status":"WAYBACK","us_key":"1056661","us_name":"Brusi","us_username":"brusi","event_start":"1619222400","event_key":"109","event_name":"Ludum Dare 48"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD48","removed_author":false},"_superparent":233335,"_trust":6,"author":56661,"body":"Hi everyone!  \nI wanted to talk a little bit about the dithering effect and shader I wrote for [our game Autumn Hike](https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike), why I wrote it and how I implemented it.\n\n## Our Game\n\n[Autumn Hike](https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike) is in 1-bit style, meaning that this game is low-res, and has only two colors, black and white.\n\n![1.png](\/\/\/raw\/55d\/d\/z\/42270.png)\n\nAccording to the \"deeper and deeper\" theme, protagonist Mr. Snail can enter some small spaces, which are then zoomed in to the entire screen.\n\n## The Problem\n\nIn the first released version, the zoom-in effect looked like this:\n\n![enter_1.gif](\/\/\/raw\/55d\/d\/z\/42271.gif)\n\nI think it looked quite neat, and communicated well the fact that you got inside this small area that now takes the entire screen.\n\nHowever, something still bothered me - our game is black-and-white, but in this transition effect we use transparency, resulting in gray pixels! Take, for example, this intermediate frame between two screens:\n\n![mid_way_transition.png](\/\/\/raw\/55d\/d\/z\/42272.png)\n\nIt has different grayscale colors all over the place, which breaks the consistency of the style, and would not be possible in the imaginary gameboy-like device on which our game runs (at least that we aimed for...)\n\n## The Solution - Dithering!\n\nTo keep this effect and still use only two colors, I wanted to implement *dithering*, which is a method that allows expressing a scale between two colors, using only pixels of these two colors (in this - all grays between black and white).\n\n![Michelangelo's_David_-_Floyd-Steinberg[1].png](\/\/\/raw\/55d\/d\/z\/42274.png)\n\n## Implementation\n\nI implemented it by writing a simple screen-space shader, which takes the current screen \"output\" of the game, and overrides it with calculations based on the current pixels. I was using Godot game engine, but this method is possible with every modern engine.\n\nThe implementation goes roughly like this:\n- Divide the screen to pixels based on the game's resolution\n- Divide all pixels to 4x4 squares\n- For each of the 16 pixels in the square, set a different [0.0 to 1.0] \"threshold\". If the \"original\" color in darker than the threshold, final color would be black; otherwise it would be white. I chose thresholds of 1\/16, 2\/16, 3\/16, ... 16\/16 and scattered them in a nice pattern inside the 4x4 square.\n\nThat's it, actually.\n\nChoosing different thresholds for different pixels in each 4x4 square makes sure that lighter gray colors would \"paint\" more pixels white and less black; while a darker color would paint more pixels \"black\" and less \"white\", resulting in the overall impression of a darker color while still using only two colors.  \nNeedless to say, a \"completely\" white input (value 1) is above the threshold of all pixels in the square, and would result in the same white square. Similarly with black (value 0).\n\nThe pattern I chose is the following, with the goal of having similar-colored pixels as far away from each other as I can, to make it look more \"scattered\":\n\n![pattern.png](\/\/\/raw\/55d\/d\/z\/42276.png)\n\nSquare 1 has the threshold of 1\/16, square 2 has 2\/16 etc. Note that a 50% gray would paint only 1-8 squares white (because it is above (or equals, in that case) 1\/16 to 8\/16), and would result in a nice checkers-board pattern.\n\nI could have chose any other pattern, but I think this one fit best the theme of the game.\n\n## Results\n\nThis grayscale gradient ![gradient.png](\/\/\/raw\/55d\/d\/z\/42277.png) would become this after applying the shader: ![dither_gradient.png](\/\/\/raw\/55d\/d\/z\/42278.png)\n\nThis is how it looks like, zoomed in around the center (see the \"checkers board\" pattern around the 50% gray): ![dither_zoomed.PNG](\/\/\/raw\/55d\/d\/z\/42279.png)\n\n## Before and after:\n### Before\n![enter_1.gif](\/\/\/raw\/55d\/d\/z\/4227c.gif)\n### After\n![enter_dither.gif](\/\/\/raw\/55d\/d\/z\/4227d.gif)\n(I like how the environment \"dissolves\" when switching to a new area)\n\nWhat do you think? Do you like the new dithering or do you prefer the previous look?  \nPlease let us know if the post was helpful for you! And don't forget to [play Autumn Hike](https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike)!\n\nThanks,  \nOri and Autumn Hike team :)","comments":4,"comments-timestamp":"2021-05-04T19:58:23Z","created":"2021-05-04T17:34:40Z","files":[],"files-timestamp":0,"id":256178,"love":44,"love-timestamp":"2021-05-09T13:26:22Z","meta":[],"modified":"2021-05-09T13:26:22Z","name":"Autumn Hike Dithering Explained","node-timestamp":"2021-05-04T18:29:22Z","parent":246841,"parents":[1,5,9,233335,246841],"path":"\/events\/ludum-dare\/48\/autumn-hike\/autumn-hike-dithering-explained","published":"2021-05-04T18:21:35Z","scope":"public","slug":"autumn-hike-dithering-explained","subsubtype":"","subtype":"","type":"post","version":787928},"node_metadata":{"n_key":"256178","n_urlkey":"377903","n_parent":"246841","n_path":"\/events\/ludum-dare\/48\/autumn-hike\/autumn-hike-dithering-explained","n_slug":"autumn-hike-dithering-explained","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"56661","n_created":"1620149680","n_modified":"1620566782","n_version":"787928","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike\/autumn-hike-dithering-explained","text":"Hi everyone!  \nI wanted to talk a little bit about the dithering effect and shader I wrote for [our game Autumn Hike](https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike), why I wrote it and how I implemented it.\n\n## Our Game\n\n[Autumn Hike](https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike) is in 1-bit style, meaning that this game is low-res, and has only two colors, black and white.\n\n![1.png](\/\/\/raw\/55d\/d\/z\/42270.png)\n\nAccording to the \"deeper and deeper\" theme, protagonist Mr. Snail can enter some small spaces, which are then zoomed in to the entire screen.\n\n## The Problem\n\nIn the first released version, the zoom-in effect looked like this:\n\n![enter_1.gif](\/\/\/raw\/55d\/d\/z\/42271.gif)\n\nI think it looked quite neat, and communicated well the fact that you got inside this small area that now takes the entire screen.\n\nHowever, something still bothered me - our game is black-and-white, but in this transition effect we use transparency, resulting in gray pixels! Take, for example, this intermediate frame between two screens:\n\n![mid_way_transition.png](\/\/\/raw\/55d\/d\/z\/42272.png)\n\nIt has different grayscale colors all over the place, which breaks the consistency of the style, and would not be possible in the imaginary gameboy-like device on which our game runs (at least that we aimed for...)\n\n## The Solution - Dithering!\n\nTo keep this effect and still use only two colors, I wanted to implement *dithering*, which is a method that allows expressing a scale between two colors, using only pixels of these two colors (in this - all grays between black and white).\n\n![Michelangelo's_David_-_Floyd-Steinberg[1].png](\/\/\/raw\/55d\/d\/z\/42274.png)\n\n## Implementation\n\nI implemented it by writing a simple screen-space shader, which takes the current screen \"output\" of the game, and overrides it with calculations based on the current pixels. I was using Godot game engine, but this method is possible with every modern engine.\n\nThe implementation goes roughly like this:\n- Divide the screen to pixels based on the game's resolution\n- Divide all pixels to 4x4 squares\n- For each of the 16 pixels in the square, set a different [0.0 to 1.0] \"threshold\". If the \"original\" color in darker than the threshold, final color would be black; otherwise it would be white. I chose thresholds of 1\/16, 2\/16, 3\/16, ... 16\/16 and scattered them in a nice pattern inside the 4x4 square.\n\nThat's it, actually.\n\nChoosing different thresholds for different pixels in each 4x4 square makes sure that lighter gray colors would \"paint\" more pixels white and less black; while a darker color would paint more pixels \"black\" and less \"white\", resulting in the overall impression of a darker color while still using only two colors.  \nNeedless to say, a \"completely\" white input (value 1) is above the threshold of all pixels in the square, and would result in the same white square. Similarly with black (value 0).\n\nThe pattern I chose is the following, with the goal of having similar-colored pixels as far away from each other as I can, to make it look more \"scattered\":\n\n![pattern.png](\/\/\/raw\/55d\/d\/z\/42276.png)\n\nSquare 1 has the threshold of 1\/16, square 2 has 2\/16 etc. Note that a 50% gray would paint only 1-8 squares white (because it is above (or equals, in that case) 1\/16 to 8\/16), and would result in a nice checkers-board pattern.\n\nI could have chose any other pattern, but I think this one fit best the theme of the game.\n\n## Results\n\nThis grayscale gradient ![gradient.png](\/\/\/raw\/55d\/d\/z\/42277.png) would become this after applying the shader: ![dither_gradient.png](\/\/\/raw\/55d\/d\/z\/42278.png)\n\nThis is how it looks like, zoomed in around the center (see the \"checkers board\" pattern around the 50% gray): ![dither_zoomed.PNG](\/\/\/raw\/55d\/d\/z\/42279.png)\n\n## Before and after:\n### Before\n![enter_1.gif](\/\/\/raw\/55d\/d\/z\/4227c.gif)\n### After\n![enter_dither.gif](\/\/\/raw\/55d\/d\/z\/4227d.gif)\n(I like how the environment \"dissolves\" when switching to a new area)\n\nWhat do you think? Do you like the new dithering or do you prefer the previous look?  \nPlease let us know if the post was helpful for you! And don't forget to [play Autumn Hike](https:\/\/ldjam.com\/events\/ludum-dare\/48\/autumn-hike)!\n\nThanks,  \nOri and Autumn Hike team :)","title":"Autumn Hike Dithering Explained","wayback_source":[]}