Some people asked me to explain how I made the screen effect from the CRT bot model in the short animation below, so I decided to explain the process in this blog post. I will create this in Blender and Cycles/EEVEE.
Please note that I will not be explaining the basics of Blender and the node editor, and assume you have prior knowledge in Blender and know how to do research. However feel free to ask question if you find anything unclear or ambiguous!
(More shots and info at : https://www.artstation.com/artwork/kDogPd . Design by Cameron Sewell : https://twitter.com/Thdark101/status/1335816473856663553 )
Part 1 : The Pixelated effect - Basic explanation
This is the first step I did. I will explain a different, simpler process first so you can understand more easily. You don't need to follow along in this step, as I'm only using it to explain, but you can try it if you want to.
Let's start with a simple plane and an image texture
Add a few subdivisions to your model. Each pixel will be represented as one polygon.
Perfect, now we will make each polygon act as a single pixel, and therefore should have a single uniform color.
To do so, we will need to "collapse" the UV map of each square to the middle (see the arrows in the image below). Each squares's UV will point to one single coordinate, instead of a whole area.
This is how the UV map (right) should look like, only dots, while keeping the geometry (left) the same.
To do this, select a vertical edge, press CTRL+G to bring the "select similar" menu and choose "Direction". This will select all vertical edges. Press V to split them. Repeat the same process with horizontal edges. you will end up with each polygon separate from each other.
From the UV editor window, press "." to bring the pivot point menu and set it to "Individual Origins", select everything and scale down everything (in the UV editor still) to 0.
You will end up with dots in the UV editor and a pixelated image in the 3D view
Part 2 : The Pixelated effect - Shader
The previous method was relatively easy, but what if you wanted to change the resolution? or change the shape? or apply it to another model? You will have to do everything from scratch every time. That can easily get very repetitive and tedious.
Luckily we can make this dynamic, and let the shaders do everything for us.
First let's start with previewing the distorted ("pixelated") UV map we got from the previous part, which should be our target, and compare it with a normal one. We can do this by plugging the UV output to an emit node (I recommend using the node wrangler addon and CTRL+Shift+LMB to do it automatically).
As we can see, the UV map is 2 dimensional, and the X component is represented as red, and Y as green. We can use a Separate XYZ (or Separate RGB) to preview only the X or Y component at the same time, and this should make things much clearer.
As you can see, the X component goes from 0 (black) from the left to 1 (white) to the right. Same thing for the Y, it goes from 0 in the bottom to 1 at the top. Let's only concentrate on the X component for now.
In the normal plane on the left, this is a perfectly smooth linear gradient, but when we applied the process in part 1 it became stepped with no transitions. This is what gives the pixelated effect, and we can replicate it entirely with shaders and using only one single polygon!
How can we achieve this? Lucky for us there's a "snap" function in the math node. (ctrl+A > converter > math ). Instead of increasing at a steady pace (left), it will increment at once, which will make a step pattern.
The increment value will define the number of steps, but we want to do the opposite : define the number of steps (number of horizontal/vertical pixels), and let the shader calculate the increment value for us instead. We can simply divide 1 by the number of steps and we will get the increment value. How convenient!
You can see the resulting node tree below. I like to use a "value" node for variables I will adjust in the future. It's not absolutely necessary, but it's nice and keeps things clean. So here I used a value node to keep the X resolution.
There are some edge cases, but let's focus on the most important one : decimal values. In the picture below you can see a "fifth of a pixel".
There's no such thing as that of course, so we want get rid of that and only keep the whole part of the number and ignore the fractional part. We will use my favorite node again, the math node. It has a "floor" function that does exactly that, so let's add it.
Perfect! Now let's repeat those steps for the Y component. Only 4 extra nodes, that should be easy now that you know how to do it!
And finally, let's ad a "Combine XYZ" (or "Combine RGB") node and preview it
It's working now! You can change the X and Y resolution on the fly and it updates instantly.
To keep things clean, we will put this in a node group. Select all those nodes we created and press CTRL+G to put them in a group, then disconnect the "X Resolution" and "Y resolutions" outputs and connect them to the Group input instead. Don't worry if if the preview turns black, the default values of a group nodes are always 0.5 and that gets rounded down to 0 pixels, which is normal.
You can press "Tab" to open and close a group node. Close it and set the X and Y resolution to values like 32, and then connect the vector output to the image texture node and done! one single node group to pixelate the image!
That's it for this part. In the next part I will explain how to make the dots and how to animate and distort the image.
If you want to get a better node tree, ready to be used in your projects, you can have a look at my full dot matrix shader https://blendermarket.com/products/dot-matrix-shader-cycles-eevee
Don't hesitate if you have any questions or thoughts!