你好,我正在使用 QTCreator 和 qml 学习 Qt 3d 6.4.2 版本,在研究了官方 qt 文档,甚至在堆栈溢出中,我没有找到一种方法将多个图像作为立方体的面或一个纹理图像映射,我尝试使用 CubeMapTexture 但出现错误,我也尝试使用材质,但我也不能
这是重现的最小代码
import QtQuick
import QtQuick3D
import QtQuick3D.Effects
import QtQuick3D.Helpers
import QtQuick.Controls
import QtQuick.Layouts
Window {
id: window
width: 1280
height: 720
visible: true
title: "Example"
color: "#848895"
SplitView {
id: splitView
anchors.fill: parent
View3D {
id: viewport
SplitView.fillHeight: true
SplitView.fillWidth: true
SplitView.minimumWidth: splitView.width * 0.5
environment: SceneEnvironment {
property bool enableEffects: false
antialiasingMode: SceneEnvironment.MSAA
antialiasingQuality: SceneEnvironment.High
lightProbe: Texture {
source: "maps/OpenfootageNET_garage-1024.hdr"
}
effects: enableEffects ? [bloom, scurveTonemap] : []
backgroundMode: SceneEnvironment.SkyBox
SCurveTonemap {
id: scurveTonemap
}
HDRBloomTonemap {
id: bloom
}
}
Node {
id: originNode
PerspectiveCamera {
id: cameraNode
z: 600
clipNear: 1
clipFar: 10000
}
}
PrincipledMaterial {
id: basicMaterial
baseColorMap: CubeMapTexture{
source: "maps/side.png"
}
}
Model {
id: cube
source: "#Cube"
materials: basicMaterial
pickable: true
}
OrbitCameraController {
origin: originNode
camera: cameraNode
}
MouseArea {
id: pickController
anchors.fill: parent
onClicked: function(mouse) {
let pickResult = viewport.pick(mouse.x, mouse.y);
if (pickResult.objectHit) {
let pickedObject = pickResult.objectHit;
// Move the camera orbit origin to be the clicked object
originNode.position = pickedObject.position
}
}
}
}
}
}
使用 CubeMapTexture 的错误是“Sampler qt_BaseColorMap_sampler 需要 2D 纹理,但关联的纹理是立方体贴图。这会导致问题。” 但在其他方面,我无法将多个纹理放入立方体中,或者只能将一个纹理放入其中并进行映射。
对于
Texture
,请考虑使用 sourceItem
。这将允许您使用传统的 2D 组件(例如 Image
)作为纹理。在我的示例中,我使用了 SVG 图像,以便我可以快速将矢量图形的混合应用到我的纹理。对于您来说,您不必限制自己使用 Image
作为您的 sourceItem
。您可以选择任何 2D 组件,例如Item
、Rectangle
、Text
、Label
、Canvas
、Shape
等
materials: [
DefaultMaterial {
diffuseMap: Texture {
sourceItem: Image {
anchors.centerIn: parent
width: 224
height: 224
source: "Dice1.svg"
sourceSize: Qt.size(width, height)
cache: false
}
}
}
]
如果您使用“#Cube”,则您使用的材质在所有 6 个面上都将相同。如果切换为使用 6 个“#Rectangle”,则可以为每个矩形使用不同的材质。我们可以使用这种技术来创建 6 面骰子。骰子的每个面都使用自己的 SVG 图像进行渲染:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
Page {
id: page
background: Rectangle { color: "#848895" }
header: Frame {
background: Rectangle { color: "#eee" }
CheckBox { id: chkLabels; text: qsTr("Labels"); checked: true }
}
Node {
id: standAloneScene
DirectionalLight { ambientColor: Qt.rgba(1.0, 1.0, 1.0, 1.0) }
Node {
id: node
Repeater3D {
model: [
["Dice1.svg", 0, 0 ],
["Dice6.svg", 0, 180 ],
["Dice3.svg", 0, 90 ],
["Dice4.svg", 0, -90 ],
["Dice2.svg", 90, 0 ],
["Dice5.svg", -90, 0 ],
]
delegate: Node {
eulerRotation.x: modelData[1]
eulerRotation.y: modelData[2]
Model {
source: "#Rectangle"
materials: [
DefaultMaterial {
diffuseMap: Texture {
sourceItem: Item {
anchors.centerIn: parent
width: 224
height: 224
Image {
anchors.fill: parent
source: modelData[0]
sourceSize: Qt.size(width, height)
cache: false
}
Label {
visible: chkLabels.checked
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
text: modelData[0]
color: "white"
Rectangle {
anchors.fill: parent
anchors.margins: -5
color: "blue"
border.color: "yellow"
radius: 5
z: -2
}
}
}
}
}
]
z: 50
}
}
}
}
OrthographicCamera {
id: cameraOrthographicFront
lookAtNode: node
y: 800; z: 1000
property double sc: 300/Math.max(Math.min(page.width, page.height), 1)
scale: Qt.vector3d(sc, sc, 1)
}
}
View3D {
anchors.fill: parent
importScene: standAloneScene
camera: cameraOrthographicFront
}
NumberAnimation {
target: node
property: "eulerRotation.y"
loops: Animation.Infinite
running: true
from: 720; to: 0
duration: 10000
}
NumberAnimation {
target: node
property: "eulerRotation.x"
loops: Animation.Infinite
running: true
from: 360; to: 0
duration: 10000
}
}
// Dice1.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#444"/>
<circle cx="16" cy="16" r="4" fill="#800"/>
</svg>
// Dice2.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#444"/>
<circle cx="24" cy="8" r="3" fill="#ccc"/>
<circle cx="8" cy="24" r="3" fill="#ccc"/>
</svg>
// Dice3.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#444"/>
<circle cx="24" cy="8" r="3" fill="#ccc"/>
<circle cx="16" cy="16" r="3" fill="#ccc"/>
<circle cx="8" cy="24" r="3" fill="#ccc"/>
</svg>
// Dice4.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#444"/>
<circle cx="8" cy="8" r="3" fill="#800"/>
<circle cx="24" cy="8" r="3" fill="#800"/>
<circle cx="8" cy="24" r="3" fill="#800"/>
<circle cx="24" cy="24" r="3" fill="#800"/>
</svg>
// Dice5.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#444"/>
<circle cx="8" cy="8" r="3" fill="#ccc"/>
<circle cx="24" cy="8" r="3" fill="#ccc"/>
<circle cx="16" cy="16" r="3" fill="#ccc"/>
<circle cx="8" cy="24" r="3" fill="#ccc"/>
<circle cx="24" cy="24" r="3" fill="#ccc"/>
</svg>
// Dice6.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#444"/>
<circle cx="8" cy="8" r="3" fill="#ccc"/>
<circle cx="8" cy="16" r="3" fill="#ccc"/>
<circle cx="8" cy="24" r="3" fill="#ccc"/>
<circle cx="24" cy="8" r="3" fill="#ccc"/>
<circle cx="24" cy="16" r="3" fill="#ccc"/>
<circle cx="24" cy="24" r="3" fill="#ccc"/>
</svg>
您可以在线尝试!