SLog3/BT.2020 IDT(.ctl) Creation Issue: How to Find a Correct BT.2020 to AP0 Matrix?

Hello buddy,

I’m trying to bring the ACES Pipeline into live music production.

But my camera signal is SLog3/BT.2020, and ACES doesn’t officially have an IDT for this, so I tried to make my own IDT (.ctl) for that. I used the DCTL (Source: SLog3/Rec.2020, Target: ACES (AP0), CAT: CIECAT02) generated by the ACES IDT Generator created by Tommy Zenth, combined with the official SLog3/SGamut3.Cine IDT, with some modifications — just replaces the matrix transform in SLog3/SGamut3.Cine IDT (.ctl) with the matrix in SLog3/BT.2020 DCTL (.dctl).

I tested this IDT (.ctl) and found that the image that comes out this way is not really right. I’m not sure if this matrix conversion is the reason. Here is the SLog3/BT.2020 IDT (.ctl), Is anyone able to check and advise? Thank a lot!

//------------------------------------------------------------------------------------
//  BT.2020 To ACES(Primaries0) matrix
//------------------------------------------------------------------------------------
const float matrixCoef[3][3] =
{
	{  0.6788911506598102, 0.15886842237789234, 0.16224042703562752 },
	{  0.04557083087232135,  0.8607127720474108, 0.0937163970408747 },
	{  -0.0004857103518124508, 0.025060195735059528,  0.9754255145687619 }
};

//------------------------------------------------------------------------------------
//  S-Log 3 to linear
//------------------------------------------------------------------------------------
float SLog3_to_linear( float SLog )
{
	float out;

	if (SLog >= 171.2102946929 / 1023.0)
	{
		out = pow(10.0, (SLog*1023.0-420.0)/261.5)*(0.18+0.01)-0.01;
	}
	else
	{
		out = (SLog*1023.0-95.0)*0.01125000/(171.2102946929-95.0);
	}

	return out;
}

//------------------------------------------------------------------------------------
//  main
//------------------------------------------------------------------------------------
void main (
	input varying float rIn,
	input varying float gIn,
	input varying float bIn,
	input varying float aIn,
	output varying float rOut,
	output varying float gOut,
	output varying float bOut,
	output varying float aOut )
{
	float SLog3[3];
	SLog3[0] = rIn;
	SLog3[1] = gIn;
	SLog3[2] = bIn;

	float linear[3];
	linear[0] = SLog3_to_linear( SLog3[0] );
	linear[1] = SLog3_to_linear( SLog3[1] );
	linear[2] = SLog3_to_linear( SLog3[2] );

	float ACES[3] = mult_f3_f33( linear, matrixCoef );

	rOut = ACES[0];
	gOut = ACES[1];
	bOut = ACES[2];
	aOut = aIn;
}

Hi @thomjiji,

The matrix seems correct but it needs to be transposed:

np.transpose(
    np.array([[ 0.6788911506,  0.1588684224,  0.1622404270],
              [ 0.0455708309,  0.8607127720,  0.0937163971],
              [-0.0004857104,  0.0250601957,  0.9754255146]]))
Out[37]: 
array([[  6.78891151e-01,   4.55708309e-02,  -4.85710400e-04],
       [  1.58868422e-01,   8.60712772e-01,   2.50601957e-02],
       [  1.62240427e-01,   9.37163971e-02,   9.75425515e-01]])

Cheers,

Thomas

Hi @Thomas_Mansencal ,

Thank you~ I think it works well now. And the final result is this:

//------------------------------------------------------------------------------------
//  BT.2020 To ACES(Primaries0) matrix
//------------------------------------------------------------------------------------
const float matrixCoef[3][3] =
{
	{  6.78891151e-01, 4.55708309e-02, -4.85710400e-04 },
	{  1.58868422e-01,  8.60712772e-01, 2.50601957e-02 },
	{  1.62240427e-01, 9.37163971e-02,  9.75425515e-01 }
};

//------------------------------------------------------------------------------------
//  S-Log 3 to linear
//------------------------------------------------------------------------------------
float SLog3_to_linear( float SLog )
{
	float out;

	if (SLog >= 171.2102946929 / 1023.0)
	{
		out = pow(10.0, (SLog*1023.0-420.0)/261.5)*(0.18+0.01)-0.01;
	}
	else
	{
		out = (SLog*1023.0-95.0)*0.01125000/(171.2102946929-95.0);
	}

	return out;
}

//------------------------------------------------------------------------------------
//  main
//------------------------------------------------------------------------------------
void main (
	input varying float rIn,
	input varying float gIn,
	input varying float bIn,
	input varying float aIn,
	output varying float rOut,
	output varying float gOut,
	output varying float bOut,
	output varying float aOut )
{
	float SLog3[3];
	SLog3[0] = rIn;
	SLog3[1] = gIn;
	SLog3[2] = bIn;

	float linear[3];
	linear[0] = SLog3_to_linear( SLog3[0] );
	linear[1] = SLog3_to_linear( SLog3[1] );
	linear[2] = SLog3_to_linear( SLog3[2] );

	float ACES[3] = mult_f3_f33( linear, matrixCoef );

	rOut = ACES[0];
	gOut = ACES[1];
	bOut = ACES[2];
	aOut = aIn;
}

1 Like