我对QML中的Qt 3D有点陌生,我正在尝试控制textured 3D对象的不透明度。为此,我正在使用simpleqml3d测试项目。
我玩过这些材料,但无法使用。这是我从IronMan.qml
测试项目中修改的simpleqml3d实体:
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
}
}
}
评论的材料是我玩过的材料。即使使用PhongAlphaMaterial
,我也无法使用,当不透明度设置为0.0时,模型仍显示为:
[有人可以帮助我控制带纹理的3D对象的不透明度,但又不会失去纹理吗?
Qt3D没有为透明纹理对象提供材料,这意味着您必须自己实现它。我稍后再讲。
简单透明
关于您的透明度问题,我试用了代码,使以下内容可以工作,但没有按钮:
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
}
}
}
我简化了示例,以找出问题所在,并且看起来您在main.cpp
中使用了错误的QML引擎。但是我建议您尝试一下Scene3DView示例,因为透明度可以与类似的设置一起使用(如果您的UI需要按钮)。我经常使用这些示例,并根据需要对其进行修改。我只是想让您开始使用我提供的代码。
如果问自己为什么我在那里有LayerFilters
,请检查我的answer,这说明了为什么场景中有透明物体时,这是必要的。
透明纹理对象
这比较困难(而且我没有时间提供示例代码,不幸的是,也许在某些不起作用的时候开始然后提出问题)。在这里,您必须实现自己的着色器。 Qt3D根本不提供任何考虑alpha的现成实现。 q3dpostproc repository是一个对我很有帮助的存储库。您可以看到如何构建自己的Qt3D材质,加载自己的着色器并将参数传递给它们。
还有高级自定义材质示例,该示例可以为如何创建自定义着色器和传递参数提供很多帮助。
如果要查看如何在着色器中对对象进行纹理化,请签出shader of QTextureMaterial及其code。我试图在QML中重新创建它,但没有立即起作用。
我建议您尝试使用q3dpostproc代码,并尝试在其中纹理一个对象(该项目的结构有点复杂,因为它是一个展示,但是过了一会儿才有意义)。它已经具有使用纹理的着色器,因为它首先将所有内容绘制到屏幕外缓冲区,然后使用该纹理绘制屏幕。在使用自己的着色器成功纹理化了一个对象之后,您可以在其中执行以下操作:
fragColor = vec4(texture(...).xyz, 0.5);
这应该为您提供透明的纹理。最后,当您想使纹理正确照明时,可能只需要用更复杂的内容替换texture(...).xyz
。但是为此,您可以在我链接的Qt3D GitHub存储库中检出phong着色器,或者从this repository或从Internet的其他地方获取一个。
希望此信息对您有所帮助。
编辑
我修改了q3dpostproc代码,以在GitHub branch中显示透明纹理。对象还没有点亮,但这应该使功能更清晰。