From patchwork Wed Jul 8 20:18:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 27350 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 33CA3C3318 for ; Wed, 8 Jul 2026 20:19:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E25D6660CF; Wed, 8 Jul 2026 22:19:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="ElXZhIrr"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 946F9660B8 for ; Wed, 8 Jul 2026 22:18:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1783541936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T/s94o5jHpgg4urdBGoB/gYa0GSqmeLwtQWVWj7i6PM=; b=ElXZhIrrx3mdF2iuXD+tNsF6xbKPeCGR60hhzeEdL9pMeQitcfRHq8N4vYQ6PM1bybK6hH UEAoko4PHCOR9yT+/O+gn+yKFaodf0MXyd7l4+j/IB9ygjDWVlynEebNHNgJ4LW7Uw9d3E SlTkWBauQx4AJvJcuT0+/Dr5bAgkt10= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-122-kUUWWl0DM7Kg7uWiSZaU-g-1; Wed, 08 Jul 2026 16:18:52 -0400 X-MC-Unique: kUUWWl0DM7Kg7uWiSZaU-g-1 X-Mimecast-MFC-AGG-ID: kUUWWl0DM7Kg7uWiSZaU-g_1783541930 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CE98319560A5; Wed, 8 Jul 2026 20:18:49 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.48.228]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B5CBB180059F; Wed, 8 Jul 2026 20:18:46 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Xander Pronk , Bryan O'Donoghue , Hans de Goede , Laurent Pinchart , Rick ten Wolde , Milan Zamazal Subject: [RFC PATCH v7 4/6] libcamera: shaders: Add LSC support Date: Wed, 8 Jul 2026 22:18:12 +0200 Message-ID: <20260708201816.299983-5-mzamazal@redhat.com> In-Reply-To: <20260708201816.299983-1-mzamazal@redhat.com> References: <20260708201816.299983-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 8Xl8hVy4Z5x86EuVByVnkrF2k0vhbwkZYtZ8PmEfP2s_1783541930 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Xander Pronk 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 Signed-off-by: Rick ten Wolde Signed-off-by: Xander Pronk Signed-off-by: Milan Zamazal --- src/libcamera/shaders/bayer_1x_packed.frag | 10 ++++++++++ src/libcamera/shaders/bayer_unpacked.frag | 10 ++++++++++ 2 files changed, 20 insertions(+) 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));