I have only taken a look at the text so far and reproduced it with Text: Simple with 0 outline on a red color clip. We are using Qt QPainter for that, and I tinkered around with the API and docs but could not figure out a way to change it yet. I found this related post in the web search, and it links to a number of similar bug reports and posts. Curious thing is looking at your picture is you can see some pink pixels which is the white blending properly with the red, but further away from the inside of the text, it goes dark. Those appear to be black translucent pixels blending with the background.
I get similar result when I put a Crop: Circle filter with red on a white color clip (Shotcut 20.09.13 uses Qt for Crop: Circle):
Upon switching to version 20.02, which uses WebKit for Crop: Circle, I get a similar result:
Using the same version white Text: HTML on a red clip:
So, it appears WebKit has this same behavior as QPainter. Even changing the HTML body background color to opaque red so there is no alpha-compositing outside WebKit:
I suspect internally these things draw against a transparent black background regardless of the foreground color before blending layers. And some pixels of the background become translucent as some side effect (not just anti-aliasing because similar happened when I turned that off).Then, these translucent black pixels blend with the background color.
This happens even with the “Size, Position & Rotate” filter.
One interesting phenomenon is that the errors always happen in the horizontal direction, even if you rotate afterwards. This makes me wonder if the bug’s as simple as a misindexed array somewhere (assuming pixel information is stored as [y * width + x]).
For example, here’s “Crop: Circle” with red on teal:
The left side of the circle has two kinds of stripes. They’re both transitions from teal to red, but the outside one passes through white-gray while the inside one passes through black-gray. A circle made in GIMP has the transition from teal to red passing through gray-gray.
The top side of the circle looks better but it’s still not right. The pixels seem to alternate, one being too light and the next being too dark. You can see this clearly when comparing it to the GIMP circle.
The pattern holds again, pixels alternate from too light to too dark in the horizontal direction. This is hard to see on the top edge, which mostly matches the gradient made with GIMP. But the right edge is a different story, with the alternating light and dark bands being clearly visible.
I figured out that there are a few reasons why this occurs and is different than GIMP: colorspace conversion, chroma subsampling, and non-linear color processing. The reasons combine to worsen the result.
Start with a test project consisting only of RGB sources and filters. Here is mine shotcut bug 21255.mlt (8.8 KB)
Export it with preset FFV1 but in the Other tab change pix_fmt=bgr0 to export it as RGB.
Use VLC to playback the result and export frames as PNG.
Do not use Shotcut with Video Zoom scope as the player converts everything to YUV 4:2:0 for more effecient playback through OpenGL.
Open the PNG and zoom in.
Do not use Shotcut’s File > Export Frame… because that comes from the player
For the ellipse made using Mask: Simple Shape
No unwanted colors (this filter is not anti-aliased and only provides softness.)
Repeat the above procedure with pix_fmt=yuv444p and mlt_image_format=rgb24 (colorspace conversion with no chroma subsampling):
Still looks perfect because we told MLT to render to RGB instead of YUV 4:2:2, and the colorspace conversion is fairly accurate with no chroma subsampling.
Repeat the above with FFV1 defaults (pix_fmt=yuv422p and mlt_image_format=yuv422):
Here we start to get miscolored pixels because the chroma data is half the resolution (horizontal only) of the luma. We use FFmpeg libswscale for colorspace conversion, and we have tweaked its flags extensively. Upon decoding for playback it must do some interpolation on the chroma, and when colors with gamma mix it produces dark artifacts like this as explained in the following articles:
The situation is worse because now the chroma resolution is half the luma’s both vertically and horizontally.
Nearly all video is delivered as yuv420p and lossy compression gets thrown on top. You cannot really compare real world lossy compressed, chroma subsampled video with lossless RGB images. We do have plans to move to a linear color processing pipeline when we also increase the bitdepth > 8-bit, but that is going to be a lot of work that will take most of 2021. GIMP already uses linear color processing when GEGL is being used.
If you want to start looking at Shotcut’s images through a microscope, do not use its player and export as lossless RGB. This thread is now reduced to lack of linear color processing.
Here is another fun experiment. Shotcut has a hidden GPU (OpenGL via Movit) processing mode that does linear color processing, and in this mode Shotcut’s player can display the OpenGL texture from the processing as long as there are no CPU-based filters used. Thus the File > Export Frame is not a down-sampled output.
Here is a red capital O from Text: Rich composited over cyan color clip using 2 video tracks (make sure the filter is not selected when using Export Frame):
Now, I change the background color of Text: Rich to the cyan color, and this forces Qt Painter to do the compositing: