View Full Version : FranceBB LUT Collection
Pages :
1
2
3
4
5
6
7
[
8]
manolito
25th December 2025, 02:16
Hi Geoffrey,
looks like in this post:
https://forum.doom9.org/showthread.php?p=2014494#post2014494
you still thought that mobius was better than reinhard? I switched to mobius at that time, liked it better than reinhard and kept it there.
Cheers
manolito
GeoffreyA
25th December 2025, 07:32
Hi manolito,
I think I put Reinhard there because it tends to be the "default" when it comes to tone mapping, but you can of course use Mobius if you prefer. Between the two, I haven't tested them for almost a year, so not sure which I'd pick right now. Mobius can give better contrast; Reinhard can be gentler on the eyes. I use Spline in libplacebo, which, when coupled with peak detection, gives a superior result to both Reinhard and Mobius.
wonkey_monkey
24th January 2026, 02:51
FFVideoSource("example.mxf")
ConvertBits(16)
ConvertToPlanarRGB()
Cube("C:\Programmi\AviSynth+\LUTs\example.cube")
Should I infer from the lack of a specified matrix that the input is assumed to be RGB to start with? If I wanted to apply, say, PQ_to_BT709_v2 to a 10-bit YUV HDR video, Should I include matrix = "Rec2020" as a parameter to ConvertToPlanarRGB? Or have I completely misunderstood? :confused:
FranceBB
24th January 2026, 22:35
Should I infer from the lack of a specified matrix that the input is assumed to be RGB to start with? If I wanted to apply, say, PQ_to_BT709_v2 to a 10-bit YUV HDR video, Should I include matrix = "Rec2020" as a parameter to ConvertToPlanarRGB? Or have I completely misunderstood? :confused:
Yes, ConverttoPlanarRGB("matrix="Rec2020") will convert from the YUV limited tv range BT2020 HDR PQ input to RGB Full PC Range BT2020 HDR PQ output. There are two reasons why I didn't specify the matrix in the example:
1) It serves a lot of purposes, so it's not just for people wanting to go from HDR PQ to BT709 SDR
2) For better or worse, we live in an age in which frame properties are a thing, so in theory the indexer (LWLibavVideoSource or FFVideoSource) is supposed to populate the frame properties with the right value and this value will be used automatically by the Convertto functions.
In your case:
FFVideoSource("example.mxf")
ConvertBits(16)
ConvertToPlanarRGB(matrix="Rec2020")
Cube("C:\Programmi\AviSynth+\LUTs\PQ_to_BT709_v2.cube", interp=1, fullrange=1)
ConverttoYUV420(matrix="Rec709")
propSet("_ColorRange", 1) #Limited TV Range
propSet("_Matrix", 1) #BT709
propSet("_Transfer", 1) #BT709
propSet("_Primaries", 1) #BT709
If your source also has MaxCLL and MaxFALL as well as the mastering display, it might be a good idea to get rid of those too, either directly or via a simple propclearall(). In the case of encoders like x264 and x265, you're fine as they won't be interpreting those frame properties anyway as they only really care about the good old clip properties, but if you're using something else like FFMpeg or if your frameserving to players like MPV etc, you might wanna get rid of them.
DMD
2nd February 2026, 16:04
@FranceBB
I sent you a PM.
Thanks.
mojie126
25th February 2026, 05:13
"HDR format : Dolby Vision, Version 1.0, Profile 5, dvhe.05.06, BL+RPU, no metadata compression"
The color is not stable when converting from DV to SDR. Is it due to an issue with the RPU?
FranceBB
15th March 2026, 20:29
"HDR format : Dolby Vision, Version 1.0, Profile 5, dvhe.05.06, BL+RPU, no metadata compression"
The color is not stable when converting from DV to SDR. Is it due to an issue with the RPU?
What do you mean with "not stable"?
LUTs are simple matrices that map values from the input curve to values on the output curve, which means that they're gonna be as stable as the input is.
@FranceBB
I sent you a PM.
Thanks.
Thanks for the footage, it took me a while to get it right.
The Apple Log curve is totally logarithmic: the black starts high and the reference white is at 0.55V in the 0.0-0.7V interval.
For reference, in PQ the reference white is 0.40V while in HLG it's 0.52V.
A reference of 0.55V for a logarithmic curve is very very high, which means that although it will do a good job in preserving the blacks, it won't do much in showing highlights.
It also raises faster than Slog3 and Slog2 and much faster than PQ which confirms that the number of available stops is relatively low, so don't expect many nits in output.
The colormatrix is the normal BT2020 in this case, so we can use the values we know.
In terms of mapping, I've mapped the reference to 0.70V because I sincerely doubt such tiny sensors are gonna have any true highlights. The result is the following:
https://images2.imgbox.com/2c/4a/xhJVkOXg_o.png
https://images2.imgbox.com/ea/14/ueAftI7L_o.png
https://images2.imgbox.com/ed/70/CuL2EDNi_o.png
https://images2.imgbox.com/b7/06/k2LygjlY_o.png
Although there aren't many details in the highlights, it would be a bit of a waste to convert the BT2020 to BT709 so I've created a BT2020 HDR HLG version as well.
https://images2.imgbox.com/c9/63/NAgFM7IN_o.png
I'll add them to the repository, but I won't make an official release just yet, so consider them "experimental", but please do play with them and let me know how it goes.
As usual, the more samples the better. :)
DMD
15th March 2026, 20:37
Thanks for the footage, it took me a while to get it right.
The Apple Log curve is totally logarithmic: the black starts high and the reference white is at 0.55V in the 0.0-0.7V interval.......
Thank you for conducting the test.
FranceBB
15th March 2026, 23:19
https://github.com/FranceBB/LinearTransformation/blob/master/LinearTransformation.avsi
https://github.com/FranceBB/LinearTransformation/blob/master/ALog_to_BT709.cube
https://github.com/FranceBB/LinearTransformation/blob/master/ALog_to_HLG.cube
https://github.com/FranceBB/LinearTransformation/blob/master/ALog_to_PQ.cube
Test them out with:
LinearTransformation(Input="ALog", Output="Linear_BT709")
LinearTransformation(Input="ALog", Output="BT2020_HLG")
LinearTransformation(Input="ALog", Output="BT2100_PQ")
mojie126
16th March 2026, 06:14
What do you mean with "not stable"?
LUTs are simple matrices that map values from the input curve to values on the output curve, which means that they're gonna be as stable as the input is.
I see. I perform LUT mapping through DV videos, and the colors suddenly change. It's likely due to inconsistent inter-frame curves in the DV videos
FranceBB
1st April 2026, 21:07
Linear Transformation v3.1 Released! (https://github.com/FranceBB/LinearTransformation/releases)
Changelog:
- Introduced support to convert Apple Log to BT709 SDR, BT2020 HDR HLG and BT2020 HDR PQ
# Apple Log to BT709 SDR
LinearTransformation(Input="ALog", Output="Linear_BT709")
# Apple Log to BT2020 HDR HLG
LinearTransformation(Input="ALog", Output="BT2020_HLG")
# Apple Log to BT2020 HDR PQ
LinearTransformation(Input="ALog", Output="BT2100_PQ")
Linear Transformation v3.1 Released! (https://github.com/FranceBB/LinearTransformation/releases)
Changelog:
Great FranceBB
Sorry for asking two questions, since I’m importing the files into Resolve.
1- Do I need to consider the LUT that converts the DWG intermediate color space to BT.2020?
2- As for the AppleLog2 color space, is it handled the same way, or do I need to wait for another LUT for that?
Thanks
FranceBB
2nd April 2026, 21:52
Great FranceBB
Sorry for asking two questions, since I’m importing the files into Resolve.
1- Do I need to consider the LUT that converts the DWG intermediate color space to BT.2020?
2- As for the AppleLog2 color space, is it handled the same way, or do I need to wait for another LUT for that?
Thanks
They're handled in the same way and you don't have to go any intermediate: just import the LUT, use it in a node and you're in your target. :)
And by the way, thank you for providing the samples, they've been what made this possible. ;)
FranceBB
10th May 2026, 20:33
Linear Transformation v3.2 Released! (https://github.com/FranceBB/LinearTransformation/releases/tag/3.2)
Changelog:
- Allow the user to specify a custom path for the .cube files directly from the function via the LUT_Path parameter.
By default the function expects the .cube file to be in C:\Program Files (x86)\AviSynth+\LUTs\ however it's not mandatory to have them in that position. Prior to this update, this was specified by myPath which was a local variable. It was possible to overwrite it but every update would have overridden it again. This is now exposed in the main function as a parameter LUT_Path.
Example:
LinearTransformation(Input="Linear_BT709", Output="Linear_BT2020", Interpolation="Tetrahedral", LUT_Path="D:\LUTs\")
By default, if not specified, it will still default to C:\Program Files (x86)\AviSynth+\LUTs\ for backwards compatibility.
wonkey_monkey
11th May 2026, 00:23
A while ago I asked about whether a matrix should be applied when doing the initial convert to RGB before calling Cube.
But now I look at LinearTransformation.avsi, I see it doesn't use one:
clp = clp.ConvertBits(bits=16).ConvertToPlanarRGB() # If already PlanarRGB 16 bit then should do nearly nothing
But it does pick and use a suitable matrix when converting back to YUV. Why is that?
And isn't there some loss in converting down to the original bitdepth first (still in RGB?) and then back to the original colour space? If I've understood the script correctly, that is.
Also (sorry, I keep being curious):
#If the input has the alpha channel it needs to be converted too
Isn't alpha usually meant to be linear? And so not in need of conversion?
FranceBB
11th May 2026, 08:54
A while ago I asked about whether a matrix should be applied when doing the initial convert to RGB before calling Cube.
But now I look at LinearTransformation.avsi, I see it doesn't use one
But it does pick and use a suitable matrix when converting back to YUV. Why is that?
That's very simple: the original idea behind this was that when converting to RGB it was gonna use the matrix specified by the frame properties thus using what was specified in the input, however when converting back from RGB to YUV Avisynth wouldn't know what was done because from the Cube() perspective it's just a set of values, so it really wouldn't know, which is why I had to specify one and set the frame properties manually.
Now that I think about it, given that we can't always trust the input, it would probably be a good idea to be explicit on the first conversion as well. I have to think this through for a little bit longer (I'm currently reading this while drinking my usual morning cappuccino) but I guess you're right and it's probably sensible to do so explicitly rather than leaving it up to the frame properties.
And isn't there some loss in converting down to the original bitdepth first (still in RGB?) and then back to the original colour space?
Yep, but that's basically user controlled in the sense that the user could, theoretically, convert to, let's say, RGB Planar 16bit before calling the function and it would work. I don't think it needs changing, but I could, potentially, add an option to allow the user to specify what to get as an output so that if, let's say, YUV 4:4:4 16bit is required, it would be possible to output it straight away. Not in my current plans but it's probably a sensible thing to do.
Isn't alpha usually meant to be linear? And so not in need of conversion?
Nope, the alpha channel must follow the other channels. I've learned this the hard way a few years back when we started broadcasting in BT2020 HLG. Our graphics department didn't have a way to output anything other than BT709 SDR and we had a bunch of logos to convert, namely the various channel logo, the logo of each football team for Sky Sport etc. I've then created a workflow that takes the input, separates the YUVA in YUV + A individually, converts them to RGBA individually as RGB (Normal) and RGB (Alpha only), then applies the conversion to both individually, then it reconstructs it to a proper RGBA and finally converts back to YUVA.
This is done because Cube() only supports normal RGB without the alpha channel, so I had to work around this by doing that "trick" before reconstructing the RGBA. It tested and it works as we've been using this for a very long time.
So... yeah, if you have YUVA with YUV in BT2020 HLG, then A must also be BT2020 HLG. Same goes for RGBA.
Here I'm checking if we have the alpha channel, so RGBA (in this case RGB32) and I'm separating the alpha from the normal image so that I have:
RGB24 with just the image
RGB24 with just the alpha
#Check if the input has the alpha channel
if (Original == "RGB32") {
my_alpha = clp.ShowAlpha(pixel_type="RGB24")
clp = clp.RemoveAlphaPlane()
has_alpha_plane = true
}
else
{
has_alpha_plane = false
}
and here I'm bringing both the RGB24 with the normal image and the RGB24 with just the alpha channel to 16bit planar RGB, converting them and then using them to recreate the RGBA.
#If the input has the alpha channel it needs to be converted too
if (has_alpha_plane == true) {
#Alpha channel conversion
ConvertBits(my_alpha, 16)
ConvertToPlanarRGB()
Cube(LUT_Path + CubeStr + ".cube", interp=Interpolation, fullrange=1)
ConverttoY()
my_alpha=last
#Normal channel conversion
Cube(clp, LUT_Path + CubeStr + ".cube", interp=Interpolation, fullrange=1)
my_video=last
#Merge converted normal channel with converted alpha channel
AddAlphaPlane(my_video, my_alpha)
#Set frame properties
propset("_Matrix", my_Matrix)
propset("_Transfer", my_transfer)
propset("_Primaries", my_primaries)
out=last
}
wonkey_monkey
12th May 2026, 00:37
Thanks for the teachings.
which is why I had to specify one and set the frame properties manually.
Since you set the frame properties, couldn't you leave the matrix unspecified in the final ConvertTo... calls as well? Seems a bit redundant, unless I've misunderstood.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.