Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for "Piece-wise Power Curves" tonemapping operator. #2

Open
KelSolaar opened this issue May 27, 2017 · 1 comment

Comments

@KelSolaar
Copy link
Member Author

KelSolaar commented Oct 1, 2019

We should create a new colour_hdri.tonemapping_operator_piecewise_power_curves global tonemapping operator in the colour.tonemapping.global_operators.operators module.

It would be great to update the Jupyter Notebook example if possible.

The implementation should be straightforward given the code from John Habble:

void FilmicToneCurve::CalcDirectParamsFromUser(CurveParamsDirect & dstParams, const CurveParamsUser & srcParams)
{
	dstParams = CurveParamsDirect();

	float toeStrength = srcParams.m_toeStrength;
	float toeLength = srcParams.m_toeLength;
	float shoulderStrength = srcParams.m_shoulderStrength;
	float shoulderLength = srcParams.m_shoulderLength;

	float shoulderAngle = srcParams.m_shoulderAngle;
	float gamma = srcParams.m_gamma;

	// This is not actually the display gamma. It's just a UI space to avoid having to 
	// enter small numbers for the input.
	float perceptualGamma = 2.2f;

	// constraints
	{
		toeLength = Saturate(toeLength);
		toeStrength = Saturate(toeStrength);
		shoulderAngle = Saturate(shoulderAngle);
		shoulderLength = Saturate(shoulderLength);

		shoulderStrength = MaxFloat(0.0f,shoulderStrength);
	}

	// apply base params
	{
		// toe goes from 0 to 0.5
		float x0 = toeLength * .5f;
		float y0 = (1.0f - toeStrength) * x0; // lerp from 0 to x0

		float remainingY = 1.0f - y0;

		float initialW = x0 + remainingY;

		float y1_offset = (1.0f - shoulderLength) * remainingY;
		float x1 = x0 + y1_offset;
		float y1 = y0 + y1_offset;

		// filmic shoulder strength is in F stops
		float extraW = exp2f(shoulderStrength)-1.0f;

		float W = initialW + extraW;

		// to adjust the perceptual gamma space, apply power
		dstParams.m_x0 = powf(x0,perceptualGamma);
		dstParams.m_y0 = powf(y0,perceptualGamma);
		dstParams.m_x1 = powf(x1,perceptualGamma);
		dstParams.m_y1 = powf(y1,perceptualGamma);
		dstParams.m_W = W;

		// bake the linear to gamma space conversion
		dstParams.m_gamma = gamma;
	}

	dstParams.m_overshootX = (dstParams.m_W * 2.0f) * shoulderAngle * shoulderStrength;
	dstParams.m_overshootY = 0.5f * shoulderAngle * shoulderStrength;
}

@KelSolaar KelSolaar changed the title Implement support for "Piecewise Power Curves" tonemapping operator. Implement support for "Piece-wise Power Curves" tonemapping operator. Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant