[RFC,v6,4/6] libcamera: shaders: Add LSC support
diff mbox series

Message ID 20260708141436.119165-5-mzamazal@redhat.com
State New
Headers show
Series
  • LSC for SoftISP simple pipeline
Related show

Commit Message

Milan Zamazal July 8, 2026, 2:14 p.m. UTC
From: Xander Pronk <xander.c.pronk@gmail.com>

Lens shading correction should be applied after black level
subtraction (in order to make the computations with meaningful values)
and before white balance (especially before white balance stats are
computed).

Note that lens shading correction depends on temperature, which is
computed from the preceding, rather than current, frame (this is due to
how white balance is currently computed).

The shaders are compiled on initialisation, while lens shading
correction can be enabled or disabled dynamically, using the
corresponding control.  The whole correction in the shader is wrapped by
a conditional macro to be able to disable it and all the related
overheads if Lsc algorithm is not enabled at all.  The correction
computation itself is conditional based on a flag that can be changed
for each processed image.

Co-developed-by: Rick ten Wolde <rick_libcamera@wolde.info>
Signed-off-by: Rick ten Wolde <rick_libcamera@wolde.info>
Signed-off-by: Xander Pronk <xander.c.pronk@gmail.com>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 src/libcamera/shaders/bayer_1x_packed.frag | 10 ++++++++++
 src/libcamera/shaders/bayer_unpacked.frag  | 10 ++++++++++
 2 files changed, 20 insertions(+)

Patch
diff mbox series

diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag
index 0b641a5f3..33f5c1fde 100644
--- a/src/libcamera/shaders/bayer_1x_packed.frag
+++ b/src/libcamera/shaders/bayer_1x_packed.frag
@@ -71,6 +71,11 @@  uniform vec3 blacklevel;
 uniform float gamma;
 uniform float contrastExp;
 
+#if defined(APPLY_LSC)
+uniform bool lsc_enabled;
+uniform sampler2D lsc_tex;
+#endif
+
 float apply_contrast(float value)
 {
 	// Apply simple S-curve
@@ -232,6 +237,11 @@  void main(void)
 	 */
 	rgb = (rgb - blacklevel) / (1.0 - blacklevel);
 
+#if defined(APPLY_LSC)
+        if (lsc_enabled)
+                rgb = rgb * texture2D(lsc_tex, textureOut).rgb;
+#endif
+
 	/* Apply AWB gains, and saturate each channel at sensor range */
 	rgb = clamp(rgb * awb, vec3(0.0), vec3(1.0));
 
diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag
index 10c5e941b..64649777e 100644
--- a/src/libcamera/shaders/bayer_unpacked.frag
+++ b/src/libcamera/shaders/bayer_unpacked.frag
@@ -30,6 +30,11 @@  uniform vec3            blacklevel;
 uniform float           gamma;
 uniform float           contrastExp;
 
+#if defined(APPLY_LSC)
+uniform bool lsc_enabled;
+uniform sampler2D lsc_tex;
+#endif
+
 float apply_contrast(float value)
 {
     // Apply simple S-curve
@@ -135,6 +140,11 @@  void main(void) {
      */
     rgb = (rgb - blacklevel) / (1.0 - blacklevel);
 
+#if defined(APPLY_LSC)
+    if (lsc_enabled)
+        rgb = rgb * texture2D(lsc_tex, center.xy).rgb;
+#endif
+
     /* Apply AWB gains, and saturate each channel at sensor range */
     rgb = clamp(rgb * awb, vec3(0.0), vec3(1.0));