diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h
index 8033f7d5b..256c7d43d 100644
--- a/include/libcamera/internal/software_isp/debayer_params.h
+++ b/include/libcamera/internal/software_isp/debayer_params.h
@@ -59,7 +59,7 @@ struct DebayerParams {
 	Matrix<float, 3, 3> ccm;
 	RGB<float> blackLevel;
 	float gamma;
-	float contrast;
+	double contrastExp;
 };
 
 } /* namespace libcamera */
diff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp
index 9aaab54f1..7d015ac89 100644
--- a/src/ipa/simple/algorithms/lut.cpp
+++ b/src/ipa/simple/algorithms/lut.cpp
@@ -60,12 +60,13 @@ void Lut::updateGammaTable(IPAContext &context)
 	const auto blackLevel = context.activeState.blc.level;
 	const unsigned int blackIndex = blackLevel * gammaTable.size() / 256;
 	const auto contrast = context.activeState.knobs.contrast.value_or(1.0);
+	/* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */
+	double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001));
 
 	const float divisor = gammaTable.size() - blackIndex - 1.0;
 	for (unsigned int i = blackIndex; i < gammaTable.size(); i++) {
 		double normalized = (i - blackIndex) / divisor;
 		/* Convert 0..2 to 0..infinity; avoid actual inifinity at tan(pi/2) */
-		double contrastExp = tan(std::clamp(contrast * M_PI_4, 0.0, M_PI_2 - 0.00001));
 		/* Apply simple S-curve */
 		if (normalized < 0.5)
 			normalized = 0.5 * std::pow(normalized / 0.5, contrastExp);
@@ -84,7 +85,7 @@ void Lut::updateGammaTable(IPAContext &context)
 		  gammaTable[blackIndex]);
 
 	context.activeState.gamma.blackLevel = blackLevel;
-	context.activeState.gamma.contrast = contrast;
+	context.activeState.gamma.contrastExp = contrastExp;
 }
 
 int16_t Lut::ccmValue(unsigned int i, float ccm) const
@@ -149,7 +150,7 @@ void Lut::prepare(IPAContext &context,
 	}
 
 	params->gamma = context.configuration.gamma;
-	params->contrast = context.activeState.gamma.contrast;
+	params->contrastExp = context.activeState.gamma.contrastExp;
 }
 
 void Lut::process([[maybe_unused]] IPAContext &context,
diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h
index 26b60fb68..7837bb4dd 100644
--- a/src/ipa/simple/ipa_context.h
+++ b/src/ipa/simple/ipa_context.h
@@ -59,6 +59,7 @@ struct IPAActiveState {
 		std::array<double, kGammaLookupSize> gammaTable;
 		uint8_t blackLevel;
 		double contrast;
+		double contrastExp;
 	} gamma;
 
 	struct {
diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp
index b33f818a7..4cb5b4da4 100644
--- a/src/libcamera/software_isp/debayer.cpp
+++ b/src/libcamera/software_isp/debayer.cpp
@@ -116,7 +116,7 @@ namespace libcamera {
  */
 
 /**
- * \var DebayerParams::contrast
+ * \var DebayerParams::contrastExp
  * \brief Contrast value for GPUISP
  */
 
