// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \page studio-3d-custom-shaders.html
    \previouspage studio-3d-effects.html
    \nextpage studio-3d-custom-effects-materials.html

    \title Custom shaders

    In \QDS projects created with \uicontrol {Qt 6} as \uicontrol {Target Qt Version},
    you create custom shaders in code and use custom shader utilities to create post-
    processing effects. In projects created with \uicontrol {Qt 5} as \uicontrol
    {Target Qt Version}, you can use custom shader utilities to to create custom
    materials and effects.

    \note Creating custom effects and materials as described here is not supported
    in the \QDS \l{Creating projects} {projects} created with \uicontrol {Qt 6} as
    \uicontrol {Target Qt Version}.

    \section1 Custom shader utilities in Qt 6

    In projects created with \uicontrol {Qt 6} as \uicontrol {Target Qt Version},
    you create custom shaders used for custom materials in code. In \uicontrol {Qt 6},
    the custom materials no longer support multipass rendering, and therefore
    you don't need to use the custom shader utilities to create custom materials.

    Use the custom shader utilities available in \uicontrol Components > \uicontrol QtQuick3D
    to customize the \uicontrol Effect component used for post-processing
    effects.

    \section2 Creating shader files

    In \uicontrol {Qt 6}, you need to create custom shaders for custom materials in code
    using \uicontrol {Text Editor} or the \uicontrol Edit mode. For more information about
    creating custom materials, see \l {Qt Quick 3D - Custom Materials Example} in the
    Qt Quick 3D documentation.

    The requirements set for shaders that you can use in custom effects and
    materials are described in \l {Qt Quick 3D Custom Material Reference}.

    If you use custom uniforms in the shader files, you must specify them
    as QML properties for the custom effect or material component. \QDS
    automatically generates the uniforms based on the property values.

    For example, the following code snippet shows fragment shader code that
    uses two uniforms: \c uTextureInUse and \c uInputTexture.

    \code
    out vec4 fragColor;

    in vec3 pos;
    in vec3 texCoord0;

    void main() {

        vec4 textCol;
        if (uTextureInUse)
            textCol = texture( uInputTexture, texCoord0.xy );

        fragColor = vec4(pos.x * 0.02 * textCol.x, pos.y * 0.02 * textCol.y, pos.z * 0.02, 1.0);
    }
    \endcode

    To use the above fragment shader in a custom effect or material component,
    you must remove the uniforms from the shader code and define them as
    properties for the component on the \uicontrol Properties tab in the
    \l {Connections} view.

    \image studio-custom-material-uniform-properties.png "Uniforms as properties in Connections view Properties tab"

    For more information about adding properties, see
    \l{Specifying custom properties}.

    \section2 Creating Post-Processing Effects

    You can use the custom shader utilities available in \uicontrol Components to create custom
    post-processing effects.

    \note \uicontrol ExtendedSceneEnvironment provides a set of built-in effects, such as depth
    of field, glow/bloom, lens flare, color grading, and vignette. These effects can be defined
    as properties, as described in \l {Applying Post-Processing Effects in the Extended Scene Environment}.
    To ensure optimal performance for your application, we recommend using these built-in effects
    instead of applying custom post-processing effects.

    To create a post-processing effect, drag an \uicontrol Effect from \uicontrol Components >
    \uicontrol QtQuick3D > \uicontrol Components to \uicontrol a scene environment in
    \uicontrol Navigator. To customize the effect, drag the required shader utilities from
    \uicontrol Components > \uicontrol QtQuick3d > \uicontrol {Custom Shader Utils} to
    \uicontrol Effect in \uicontrol Navigator. To define settings for a shader utility, select
    it in \uicontrol Navigator and edit its properties in the \uicontrol Properties view.

    \section1 Custom shaders in Qt 5

    Use the 3D shader utilities and commands available in \uicontrol Components
    > \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D Custom Shader Utilities}
    to create your own effects and materials. The \uicontrol Effect component, used
    as the base component for custom effects, is located in
     \uicontrol {Qt Quick 3D Effects} > \uicontrol {Qt Quick 3D Custom Shader Utilities}.
    To use the \uicontrol Effect component, you may need to add add the
    \uicontrol QtQuick3D.Effects module to your project. The \uicontrol {Custom Material}
    is located in \uicontrol {Qt Quick 3D Materials} >
    \uicontrol {Qt Quick 3D Custom Shader Utilities}. To use the
    \uicontrol {Custom Material} component, you may need to add the
    \uicontrol QtQuick3D.Materials module to your project.

    If the custom shader utilities are not displayed in \uicontrol {Components},
    add the \uicontrol QtQuick3D module to your project, as described in
     \l {Adding and Removing Modules}.

    \note In some \QDS versions the location of the custom shader utilities in
    \uicontrol Components may differ from what is described here. Use the search
    function in \uicontrol Components to locate any available component.

    \image studio-qtquick-3d-shader-utilities-qt5.webp "Qt 5 custom shader utilities in Components"

    For more information about using the shaders, see
    \l {Custom effects and materials in Qt 5}.

    See the following tables for available shader utilities and commands.

    \section1 Available custom shader utilities and base components
    \table
    \header
        \li Component
        \li Qt 5 only
        \li Description

    \row
        \li \l Buffer
        \li No
        \li A buffer to be used for a pass of \uicontrol {Custom Material}
            or \uicontrol Effect instances.

            The \uicontrol Name property identifies the \uicontrol Buffer
            instance. When the value of this property is empty, the buffer will
            refer to the default output texture of the render pass instead of
            allocating a buffer. This can be useful to override certain settings
            of the output, such as the texture format, without introducing a new,
            separate intermediate texture.

            The \uicontrol Format property specifies the format of the buffer.

            The \uicontrol Filter property specifies the filter operation when a
            render pass is reading a buffer that differs in size in comparison
            to the current output buffer.

            The \uicontrol {Coordinate operation} property specifies the texture
            coordinate operation for coordinates outside [0, 1] range.
            Select the \uicontrol ClampToEdge operation to clamp coordinates to
            edges. The \uicontrol Repeat operation wraps the coordinates at the
            edges to tile the texture, while \uicontrol MirroredRepeat also
            mirrors every other repeat of the texture while tiling it.

            The \uicontrol {Allocation flags} property defines allocation flags
            for the \uicontrol Buffer instance. Select \uicontrol SceneLifeTime
            to allocate the buffer for the whole lifetime of the scene.

            \uicontrol {Size multiplier} specifies the size of the
            \uicontrol Buffer instance. Value of 1.0 creates a buffer with the
            same size, while 0.5 creates a buffer with width and height halved.

    \row
        \li \l {CustomMaterial} {Custom Material}
        \li No
        \li The base component for creating custom materials used to shade
            model instances.

            The \uicontrol {Shading mode} property specifies whether the material
            is \uicontrol Shaded or \uicontrol Unshaded.

            The \uicontrol {Vertex shader} and \uicontrol {Fragment shader}
            properties define the vertex and fragment shader files for the
            material. Select the shader files from the dropdown menus. You can
            select \imageaddfile16px
            to add new shader files to the dropdown menus.

            The \uicontrol {Source blend} and \uicontrol {Destination blend}
            properties specify the source and destination blend factors.

            The \uicontrol {Always dirty} property determines whether the
            material is refreshed every time it is used.

            The \uicontrol {Line Width} property defines the width of the lines
            when the geometry is using lines or line strips.

            Specify the attributes of the \uicontrol {Custom Material} by
            defining the \uicontrol Transparency, \uicontrol Refraction and
            \uicontrol {Always dirty} properties.

            The \uicontrol {Shader Info} specifies the shader info of the
            material. For more information, see \l {Custom effects and materials in Qt 5}.

            \note In \uicontrol {Qt 5} you can also define render passes for
            \uicontrol {Custom Material} by using the \uicontrol Passes property,
            which lists render passes implemented by the material.

    \row
        \li \l Effect
        \li No
        \li A base component for creating post-processing effects.

            The \uicontrol Passes property contains a list of render passes
            implemented by the effect. You can add more entry fields to the list
            by selecting \imageplus
            . For more information, see \l {Custom effects and materials in Qt 5}.

    \row
        \li \l Pass
        \li No
        \li A render pass of an \uicontrol Effect instance. In Qt 5 you can also
            use render passes for \uicontrol {Custom Materials}.

            The \uicontrol Commands property specifies the list of render
            commands for the \uicontrol Pass instance, while the
            \uicontrol Shaders property lists the shaders for it. Use the
            dropdown menus to select the render commands and shader files of
            your choice.

            The \uicontrol Buffer property specifies an output buffer for the
            \uicontrol Pass instance.
    \row
        \li \l Shader
        \li No
        \li A container component for defining shader code used by
            \uicontrol Effect instances.

            The \uicontrol Source property specifies the shader file to be used
            by the \uicontrol Shader instance, and the \uicontrol Stage property
            defines a \uicontrol Vertex or \uicontrol Fragment stage for it.

            \note In Qt 5 you can also set the \uicontrol Stage property to
            \uicontrol Shared, \uicontrol Geometry, or \uicontrol Compute.

    \row
        \li \l {ShaderInfo} {Shader Info}
        \li Yes
        \li Basic information about custom shader code for Custom Materials.

            The \uicontrol Version property specifies the shader code version,
            while the \uicontrol Type property defines the shader code type.

            The \uicontrol Key property specifies the options used by the shader
            using the combination of shader key values, such as diffuse or
            specular lighting, refraction, transparency, displacement,
            transmissiveness, glossiness, and alpha cutout.

            The \uicontrol Key property specifies the options used by the shader
            using the combination of shader key values. Use the dropdown list
            to select the one of available shader keys:
            \list
                \li The \uicontrol Diffuse shader key applies diffuse lighting
                    and \uicontrol Specular applies specular lighting to the
                    shader instance.
                \li The \uicontrol Cutout shader key applies alpha cutout to
                    the shader instance.
                \li The \uicontrol Refraction shader key applies refraction to
                    the shader instance, while using the \uicontrol Transparent
                    key applies transparency to the shader instance.
                \li The \uicontrol Displace shader key applies displacement
                    mapping to the shader instance.
                \li The \uicontrol Transmissive shader key applies
                    transmissiveness to the shader instance.
                \li The \uicontrol Glossy shader key applies glossiness to the
                    shader instance by default. This shader key is a combination
                    of \uicontrol Diffuse and \uicontrol Specular keys.
            \endlist
    \row
        \li \l {TextureInput} {Texture Input}
        \li No
        \li A texture channel for \uicontrol {Custom Material} and Effect
            instances.

            The \uicontrol Texture property specifies the texture to input,
            while \uicontrol Enabled determines whether the texture is
            enabled.
            In \uicontrol Effect instances, setting \uicontrol Enabled
            to \uicontrol false causes the shaders to sample a dummy, opaque
            black texture instead of the one specified by texture.
    \endtable

    \section1 Available custom shader commands
    \table
    \header
        \li Command
        \li Qt 5 only
        \li Description

    \row
        \li \l Blending
        \li Yes
        \li A pass command that specifies the source blending function.

            The \uicontrol Source property specifies the source blending
            function, while the \uicontrol Destination property specifies the
            destination for it.
    \row
        \li \l {BufferBlit} {Buffer Blit}
        \li Yes
        \li A copy operation between two buffers in a pass of a Custom Material
            or an Effect.

            The \uicontrol Source and \uicontrol Destination specify the source
            and the destination buffers for the copy-operation.
    \row
        \li \l {BufferInput} {Buffer Input}
        \li No
        \li An input buffer to be used for a pass of a Custom Material or an
            Effect.

            The \uicontrol Buffer property specifies the input buffer for an
            instance of the \uicontrol Pass instance. The \uicontrol Parameter
            specifies the name of the input parameter in the shader.

    \row
        \li \l {CullMode} {Cull Mode}
        \li Yes
        \li A culling mode for a render pass.

            The \uicontrol Mode property specifies the culling mode in a pass
            when the \uicontrol {State} property of the \uicontrol {Render State}
            is set to \uicontrol CullFace. Use the dropdown menu to set the
            culling mode to \uicontrol BackFaceCulling,
            \uicontrol FrontFaceCulling, or \uicontrol NoCulling.

    \row
        \li \l {DepthInput} {Depth Input}
        \li Yes
        \li An output texture for the depth buffer.

            The \uicontrol Parameter property specifies the name of the texture
            the depth buffer will bind to.

    \row
        \li \l {RenderState} {Render State}
        \li Yes
        \li The render state to be enabled or disabled in a pass of a
            \uicontrol {Custom Material} or an \uicontrol Effect instance.

            The \uicontrol State property specifies the render state to
            enable or disable in a pass. Use the dropdown menu to set the
            \uicontrol State to \uicontrol Blend, \uicontrol CullFace,
            \uicontrol DepthTest, \uicontrol StencilTest,
            \uicontrol ScissorTest, \uicontrol DepthWrite, or
            \uicontrol Multisample.

            The \uicontrol Enabled property defines the \uicontrol Enable state
            for the \uicontrol {Render State}.

    \row
        \li \l {SetUniformValue} {Set Uniform Value}
        \li No
        \li A value to be set during a single pass.

            The \uicontrol Target property specifies the name of the uniform
            that will have its value changed during the pass, while the
            \uicontrol Value specifies the value that will be set on the target
            uniform.
    \endtable

*/
