The Blasphemous Miracle of Post-Processing


(Do not read this article with a phone)

After I finish an excellent videogame, I can't help but consoom internet content about it.
For Blasphemous, I stumbled into this

and I got so hyped that I wanted to make a review for Blasphemous.

What hyped me in the video was the music, just divine. But the animations were "off"; Even though the animations were great, the color palette was too bright, and did not reflect the grimdark of Blasphemous. Cartoony artstyle contrasts Blasphemous!


This got me thinking...

Can a single filter add "artstyle" to an animation?

I will let the images answer for you.


Cartoon Protagonist

image of cartoon protagonist

Mysterious Dark Protagonist

image of mysterious dark protagonist


Favourite Morning Cartoon

cartoon image of protagonist vs TrueForm Escribar

Hunting The Demon

image of protagonist vs TrueForm Escribar


Ambient Light Spam

image of cringe church

Grim Hope

image of grimdark church


What filter is that^?

Doesn't matter, you can make other filters yourself, I'm sure GIMP isn't alone in this capability. Though for every image here, I did use GIMP. Before I share the full GIMP workflow to filtering a video, I want to share my journey and experiments. Because before I got the desire to learn if I can "simply fix" a video's artstyle, I had 0 knowledge of anything you will read below, not even of image processing. Never used GIMPressionist, BIMP, nor did I ever dare to touch GIMP's source code. And I'm sure some of what you will read will be helpful.

GIMPressionist

In the Filters -> Artistic, down there in the bottom is a deprecated plugin: GIMPressionist. For context, GIMPressionist could be simplified to "Neural AI Style before it was cool". For example, take this image, and style it with a canvas texture.


Tri-Depth Crisanta

image of crisanta with only 3 light levels

Multi-Depth Crisanta

image of crisanta with multiple light levels

The above^ was the very first GIMPressionist filter which made me convinced that a filter can lead to a better image than the default. I ended up on the above filter after tweaking values and (default) textures for like 2 full hours. The original animation has only 3 light levels (see "Tri-Depth Crisanta" above), but this filter creates more light levels, and also lowers the brightness. The canvas texture, even makes sense because paintings like this did exist in spanish churches.


Let's make a filtered video!

A video is made of many images. So first, you must extract/export every single image from a video. ffmpeg does the job, as usual. You now have a folder full of images. Save the filter values, and apply the filter to all the images. Obviously, you want every image filtered, and it would be retarded to do this manually. BIMP exists, where you can set macros/operations to do on a batch of images (aka that entire folder)


This should take a while, but eventually you should have a folder full of filtered images. You now gotta stitch them into a video. ffmpeg does the job again. Here is the result:



DOUBLE FAIL^

  1. Flicker is painful to the eye, like old television static artifacts.
  2. No audio, as we only batched images, so there is no audio stream!
    Let's extract the audio stream of the original video, and add it onto our filtered video

Audio Desync^

Remember when we stiched the images? Obviously when you stitch a video with the goal of simply filtering each frame, you want each filtered frame to be at the exact same timestamp as the original frame. So, if a video is 30 fps, you just place each image 30 frames apart, right? Wrong.

Welcome to the world of animations. Where you may stretch an image for a few more frames; Not every frame is created equal. So, to stitch the frames back together at the exact timestamp, you must also export/extract each original frame and record its timestamp. I do not know how to do either in ffmpeg (is it even possible?)
But like every problem, there is never 1 solution. I just opened the video in Sony Vegas, and stretched it a bit to match the big sound cues. Not frame-perfect, but no one should notice the minor desync. This is the result:

Trash Visuals^

Literally worse than the original. So, certain static frames may look better filtered, but other frames in motion look worse. What cannot be overlooked is the (rectangular) flickering, literally painful to watch.


This is where I got back to testing filters, trying to find some set of values which have consistency between frames. Like textures where the ending and beginning is identical, instead of clipping. This is where I pretty much found the values for the original filtered images at the top of this post. Let me post some more eyecandy, as the final filter was applied to Esdras.




