Hey,
As always, first a quick update on the social media progress: The pistons were received very well both on Instagram and TikTok. One video got 1+ million views on both platforms, which was quite surprising because the pistons are quite "futuristic" and don’t fit the typical Minecraft style at all.
Btw, here are the links to my accounts, it’s quite difficult to find them because there are a few fake accounts pretending to be me.
https://www.tiktok.com/@umsoea.showcase
https://www.instagram.com/umsoea.showcase/
Jukebox:
Because the pistons performed so well, I wanted to texture something in a similar "modern" style and also with ridiculous detail. To find new unique ideas I usually browse the original blockstate game files to see if there is some feature that I can abuse. I’ve considered the jukebox multiple times in the past but its blockstate file is boring – it doesn’t even support block rotations… But I think it was on the minecraft wiki that I came across the "has_record" block state by accident. It allows you to detect whether a music disc is inserted or not. The interesting part is that this feature is not used in the game – maybe it was planned but never used? I just hope that it will not be removed any time soon.
The jukebox basically is a modern turntable. I know nothing about them in real life so I had to do some research on how they work etc so I don’t embarass myself too much by adding unrealistic stuff.
The jukebox has an OFF and ON state. If Off ( = no music disc playing) only the rotating platform with a black felt mat is visible. It has a text with "Place music disc here". The tonearm (where the needle is) is resting in the neutral position.
The ON state shows a fully animated spinning vinyl disc that spins at a rate not far off from the ~33 rpm that most real vinyls spin at. The tonearm is enganged with a needle touching the disc. A red light is blinking and there is also a fake LED level meter that is animated in a pattern that fits to most music discs.
Sadly, there is no way to detect which type of music disc is playing, which means all discs have the same gray label color. But even if it was possible, to make the color switch I’d have to store one animated disc texture for each type of music disc – and that would be way too heavy performance wise.
Optimization:
My models are often very detailed and animations obviously make things even worse because each individual frame is basically an entirely separate texture on the texture atlas. But I care a lot about optimization which usually takes most of the time.
To show you the impact of optimizing models/textures I want to introduce an easy and objective way to compare how heavy a model/texture is:
I think the easiest 2 metrics are: The space used on the texture atlas + the amount of planes/quads. Example: The default vanilla jukebox is a simple cube, so it is made of 6 quad faces. It has two full 1x1 block textures: one for the top and one for the sides. So: 2 full textures and 6 quads.
Now let’s look at the unoptimized version of my new jukebox model:
Minecraft animations run at only 20fps (one for each game tick) so if I want to make a music disc spin at a rate similar to 33.333 rpm I would have to use at least 32 frames. (that’s 37.5 rpm – so a bit faster but making it slower would require even more frames or playing at a slower fps rate – both are not good options). So I would end up having 32 full block textures just to have the ON version of the model animated.
Optimization 1: Break the one big animated texture into multiple smaller animated textures with differing amounts of frames (and some non-animated parts).
The spinning disc and the blinking light fit into a square that uses a texture that is only 25% of the full block resolution (total pixel count) while maintaining almost the same pixel density (important). And the fake level meter is on a much smaller texture that has only 4 frames instead of 32. Because it’s a separate texture I can use a separate .mcmeta file to define a custom animation that repeats those 4 frames in a much longer custom pattern.
Optimization 2: Make the music disc rotation repeatable every 1/2 rotation. At first that sounds simple: You just take one half of the music disc texture and place it on the other side rotated by 180 degrees. This makes the 2nd half of the animation identical to the first half and so you only need 16 instead of 32 frames.
BUT the big issue is that my albedo texture has baked-in anisotropic reflections that obviously are stationary and do not rotate with the disc! The solution: This 180 rotation has to be done on the level of the normal and roughness data BEFORE the reflections are baked etc. That took some time to wrap my head around but it works really well.
Now the obvious question: Could you do this again and only use 8 frames by making it repeat again? Yes, but in my opinion with that you already reach the point where the brain recognizes this temporal repetition. And of course the label of the vinyl disc would have to also exist 4 times instead of 2, which would look really odd.
So due to lower resolution and less frames, we wen’t from 32 full block textures to only 4 for the animated textures. (16 frames at 25% resolution = 4 full block textures)
In summary, the numbers for the entire model (including the extra textures for the details e.g. buttons):
Vanilla Jukebox: 2 full block textures & 6 quads.
My optimized Jukebox: 6 full block textures (+ 0.125 for details) & 210 quads
My unoptimized Jukebox: 34 full block textures …
(210 quads sounds a lot but it’s similar to the pistons and the old bookshelf model had ~500 I think.)
Problems with Emissive Textures and Recommended Settings:
My most recent textures (rails, pistons, jukebox) use emissive maps with the labPBR format but I think there are a few issues with that format. Alpha values 0 and 255 of the specular texture are both treated as non-emissive but both come with their own problems. When using a value of 0, the RGB channels seem to stop working e.g. for smoothness. (I made sure that RGB channels store the correct values even with alpha = 0). I’m guessing this is simply due to how Minecraft handles pixels with alpha 0. So yeah, alpha = 0 is not an option for me. The alternative that most creators seem to be using is to use alpha 255. It works fine but it’s a hassle to work with (especially when downscaling) and the big issue: It causes weird glowing outlines when you have mipmaps enabled which are enabled by default…. I wish labPBR would just use transparency as emissiveness instead of opacity. That would fix these problems.
I highly recommend disabling "Mipmaps"!
Go to "Video Settings" → "Quality" Tab → at the very bottom set "Mipmap Levels" to "0x".
Mipmaps are great for Vanilla Minecraft but if you use good shaders you only notice the downsides. Mipmapping basically downscales the textures to a lower resolution automatically and only shows you the highest resolution when you directly look at a block close up / straight on. This can cause textures to look weird and blurry from some angles and mess up things like POM or especially emissive textures as mentioned above.
Downscaling is tricky, again:
image 1. direct subsampling 2. manual average+ sharpen 3. original full resolution
As mentioned in previous posts, downscaling with direct subsampling (e.g. nearest neighbour) is the best if you don’t want to worry about messing up any of the PBR features. And that’s why I recently switched to nearest neighbour downscaling and of course it also works for the emissive textures. The problem: It looks really ugly in some cases and the jukebox disc with it’s circular grooves is the worst case scenario…. It produces really strong "moire patterns"….
So yeah…. I gave up and went straight back to just manually downscaling the textures with a mixture of techniques and manual sharpening + manual removal of emission halos etc…. Disappointing but I don’t think there is any way around it currently.
DOWNLOADS:
As always, the downloads can be found on the download post:
https://www.patreon.com/posts/public-downloads-127596976
The newer stuff like the pistons and jukebox is also in the R15-16 packs in full resolution. (up to 2048x)