如何使用 QML 在 Qt3D 中启用 GL 功能

How do you enable a GL function in Qt3D with QML

我正在使用 Qt3D 编写应用程序。我一直在做的大多数 3D 处理都使用 QML 而不是 C++ 接口。我已经创建了一个 QML 效果来加载我的着色器程序,类似于 Qt5.9 附带的 PerVertex 颜色效果 QML。

我遇到的问题是我正在尝试编写片段着色器并利用 glBlendFunc(sfactor, dfactor)。根据 OpenGL 文档,我需要设置 glEnable(GL_BLEND) 并使用 glBlendFunc,但我不知道如何使用 QML 来做到这一点。我可以看到它是如何在 C++ 方面完成的,但是当我使用 QML Scene3D 时,这需要大量的重写才能完成。谁能告诉我如何通过 Qt3D QML 启用 OpenGL 功能(如 GL_BLEND)?

根据要求,片段着色器:

#version 330 core

// TODO: Replace with a struct
uniform vec3 ka;            // Ambient reflectivity
uniform vec3 kd;            // Diffuse reflectivity
uniform vec3 ks;            // Specular reflectivity
uniform float shininess;    // Specular shininess factor
uniform float alpha;

uniform vec3 eyePosition;

in vec3 worldPosition;
in vec3 worldNormal;
in vec3 color;

out vec4 fragColor;

#pragma include light.inc.frag

void main()
{
    vec3 diffuseColor, specularColor;
    adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
    fragColor = vec4( ka * color + kd * color * diffuseColor + ks * color * specularColor, 1.0 );
}

这里还有Effect组件:

import Qt3D.Core 2.0
import Qt3D.Render 2.0

Effect {
    id: root

parameters: [
    Parameter { name: "k";         value: Qt.vector3d( 0.1, 0.1, 0.1 )    },
    Parameter { name: "kd";        value: Qt.vector3d( 0.7, 0.7, 0.7 )    },
    Parameter { name: "ks";        value: Qt.vector3d( 0.95, 0.95, 0.95 ) },
    Parameter { name: "shininess"; value: 150.0                           }
]

techniques: [
    Technique {
        graphicsApiFilter {
            api: GraphicsApiFilter.OpenGL
            profile: GraphicsApiFilter.CoreProfile
            majorVersion: 3
            minorVersion: 1
        }

        filterKeys: [ FilterKey { name: "renderingStyle"; value: "forward" } ]

        parameters: [
            Parameter { name: "light.position";  value: Qt.vector4d( 0.0, 0.0, 0.0, 1.0 ) },
            Parameter { name: "light.intensity"; value: Qt.vector3d( 1.0, 1.0, 1.0 )      }
        ]

        renderPasses: [
            RenderPass {
                filterKeys: [ FilterKey { name: "pass"; value: "forward" } ]

                shaderProgram: ShaderProgram {
                    vertexShaderCode:   loadSource("qrc:/shaders/thermal.vert")
                    fragmentShaderCode: loadSource("qrc:/shaders/thermal.frag")
                }
            }
        ]
    }
]
}

在 Qt3D 中无法直接调用 glBlendFunc。您需要设置 RenderPass 的 renderStates 属性。它应该类似于此,具体取决于您要启用的混合功能和其他状态:

renderPasses: [
    RenderPass {
        filterKeys: [ FilterKey { name: "pass"; value: "forward" } ]
        renderStates: [
            CullFace { mode : CullFace.Back },       
            DepthTest { depthFunction: DepthTest.Less },         
            NoDepthMask { },         
            BlendEquationArguments {         
                sourceRgb: BlendEquationArguments.SourceAlpha        
                destinationRgb: BlendEquationArguments.OneMinusSourceAlpha       
            },
            BlendEquation {blendFunction: BlendEquation.Add}
        ]

        shaderProgram: ShaderProgram {
            vertexShaderCode:   loadSource("qrc:/shaders/thermal.vert")
            fragmentShaderCode: loadSource("qrc:/shaders/thermal.frag")
        }
    }
]