问题描述
我对 QML 中的 Qt 3D 有点陌生,我正在尝试控制 纹理 3D 对象的不透明度.我正在使用
有人可以帮我控制带纹理的 3D 对象的不透明度,同时又不会丢失纹理吗?
我接受了 Florian Blume 的答案,因为答案基于 Github 存储库,所以我认为最好将代码也放在 StackOverflow 上,以防他的分叉存储库分支发生不好的事情.因此,我将在此处发布使项目完全发挥作用的来源.
simpleqml3d.pro
TEMPLATE = appQT += 核心 gui 小部件 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras配置 += c++11源 += main.cpp资源 += 资源.qrc# 用于解析 Qt Creator 代码模型中 QML 模块的附加导入路径QML_IMPORT_PATH =# 用于为 Qt Quick Designer 解析 QML 模块的附加导入路径QML_DESIGNER_IMPORT_PATH =# 以下定义使您的编译器在您使用时发出警告# Qt 的任何被标记为弃用的特性(确切的警告# 取决于您的编译器).请查阅相关文档# 不推荐使用的 API,以便了解如何将您的代码从中移植.定义 += QT_DEPRECATED_WARNINGS# 如果您使用已弃用的 API,您还可能导致代码无法编译.# 为此,请取消注释以下行.# 您还可以选择仅禁用特定版本的 Qt 之前不推荐使用的 API.#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # 禁用 Qt 6.0.0 之前弃用的所有 API# 部署的默认规则.qnx:target.path =/tmp/$${TARGET}/binelse: unix:!android: target.path =/opt/$${TARGET}/bin!isEmpty(target.path): 安装 += 目标
main.cpp
/*************************************************************************************** 版权所有 (C) 2014 Klaralvdalens Datakonsult AB (KDAB).** 联系方式:https://www.qt.io/licensing/**** 该文件是 Qt Toolkit 的 Qt3D 模块的一部分.**** $QT_BEGIN_LICENSE:BSD$** 商业许可证使用** 持有有效商业 Qt 许可证的被许可人可以在** 根据随附提供的商业许可协议** 软件,或者,根据包含在** 您与 Qt 公司之间的书面协议.对于许可条款** 和条件见 https://www.qt.io/terms-conditions.为了更进一步的** 信息使用 https://www.qt.io/contact-us 上的联系表.**** BSD 许可证使用** 或者,您可以根据 BSD 许可条款使用此文件** 如下:**** "以源代码和二进制形式重新分发和使用,有或没有** 修改,只要满足以下条件是允许的** 遇见:** * 重新分发源代码必须保留以上版权** 注意,此条件列表和以下免责声明.** * 以二进制形式重新分发必须复制上述版权** 注意,此条件列表和以下免责声明在** 随附提供的文件和/或其他材料** 分配.** * 既不是 The Qt Company Ltd 的名称,也不是其名称** 贡献者可用于认可或推广衍生产品** 未经本软件事先书面许可.****** 本软件由版权所有者和贡献者提供**按原样"和任何明示或暗示的保证,包括但不** 仅限于对适销性和适用性的默示保证** 否认特定目的.在任何情况下都不应享有版权** 所有者或贡献者应对任何直接、间接、偶然、** 特殊的、惩戒性的或间接的损害(包括但不包括** 仅限于替代品或服务的采购;失去使用,** 数据或利润;或业务中断),无论是由于何种原因造成的,以及在任何情况下** 责任理论,无论是合同、严格责任还是侵权**(包括疏忽或其他)以任何方式因使用而导致** 本软件,即使已被告知可能发生此类损坏."**** $QT_END_LICENSE$**************************************************************************************/#include #include #include #include #include int main(int argc, char* argv[]){QGuiApplication app(argc, argv);Qt3DExtras::Quick::Qt3DQuickWindow 视图;//将窗口作为上下文属性公开,以便我们可以设置纵横比view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);view.setSource(QUrl("qrc:/main.qml"));视图.show();返回 app.exec();}
resources.qrc
<qresource prefix="/"><file>main.qml</file><file>IronMan.qml</file><file>man.obj</file><file>man.png</file><file>TextureAlphaMaterial.qml</file></qresource><qresource prefix="/shaders"><file>unlittexture.frag</file><file>unlittexture.vert</file></qresource></RCC>
main.qml
/*************************************************************************************** 版权所有 (C) 2016 Klaralvdalens Datakonsult AB (KDAB).** 联系方式:https://www.qt.io/licensing/**** 该文件是 Qt Toolkit 的 Qt3D 模块的一部分.**** $QT_BEGIN_LICENSE:BSD$** 商业许可证使用** 持有有效商业 Qt 许可证的被许可人可以在** 根据随附提供的商业许可协议** 软件,或者,根据包含在** 您与 Qt 公司之间的书面协议.对于许可条款** 和条件见 https://www.qt.io/terms-conditions.为了更进一步的** 信息使用 https://www.qt.io/contact-us 上的联系表.**** BSD 许可证使用** 或者,您可以根据 BSD 许可条款使用此文件** 如下:**** "以源代码和二进制形式重新分发和使用,有或没有** 修改,只要满足以下条件是允许的** 遇见:** * 重新分发源代码必须保留以上版权** 注意,此条件列表和以下免责声明.** * 以二进制形式重新分发必须复制上述版权** 注意,此条件列表和以下免责声明在** 随附提供的文件和/或其他材料** 分配.** * 既不是 The Qt Company Ltd 的名称,也不是其名称** 贡献者可用于认可或推广衍生产品** 未经本软件事先书面许可.****** 本软件由版权所有者和贡献者提供**按原样"和任何明示或暗示的保证,包括但不** 仅限于对适销性和适用性的默示保证** 否认特定目的.在任何情况下都不应享有版权** 所有者或贡献者应对任何直接、间接、偶然、** 特殊的、惩戒性的或间接的损害(包括但不包括** 仅限于替代品或服务的采购;失去使用,** 数据或利润;或业务中断),无论是由于何种原因造成的,以及在任何情况下** 责任理论,无论是合同、严格责任还是侵权**(包括疏忽或其他)以任何方式因使用而导致** 本软件,即使已被告知可能发生此类损坏."**** $QT_END_LICENSE$**************************************************************************************/导入 QtQuick 2.1导入 Qt3D.Core 2.0导入 Qt3D.Render 2.9导入 Qt3D.Input 2.0导入 Qt3D.Extras 2.9实体 {身份证:根对象名称:根"//使用 ForwardRenderer.qml 中指定的渲染器配置//并从 mainCamera 渲染组件: [渲染设置{activeFrameGraph: RenderSurfaceSelector {id:renderSurfaceSelector相机选择器 {id:相机选择器相机:相机视口{id:视口normalizedRect: Qt.rect(0, 0, 1, 1)清除缓冲区{缓冲区:ClearBuffers.AllBuffersclearColor:白色"无绘制{}}图层过滤器{层:[不透明层]}图层过滤器{层:[不透明层]filterMode: LayerFilter.DiscardAllMatchingLayersNoDepthMask {}}}}}},输入设置 { }]相机 {身份证:相机投影类型:CameraLens.PerspectiveProjection视野:45近平面:0.1远平面:1000.0位置:Qt.vector3d( 0.0, 4.0, -5.0 )upVector: Qt.vector3d( 0.0, 1.0, 0.0 )viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )}FirstPersonCameraController { 相机:相机 }实体 {组件: [点光源{启用:parent.enabled颜色:黑色"强度:0}]}实体 {平面网格{id:groundMesh宽度:50高度宽度网格分辨率:Qt.size(2, 2)}转换 {id:地面变换翻译:Qt.vector3d(0, 0, 0)}层 {id:不透明层}PhongMaterial {编号:材料漫反射:Qt.rgba( 0.5, 0.5, 0.5, 1 )环境:Qt.rgba( 0.5, 0.5, 0.5, 1 )}组件: [地面网格,地面变换,材料,不透明层]}钢铁侠 {id:钢铁侠}}
IronMan.qml
导入Qt3D.Core 2.0导入 Qt3D.Render 2.0导入 Qt3D.Extras 2.0导入 QtQml 2.14实体 {身份证:根属性vector3d位置:Qt.vector3d(0, 0, 0)房产真实比例:1.0属性真实旋转角度:0.0属性 vector3d rotationAxis: Qt.vector3d(1, 0, 0)属性别名来源:mesh.source属性 材质 材质组件:[变换、网格、材质]转换 {id:变换规模:root.scale旋转:fromAxisAndAngle(root.rotationAxis,root.rotationAngle)翻译:root.position}网 {编号:网格来源:qrc:/man.obj"}材质:TextureAlphaMaterial {编号:材料不透明度:0.5}}
TextureAlphaMaterial.qml
导入Qt3D.Core 2.0导入 Qt3D.Render 2.0材料 {身份证:根属性真实不透明度:1.参数: [范围 {名称:漫反射纹理"值:Texture2D {纹理图像:[纹理图像 {来源:qrc:/man.png"}]}}]效果:效果{id:rootEffect参数: [范围{名称:不透明度"值:root.opacity}]技术:[技术{graphicsApiFilter {api:GraphicsApiFilter.OpenGL配置文件:GraphicsApiFilter.CoreProfile主要版本:3次要版本:1}filterKeys: [ FilterKey { name: "renderingStyle";值:转发"}]渲染通道:[渲染通道{着色器程序:着色器程序{vertexShaderCode: loadSource("qrc:/shaders/unlittexture.vert")fragmentShaderCode: loadSource("qrc:/shaders/unlittexture.frag")}渲染状态:[深度测试{depthFunction:DepthTest.LessOrEqual},NoDepthMask {},混合方程{blendFunction: BlendEquation.Add},BlendEquationArguments {sourceRgb:BlendEquationArguments.OnedestinationRgb:BlendEquationArguments.OneMinusSourceAlphasourceAlpha:BlendEquationArguments.OnedestinationAlpha:BlendEquationArguments.OneMinusSourceAlpha}]}]}]}}
unlittexture.frag
#version 150 核心均匀的采样器2D漫反射纹理;均匀的浮动不透明度;在 vec3 位置;在 vec2 texCoord 中;出 vec4 fragColor;无效主(){fragColor = vec4(texture(diffuseTexture, texCoord).xyz * opacity, opacity);}
unlittexture.vert
#version 150 核心在 vec3 顶点位置;在 vec2 vertexTexCoord 中;出 vec3 位置;出 vec2 texCoord;统一 mat4 模型视图;统一 mat4 MVP;无效主(){vec3 t = vec3(vertexTexCoord, 1.0);texCoord = (t/t.z).xy;位置 = vec3(modelView * vec4(vertexPosition, 1.0));gl_Position = mvp * vec4(vertexPosition, 1.0);}
注意:
您可以分别用任何 3D 模型(使用 Blender 或任何其他 3D 软件导出到 obj)或映射纹理替换 man.obj 和 man.png.不过,它们可以在
Edit 2
我修改了你的项目.它现在显示具有透明纹理的模型,您可以在 GitHub 上找到它.一定要检查分支transparent_texture
.
我没有实现允许动态设置透明度的功能,但我认为您可以从示例开始自己做到这一点.模型也没有点亮,即只显示纹理而没有任何闪电,但通过查看其他 Qt3D 材料应该可以轻松实现一些简单的 phong 闪电.
原答案
Qt3D 不提供透明纹理对象的材质,这意味着您必须自己实现它.我稍后再谈.
简单的透明度
关于你的透明度问题,我玩弄了代码并得到以下工作,但没有按钮:
main.cpp
:
#include #include #include #include #include int main(int argc, char* argv[]){QGuiApplication app(argc, argv);Qt3DExtras::Quick::Qt3DQuickWindow 视图;view.engine()->qmlEngine()->rootContext()->setContextProperty(_window", &view);view.setSource(QUrl(qrc:/main.qml"));视图.show();返回 app.exec();}
main.qml
:
导入QtQuick 2.1导入 Qt3D.Core 2.0导入 Qt3D.Render 2.9导入 Qt3D.Input 2.0导入 Qt3D.Extras 2.9实体 {身份证:根对象名称:根"//使用 ForwardRenderer.qml 中指定的渲染器配置//并从 mainCamera 渲染组件: [渲染设置{activeFrameGraph: RenderSurfaceSelector {id:renderSurfaceSelector相机选择器 {id:相机选择器相机:相机视口{id:视口normalizedRect: Qt.rect(0, 0, 1, 1)清除缓冲区{缓冲区:ClearBuffers.AllBuffersclearColor:白色"无绘制{}}图层过滤器{层:[不透明层]}图层过滤器{层:[不透明层]filterMode: LayerFilter.DiscardAllMatchingLayers}}}}},//事件源将由 Qt3DQuickWindow 设置输入设置 { }]相机 {身份证:相机投影类型:CameraLens.PerspectiveProjection视野:45近平面:0.1远平面:1000.0位置:Qt.vector3d( 0.0, 4.0, -5.0 )upVector: Qt.vector3d( 0.0, 1.0, 0.0 )viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )}FirstPersonCameraController { 相机:相机 }实体 {组件: [点光源{启用:parent.enabled颜色:黑色"强度:0}]}实体 {平面网格{id:groundMesh宽度:50高度宽度网格分辨率:Qt.size(2, 2)}转换 {id:地面变换翻译:Qt.vector3d(0, 0, 0)}层 {id:不透明层}PhongMaterial {编号:材料漫反射:Qt.rgba( 0.5, 0.5, 0.5, 1 )环境:Qt.rgba( 0.5, 0.5, 0.5, 1 )}组件: [地面网格,地面变换,材料,不透明层]}实体 {编号:sphere1网 {身份证:男人来源:qrc:/man.obj"}组件: [男子,matSphere1Material]PhongAlphaMaterial {id:matSphere1Material阿尔法:0.1环境:Qt.rgba( 1, 1, 0, 0.0 )漫反射:Qt.rgba( 1, 1, 0, 0.0 )光泽度:50}}}
我简化了您的示例以找出问题所在,看起来您在 main.cpp
中使用了错误的 QML 引擎.但我建议您尝试使用 Scene3DView 示例,因为透明度与您的设置类似(如果您需要 UI 中的按钮).我经常使用这些示例并根据我的需要修改它们.我只是想让你开始使用我提供的代码.
如果你问自己为什么我有 LayerFilters
,请查看我的 answer 这解释了为什么当场景中有透明物体时这是必要的.
透明纹理对象
这比较困难(不幸的是我没有时间提供示例代码,也许当某些东西不起作用时开始然后提出问题).在这里,您必须实现自己的着色器.Qt3D 根本不提供任何考虑 alpha 的 read-made 实现.q3dpostproc 存储库 是一个对我帮助很大的存储库.您可以看到如何构建自己的 Qt3D 材质、加载自己的着色器并将参数传递给它们.
还有高级自定义材质示例,它可以为如何创建自定义着色器和传递参数提供很多帮助.
如果您想了解如何在着色器中对对象进行纹理处理,请查看 QTextureMaterial 的着色器 及其代码.我尝试在 QML 中重新创建它,但它没有立即起作用.
我建议您尝试使用 q3dpostproc 代码并尝试在那里对其中一个对象进行纹理化(项目的结构有点复杂,因为它是一个展示,但过了一段时间后一切都有意义了).它已经有一个使用纹理的着色器,因为它首先将所有内容绘制到屏幕外缓冲区,然后使用该纹理绘制屏幕.在您使用自己的着色器成功地对其中一个对象进行纹理处理后,您可以在其中执行以下操作:
fragColor = vec4(texture(...).xyz, 0.5);
这应该会给你一个透明的纹理.当您想要正确点亮纹理时,您可能只需要在最后用更复杂的东西替换 texture(...).xyz
.但是为此,您可以查看我链接的 Qt3D GitHub 存储库中的 phong 着色器或从 此存储库 或来自 Internet 的其他位置.
我希望这些信息有帮助.
编辑 1
我修改了 q3dpostproc 代码以在 GitHub 分支中显示透明纹理.对象尚未点亮,但这应该使功能清晰.
I am a bit new to Qt 3D in QML and I am trying to control the opacity of a textured 3D object.I am using the simpleqml3d test project in order to do that.
I have played with the materials, but couldn't get it to work.This is my modified IronMan.qml
entity from the simpleqml3d test project:
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.0
Entity {
id: root
property real x: 0
property real y: 0
property real z: 0
property real scale: 1.0
Texture2D{
id: texture
TextureImage {
source: "qrc:/man.png"
}
}
//COPY RenderableEntity.qml in your project!!!!!!
RenderableEntity{
id: chest
source: "qrc:/man.obj" //Path to iron man model. You can open it with 3D Builder on Windows 10
position: Qt.vector3d(root.x, root.y, root.z)
scale: root.scale
// material: DiffuseMapMaterial {
// id: material
// diffuse: texture
// specular: Qt.rgba( 0.2, 0.2, 0.2, 1.0 )
// shininess: 2.0
// }
// material: DiffuseMapMaterial {
// diffuse: texture
// specular: Qt.rgba( 0.2, 0.2, 0.2, 1.0 )
// shininess: 2.0
// }
// material: DiffuseSpecularMaterial {
// alphaBlending: true
// diffuse: Qt.rgba(0.2, 0.2, 0.2, 0.0)//texture
// specular: texture//Qt.rgba(0.2, 0.2, 0.2, 0.5)
// shininess: 2.0
// }
// material: PhongMaterial {
// ambient: Qt.rgba( 1, 0, 0, 0 )
// diffuse: Qt.rgba( 1, 0, 0, 0 )
// shininess: 50
// }
// material: PhongAlphaMaterial {
// alpha: 0.0
// diffuse: Qt.rgba(0.2, 0.2, 0.2, 0.0)//texture
// specular: Qt.rgba(0.2, 0.2, 0.2, 0.0)
// shininess: 2.0
// }
material: PhongAlphaMaterial {
alpha: 0.0
ambient: Qt.rgba( 1, 0, 0, 0 )
diffuse: Qt.rgba( 1, 0, 0, 0 )
shininess: 50
}
}
}
The commented materials are the materials I have played with. I couldn't get working not even with a PhongAlphaMaterial
, when the opacity is set to 0.0 the model is still displayed like this:
Can somebody please help me control the textured 3D object opacity but also without loosing the texture?
Edit:
I have accepted Florian Blume's answer and because the answer is based on a Github repository I figured it's better to have the code also here, on StackOverflow in case something bad happens to his forked repository branch. So I will post here the sources that fully make the project work.
simpleqml3d.pro
TEMPLATE = app
QT += core gui widgets 3dcore 3drender 3dinput 3dquick qml quick 3dquickextras
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += resources.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.cpp
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>
#include <QGuiApplication>
#include <QQmlEngine>
#include <QQmlContext>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
// Expose the window as a context property so we can set the aspect ratio
view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}
resources.qrc
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>IronMan.qml</file>
<file>man.obj</file>
<file>man.png</file>
<file>TextureAlphaMaterial.qml</file>
</qresource>
<qresource prefix="/shaders">
<file>unlittexture.frag</file>
<file>unlittexture.vert</file>
</qresource>
</RCC>
main.qml
/****************************************************************************
**
** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.1
import Qt3D.Core 2.0
import Qt3D.Render 2.9
import Qt3D.Input 2.0
import Qt3D.Extras 2.9
Entity {
id: root
objectName: "root"
// Use the renderer configuration specified in ForwardRenderer.qml
// and render from the mainCamera
components: [
RenderSettings {
activeFrameGraph: RenderSurfaceSelector {
id: renderSurfaceSelector
CameraSelector {
id: cameraSelector
camera: camera
Viewport {
id: viewport
normalizedRect: Qt.rect(0, 0, 1, 1)
ClearBuffers {
buffers: ClearBuffers.AllBuffers
clearColor: "white"
NoDraw{}
}
LayerFilter {
layers: [opaqueLayer]
}
LayerFilter {
layers: [opaqueLayer]
filterMode: LayerFilter.DiscardAllMatchingLayers
NoDepthMask {}
}
}
}
}
},
InputSettings { }
]
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d( 0.0, 4.0, -5.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
FirstPersonCameraController { camera: camera }
Entity {
components: [
PointLight {
enabled: parent.enabled
color: "black"
intensity: 0
}
]
}
Entity {
PlaneMesh {
id: groundMesh
width: 50
height: width
meshResolution: Qt.size(2, 2)
}
Transform {
id: groundTransform
translation: Qt.vector3d(0, 0, 0)
}
Layer {
id: opaqueLayer
}
PhongMaterial {
id: material
diffuse: Qt.rgba( 0.5, 0.5, 0.5, 1 )
ambient: Qt.rgba( 0.5, 0.5, 0.5, 1 )
}
components: [
groundMesh,
groundTransform,
material,
opaqueLayer
]
}
IronMan {
id: ironMan
}
}
IronMan.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.0
import QtQml 2.14
Entity {
id: root
property vector3d position: Qt.vector3d(0, 0, 0)
property real scale: 1.0
property real rotationAngle: 0.0
property vector3d rotationAxis: Qt.vector3d(1, 0, 0)
property alias source: mesh.source
property Material material
components: [ transform, mesh, material ]
Transform {
id: transform
scale: root.scale
rotation: fromAxisAndAngle(root.rotationAxis, root.rotationAngle)
translation: root.position
}
Mesh {
id: mesh
source: "qrc:/man.obj"
}
material: TextureAlphaMaterial {
id: material
opacity: 0.5
}
}
TextureAlphaMaterial.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
Material {
id: root
property real opacity: 1.
parameters: [
Parameter {
name: "diffuseTexture"
value: Texture2D {
textureImages: [
TextureImage {
source: "qrc:/man.png"
}
]
}
}
]
effect: Effect {
id: rootEffect
parameters: [
Parameter
{
name: "opacity"
value: root.opacity
}
]
techniques: [
Technique {
graphicsApiFilter {
api: GraphicsApiFilter.OpenGL
profile: GraphicsApiFilter.CoreProfile
majorVersion: 3
minorVersion: 1
}
filterKeys: [ FilterKey { name: "renderingStyle"; value: "forward" } ]
renderPasses: [
RenderPass {
shaderProgram: ShaderProgram {
vertexShaderCode: loadSource("qrc:/shaders/unlittexture.vert")
fragmentShaderCode: loadSource("qrc:/shaders/unlittexture.frag")
}
renderStates: [
DepthTest {
depthFunction: DepthTest.LessOrEqual
},
NoDepthMask {
},
BlendEquation {
blendFunction: BlendEquation.Add
},
BlendEquationArguments {
sourceRgb: BlendEquationArguments.One
destinationRgb: BlendEquationArguments.OneMinusSourceAlpha
sourceAlpha: BlendEquationArguments.One
destinationAlpha: BlendEquationArguments.OneMinusSourceAlpha
}
]
}
]
}
]
}
}
unlittexture.frag
#version 150 core
uniform sampler2D diffuseTexture;
uniform float opacity;
in vec3 position;
in vec2 texCoord;
out vec4 fragColor;
void main()
{
fragColor = vec4(texture(diffuseTexture, texCoord).xyz * opacity, opacity);
}
unlittexture.vert
#version 150 core
in vec3 vertexPosition;
in vec2 vertexTexCoord;
out vec3 position;
out vec2 texCoord;
uniform mat4 modelView;
uniform mat4 mvp;
void main()
{
vec3 t = vec3(vertexTexCoord, 1.0);
texCoord = (t / t.z).xy;
position = vec3(modelView * vec4(vertexPosition, 1.0));
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
Note:
You can replace man.obj and man.png with any 3D model(exported to obj using Blender or any other 3D software) or mapped texture respectively. Nevertheless they can be found on Florian's repository or on tripolskypetr's repository.
This is the end result:
Edit 2
I modified your project. It now shows the model with a transparent texture, you can find it on GitHub. Be sure to check out the branch transparent_texture
.
I didn't implement functionality that allows setting the transparency dynamically but I think you can do that yourself starting from the example. The model is also unlit, i.e. only the texture is displayed without any lightning, but it should be easy to implement some simple phong lightning by looking at the other Qt3D materials.
Original Answer
Qt3D doesn't provide a material for transparent textured objects which means that you have to implement it yourself. I'll get back to that later.
Simple Transparency
Regarding your transparency issue, I played around with the code and got the following to work but without the buttons:
main.cpp
:
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>
#include <QGuiApplication>
#include <QQmlEngine>
#include <QQmlContext>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}
main.qml
:
import QtQuick 2.1
import Qt3D.Core 2.0
import Qt3D.Render 2.9
import Qt3D.Input 2.0
import Qt3D.Extras 2.9
Entity {
id: root
objectName: "root"
// Use the renderer configuration specified in ForwardRenderer.qml
// and render from the mainCamera
components: [
RenderSettings {
activeFrameGraph: RenderSurfaceSelector {
id: renderSurfaceSelector
CameraSelector {
id: cameraSelector
camera: camera
Viewport {
id: viewport
normalizedRect: Qt.rect(0, 0, 1, 1)
ClearBuffers {
buffers: ClearBuffers.AllBuffers
clearColor: "white"
NoDraw{}
}
LayerFilter {
layers: [opaqueLayer]
}
LayerFilter {
layers: [opaqueLayer]
filterMode: LayerFilter.DiscardAllMatchingLayers
}
}
}
}
},
// Event Source will be set by the Qt3DQuickWindow
InputSettings { }
]
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d( 0.0, 4.0, -5.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
FirstPersonCameraController { camera: camera }
Entity {
components: [
PointLight {
enabled: parent.enabled
color: "black"
intensity: 0
}
]
}
Entity {
PlaneMesh {
id: groundMesh
width: 50
height: width
meshResolution: Qt.size(2, 2)
}
Transform {
id: groundTransform
translation: Qt.vector3d(0, 0, 0)
}
Layer {
id: opaqueLayer
}
PhongMaterial {
id: material
diffuse: Qt.rgba( 0.5, 0.5, 0.5, 1 )
ambient: Qt.rgba( 0.5, 0.5, 0.5, 1 )
}
components: [
groundMesh,
groundTransform,
material,
opaqueLayer
]
}
Entity {
id: sphere1
Mesh {
id: man
source: "qrc:/man.obj"
}
components: [
man,
matSphere1Material
]
PhongAlphaMaterial {
id: matSphere1Material
alpha: 0.1
ambient: Qt.rgba( 1, 1, 0, 0.0 )
diffuse: Qt.rgba( 1, 1, 0, 0.0 )
shininess: 50
}
}
}
I simplified your example to find out what the issue was and it looks like you used the wrong QML engine in the main.cpp
. But I'd suggest you try out the Scene3DView example because there transparency works with a similar setup like yours (if you need buttons in your UI). I often use the examples and modify them to my needs. I just wanted to get you started with the code I provided.
If you ask yourself why I have LayerFilters
in there, checkout my answer which explains why this is necessary when you have transparent objects in your scene.
Transparent Textured Objects
This is more difficult (and I don't have time to provide example code unfortunately, maybe start and then ask questions when something doesn't work). Here you have to implement your own shader. Qt3D simply doesn't offer any read-made implementation that takes alpha into account. One repository that always helped me a lot is the q3dpostproc repository. You can see how you can build your own Qt3D materials, load your own shaders and pass parameters to them.
There's also the Advanced Custom Material example which can provide a lot of help how to create custom shaders and pass on parameters.
If you want to see how to texture an object in a shader checkout the shader of QTextureMaterial and its code. I tried to recreate it in QML but it didn't work straight away.
I'd suggest you play around with the q3dpostproc code and try to texture one of the objects there (the structure of the project is a bit more complex because it's a showcase but after a while it all makes sense). It already has a shader that uses texturing because it draws everything to an offscreen buffer first and then uses that texture to draw the screen. After you've textured one of the objects successfully with your own shader you can do something like this in it:
fragColor = vec4(texture(...).xyz, 0.5);
This should give you a transparent texture. You probably just need to replace texture(...).xyz
in the end with something more elaborate when you want to texture to be lit correctly. But for this you can check out the phong shader in the Qt3D GitHub repository that I linked or get one from this repository or somewhere else from the internet.
I hope this information helps.
Edit 1
I modified the q3dpostproc code to show transparent textures in a GitHub branch. The objects aren't lit yet but this should make the functioning clear.
这篇关于在 QML 中控制带纹理的 3D 对象不透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!