[{"id":37252,"web_url":"https://patchwork.libcamera.org/comment/37252/","msgid":"<854ipy5sfz.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-12-10T14:20:48","subject":"Re: [PATCH v7 10/26] libcamera: shaders: Add support for contrast","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Bryan O'Donoghue <bryan.odonoghue@linaro.org> writes:\n\n> Apply contrast after black-level and CCM operations.\n>\n> Suggested-by: Milan Zamazal <mzamazal@redhat.com>\n> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n> ---\n>  src/libcamera/shaders/bayer_1x_packed.frag | 19 +++++++++++++++++++\n>  src/libcamera/shaders/bayer_unpacked.frag  | 19 +++++++++++++++++++\n>  2 files changed, 38 insertions(+)\n>\n> diff --git a/src/libcamera/shaders/bayer_1x_packed.frag b/src/libcamera/shaders/bayer_1x_packed.frag\n> index 77d9fbfa7..eea237dfc 100644\n> --- a/src/libcamera/shaders/bayer_1x_packed.frag\n> +++ b/src/libcamera/shaders/bayer_1x_packed.frag\n> @@ -68,6 +68,19 @@ uniform sampler2D tex_y;\n>  uniform mat3 ccm;\n>  uniform vec3 blacklevel;\n>  uniform float gamma;\n> +uniform float contrast;\n> +\n> +float apply_contrast(float value)\n> +{\n> +\t// Convert 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2)\n> +\tfloat contrastExp = tan(clamp(contrast * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001));\n\nCan this be moved to the top level?  (The same for the unpacked shader.)\n\n> +\n> +\t// Apply simple S-curve\n> +\tif (value < 0.5)\n> +\t\treturn 0.5 * pow(value / 0.5, contrastExp);\n> +\telse\n> +\t\treturn 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp);\n> +}\n>  \n>  void main(void)\n>  {\n> @@ -261,6 +274,12 @@ void main(void)\n>  \trgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);\n>  \trgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);\n>  \n> +\t// Contrast\n> +\trgb = clamp(rgb, 0.0, 1.0);\n> +\trgb.r = apply_contrast(rgb.r);\n> +\trgb.g = apply_contrast(rgb.g);\n> +\trgb.b = apply_contrast(rgb.b);\n> +\n>  \t/* Apply gamma after colour correction */\n>  \trgb = pow(rgb, vec3(gamma));\n>  \n> diff --git a/src/libcamera/shaders/bayer_unpacked.frag b/src/libcamera/shaders/bayer_unpacked.frag\n> index aba11a87f..1226fe075 100644\n> --- a/src/libcamera/shaders/bayer_unpacked.frag\n> +++ b/src/libcamera/shaders/bayer_unpacked.frag\n> @@ -27,6 +27,19 @@ varying vec4            xCoord;\n>  uniform mat3            ccm;\n>  uniform vec3            blacklevel;\n>  uniform float           gamma;\n> +uniform float           contrast;\n> +\n> +float apply_contrast(float value)\n> +{\n> +    // Convert 0..2 contrast to 0..infinity; avoid actual infinity at tan(pi/2)\n> +    float contrastExp = tan(clamp(contrast * 0.78539816339744830962, 0.0, 1.5707963267948966 - 0.00001));\n> +\n> +    // Apply simple S-curve\n> +    if (value < 0.5)\n> +        return 0.5 * pow(value / 0.5, contrastExp);\n> +    else\n> +        return 1.0 - 0.5 * pow((1.0 - value) / 0.5, contrastExp);\n> +}\n>  \n>  void main(void) {\n>      vec3 rgb;\n> @@ -156,6 +169,12 @@ void main(void) {\n>      rgb.g = (rin * ccm[1][0]) + (gin * ccm[1][1]) + (bin * ccm[1][2]);\n>      rgb.b = (rin * ccm[2][0]) + (gin * ccm[2][1]) + (bin * ccm[2][2]);\n>  \n> +    // Contrast\n> +    rgb = clamp(rgb, 0.0, 1.0);\n> +    rgb.r = apply_contrast(rgb.r, contrast);\n> +    rgb.g = apply_contrast(rgb.g, contrast);\n> +    rgb.b = apply_contrast(rgb.b, contrast);\n> +\n>      /* Apply gamma after colour correction */\n>      rgb = pow(rgb, vec3(gamma));","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id CDD9AC3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 10 Dec 2025 14:20:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1582A61479;\n\tWed, 10 Dec 2025 15:20:55 +0100 (CET)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 22C9E613CB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 15:20:54 +0100 (CET)","from mail-wm1-f69.google.com (mail-wm1-f69.google.com\n\t[209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-244-suRqxKjRM9S2BOwl9rxkYA-1; Wed, 10 Dec 2025 09:20:51 -0500","by mail-wm1-f69.google.com with SMTP id\n\t5b1f17b1804b1-477563e531cso45105515e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 06:20:51 -0800 (PST)","from mzamazal-thinkpadp1gen7.tpbc.csb ([213.175.46.86])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-47a7fbdaf54sm34406725e9.19.2025.12.10.06.20.48\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 10 Dec 2025 06:20:49 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"YWmgHHjb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1765376453;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=YeabHPaYwavu7OnuArzzzrlJL7CHklSOyPLrqSVrSBc=;\n\tb=YWmgHHjbswzLzZiEwpxfROH173gZFD45hYCtcA/NKVeOhCE2YUt4aSI3CM7EMMFJabDmJi\n\t5Me02oQRxbMSEEes1ZpFVsBbuEoOgZuL/5v0ThFMRwheEzwlY5mX43Tiy2NXcuR/UfP83N\n\tUqJi6IvmDEWiRiupFhqIxIN42jtyFy8=","X-MC-Unique":"suRqxKjRM9S2BOwl9rxkYA-1","X-Mimecast-MFC-AGG-ID":"suRqxKjRM9S2BOwl9rxkYA_1765376450","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1765376450; x=1765981250;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=YeabHPaYwavu7OnuArzzzrlJL7CHklSOyPLrqSVrSBc=;\n\tb=oLxFkF4zImOxh6tuXuqCaK5LmLA/Zvrn9z3MpBUBOz9m8pyCu7cnOiz9DBLWP0XSh8\n\tSxth1Cq1QvS/y5JHXgay1wpRXaSLpX/YTY3p4DlriOnzeeX2CnxZBh8AuPNJwI+ywfmi\n\tCPQq40MQWMZfHRCLrAX/h28eV8FtzE/jPHkiWOY7/AY+PNY+SiKRrmNIMmdDN0bXvxGL\n\tmsC5r118yupWdEiY32aVQsu56ol8DDtH4d8MpqRYGvtxloZeZYPYF8M3Y8BwV+35l3F6\n\tqmkzjTkbsUFGdtzQFaH3nbkBlFVd4riVdW/pRbZc4ER6vS/0u2o+fhaydKpTcFBi2FmX\n\tI8YA==","X-Gm-Message-State":"AOJu0Ywd5co6aIgB/MVQ1vSZ+8WMfwNi9BXkZXhjkCCVB9gNzY0mNqFl\n\t0g/UeP4/YcvBCwSJIztEiTJ9y1prCWxBpRbqBk0ADmxEX+gZyyNBzfReEgWXGyK6U7+OW7mYcJ4\n\tRNpkxA8bq/oaIzFBfQxf8EbOjc4X/fHxQXzh9g0Xhkf1gZlq59YgRIW4AUFyWfaUGq/UelWsk1A\n\t4=","X-Gm-Gg":"ASbGncsUIVKaTZWJuaIt6x31mD84JnTcfErufIU9wKfYSzivyM7GEbolZ1FIPDUvauK\n\tp+wTEm7JisLTC+h75tx+zjwX0spyTHg6lGopCrOcoycVruhcu0CPPXav99R9B2b1E0zYLD5aDRu\n\t7Os6JoRqtlzMnaijdk9r9g8H4uCqhhIzFYHIvCmJ2mzdHDEl5mM9HWbTKNcArbpve/dGtu8zHwn\n\tDdZXOis9KUTZVkMBkrSm02AW+AS2Vf+W746kq7Gui01Uq8bVNW7M1/crRdaQe2LcyQGuXFBE21w\n\tBAPLZ2vOLMAYdfzjoA1RW5OVcFP5GS7qtoQfMAvPoV2p0uwT3VZPIXPU9tVMMiByc3Axp03I6dq\n\t0FVj5Sud90hBxn5xfbe6bNcfbdQ==","X-Received":["by 2002:a05:600c:1991:b0:46e:1a5e:211 with SMTP id\n\t5b1f17b1804b1-47a83843143mr24069335e9.21.1765376450125; \n\tWed, 10 Dec 2025 06:20:50 -0800 (PST)","by 2002:a05:600c:1991:b0:46e:1a5e:211 with SMTP id\n\t5b1f17b1804b1-47a83843143mr24069105e9.21.1765376449726; \n\tWed, 10 Dec 2025 06:20:49 -0800 (PST)"],"X-Google-Smtp-Source":"AGHT+IFySmI4BjtQKleK4CTeu81JMQXDLDzUG3SIXxv0zM8RQS2wH0QgI3oRNxrPNSQttP3zpJ15rw==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>","Cc":"libcamera-devel@lists.libcamera.org,  pavel@ucw.cz","Subject":"Re: [PATCH v7 10/26] libcamera: shaders: Add support for contrast","In-Reply-To":"<20251210005354.44726-11-bryan.odonoghue@linaro.org> (Bryan\n\tO'Donoghue's message of \"Wed, 10 Dec 2025 00:53:38 +0000\")","References":"<20251210005354.44726-1-bryan.odonoghue@linaro.org>\n\t<20251210005354.44726-11-bryan.odonoghue@linaro.org>","Date":"Wed, 10 Dec 2025 15:20:48 +0100","Message-ID":"<854ipy5sfz.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"m5fmq0slMIH8JTBenDQqghHRfhSXQoIXk0oW9ck6sQo_1765376450","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]