Skip to content

Commit

Permalink
[Metal] add cross-platform gamma adjustment for texture rendered into…
Browse files Browse the repository at this point in the history
… QML

- Adapt the GammaAdjust element from QtGraphicalEffects to work with Metal
- Add shaders from Qt
- Create a Vulkan supported version of the fragment shader
- Generate a shader pack using qsb

Signed-off-by: Rhys Mainwaring <[email protected]>
  • Loading branch information
srmainwaring committed Oct 23, 2021
1 parent be620c0 commit 7d40f42
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 0 deletions.
42 changes: 42 additions & 0 deletions examples/simple_demo_qml_metal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,45 @@ set_target_properties(simple_demo_qml_metal
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)

# Building shader packs
#
# 1. Install Qt Shader Tools to get the command line tool `qsb`
#
# macOS: install qt6
# $ brew install qt
#
# 2. Run the qsb command line tool
#
# $ qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o gammaadjust.frag.qsb gammaadjust.frag
#
# 3. For Qt 5.15 the shaders should be in a shaders directory
#
# shaders
# ├── +glslcore
# │   └── gammaadjust.frag
# ├── +qsb
# │   └── gammaadjust.frag
# └── gammaadjust.frag
#
# 4. Ensure that Main.qrc contains the entries
#
# <!DOCTYPE RCC>
# <RCC version="1.0">
# <qresource prefix="/">
# ...
# <file>shaders/gammaadjust.frag</file>
# <file>shaders/+glslcore/gammaadjust.frag</file>
# <file>shaders/+qsb/gammaadjust.frag</file>
# </qresource>
# </RCC>
#
# 5. Reference the shader in a QML file as:
#
# ShaderEffect {
# anchors.centerIn: parent
# width: theItem.width
# height: theItem.height
# ...
# fragmentShader: "qrc:shaders/gammaadjust.frag"
# }
92 changes: 92 additions & 0 deletions examples/simple_demo_qml_metal/Main.qml
Original file line number Diff line number Diff line change
@@ -1,10 +1,64 @@
/*
* The QML for the custom GammaAdjust Item and shaders:
*
* gammaadjust.frag
* shaders/gammaadjust.frag
* shaders/+glslcore/gammaadjust.frag
*
* are adapted from the QtGraphicalEffects package and are subject to
* the licence below.
*/

/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Graphical Effects module.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

import QtQuick 2.0
import IgnitionRendering 1.0
import QtGraphicalEffects 1.0

Item {
id: rootItem
width: 800
height: 600

property bool gammaCorrect: true

ThreadRenderer {
id: renderer
anchors.fill: parent
Expand All @@ -13,6 +67,44 @@ Item {
Component.onCompleted: renderer.opacity = 1;
}

/*
* Gamma correction for sRGB output. Enabled when engine is set to ogre2
*/
// GammaAdjust {
// anchors.fill: renderer
// source: renderer
// gamma: 2.4
// enabled: gammaCorrect
// visible: gammaCorrect
// }

/*
* Substitue for GammaAdjust with cross-platform shaders
*/
Item {
id: gammaAdjustItem
anchors.fill: renderer
property real gamma: 2.4
visible: rootItem.gammaCorrect

ShaderEffectSource {
sourceItem: renderer
id: shaderSource
visible: gammaAdjustItem.visible
smooth: true
live: true
hideSource: visible
}

ShaderEffect {
id: shaderItem
anchors.fill: parent
property variant source: shaderSource
property real gamma: 1.0 / Math.max(gammaAdjustItem.gamma, 0.0001)
fragmentShader: "qrc:shaders/gammaadjust.frag"
}
}

Rectangle {
id: labelFrame
anchors.margins: -10
Expand Down
3 changes: 3 additions & 0 deletions examples/simple_demo_qml_metal/Main.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
<RCC version="1.0">
<qresource prefix="/">
<file>Main.qml</file>
<file>shaders/gammaadjust.frag</file>
<file>shaders/+glslcore/gammaadjust.frag</file>
<file>shaders/+qsb/gammaadjust.frag</file>
</qresource>
</RCC>
23 changes: 23 additions & 0 deletions examples/simple_demo_qml_metal/gammaadjust.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#version 440

layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;

layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
float gamma;
};

layout(binding = 1) uniform sampler2D source;

void main() {

// float rootGamma = 2.4;
// float gamma = 1.0 / max(rootGamma, 0.0001);

vec4 originalColor = texture(source, qt_TexCoord0);
originalColor.rgb = originalColor.rgb / max(1.0/256.0, originalColor.a);
vec3 adjustedColor = pow(originalColor.rgb, vec3(gamma));
fragColor = vec4(adjustedColor * originalColor.a, originalColor.a) * qt_Opacity;
}
Binary file not shown.
13 changes: 13 additions & 0 deletions examples/simple_demo_qml_metal/shaders/+glslcore/gammaadjust.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#version 150 core
in vec2 qt_TexCoord0;
uniform float qt_Opacity;
uniform sampler2D source;
uniform float gamma;
out vec4 fragColor;

void main(void) {
vec4 originalColor = texture(source, qt_TexCoord0.st);
originalColor.rgb = originalColor.rgb / max(1.0/256.0, originalColor.a);
vec3 adjustedColor = pow(originalColor.rgb, vec3(gamma));
fragColor = vec4(adjustedColor * originalColor.a, originalColor.a) * qt_Opacity;
}
Binary file not shown.
10 changes: 10 additions & 0 deletions examples/simple_demo_qml_metal/shaders/gammaadjust.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform lowp sampler2D source;
uniform highp float gamma;
void main(void) {
highp vec4 originalColor = texture2D(source, qt_TexCoord0.st);
originalColor.rgb = originalColor.rgb / max(1.0/256.0, originalColor.a);
highp vec3 adjustedColor = pow(originalColor.rgb, vec3(gamma));
gl_FragColor = vec4(adjustedColor * originalColor.a, originalColor.a) * qt_Opacity;
}

0 comments on commit 7d40f42

Please sign in to comment.