Default Esdras (generic cartoon face)

default image of Esdras

FilterTest Esdras

testfiltered image of Esdras

FilterTest Esdras + DropShadow

testfiltered image of Esdras


"FilterTest + DropShadow" ended up being the final filter which I will call Darkflow. Note that the DropShadow does all the difference, but to apply that is very performance-heavy. It makes a single filter take 30 seconds on my machine! Regardless, it's too good to ignore, just see the images at the top of this post. Or simply the eyecandy below.




Cartoon Villain

cartoon image of TrueForm Escribar

Red Demon

image of TrueForm Escribar

This image is already excellent (except the stone heads on the back are a bit too bright)

bootleg xenomorph kappa

Darker stoneheads and candles poggers

bootleg xenomorph kappa2

Dark Snake

image of Sierpes

Slightly Darker Snake

filtered image of Sierpes

Mudwater Boat

image of boat in muddy waters

Grimlight Boat

image of boat in the final dark

and let me post variants of my favourite frame:

Mysterious Dark Protagonist 2

filtered image of Protagonist

Mysterious Dark Protagonist 3

filtered image of Protagonist


The Filter Settings

Want to apply the filter on your images? Just copy these values into your own GIMPressionist.


Note that there are surely better filters - or more fitting to your video. While I was writing this article, I played around for 10 minutes and already found one which is slightly better than the canvas one above. Of course, you can even have 2 filters on top of each other for more possible results ;)

Also note that the Update button to the left shows false results, so never use it. Just press Apply and Ok.


Darkflow Filtered Video


Flickering makes it worse than unfiltered

And to solve it, you need to tinker with GIMPressionist's post-processing. Yes, to fix flickering, the source code must be changed. I did dive to the source code, edit, build it. I spent a full week trying to "update" GIMPressionist. I learned a lot, and there were even some interesting bugs:

It's not a bug, it's a feature

bugged-filtered image of opening

Ultimately, life happened, something else caught my attention, and then I moved into coding Double Damnation (as it wouldn't code itself to release ;) After 8 months, I returned to Linux to make an email server, and the update broke my entire Linux beyond repair (rolling release moment -_-)
So, I lost the GIMP build script + the code changes I had done + I obviously have forgotten how GIMPressionist code works.


I got only a small .txt which has the last TODO, which I will synopsize it as:
"Use global variables and cache the random values of the first image's filter, so the exact same values are used for the rest of the images."
The filter's results are different even for the same image, as it uses a random number generator (which I couldn't hardcode to output a fixed value reeeee) So, frame1 and frame2, with the same random output would be almost identical in filtering (as the brushes are applied adaptively, aka matching the orientation)
This theoritically would fix flickering, as the next frame of the current would be identical in its filter, except for the diff part of the image.


"Complicated, gib example plz!"

Frames 621 and 622

gif of frame 621 and 622

Now look what happens without randomness.
Look what happens when the filter is consistent, how it should look like:

Frames 621 and 622

gif of frame 621 and 622

Epilogue

I would honestly return to editing GIMPressionist's source code, if I had the old setup but it's gone! Succeeding in fixing the flickering^, would mean I can apply any filter to any video. Then I planned to open-source this "tool"/guide, so anyone could use it to improve their videos! An obvious example is for your gameplay video (youtuber or developer) where you can apply styling onto an entire video! No need to pay Neural AI servers of Google/Amazons, but just use your own machine! So, if you have knowledge of GIMP's codebase, please contact me, and I will give it another try.


Anyway, for a 1-week experiment, I learned quite much, and having ignored the boring code stuff, I have shared the most important bits to you, so I hope your reading of my tinkering was helpful to you. And at least I got those beautiful dark images, which match the greatness of one of the best metroidvanias in existence.

It's insane to think that all of this autism wouldn't have happened, if not for that Divine song in the animation at the top. Hype is one hell of a drug.