Qt例子学习笔记 - Examples/Qt-6.2.0/qt3d/advancedcustommaterial

2024-04-13 14:48

本文主要是介绍Qt例子学习笔记 - Examples/Qt-6.2.0/qt3d/advancedcustommaterial,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

main.cpp


//演示在 Qt3D 中创建高级材料。
//此示例演示创建高级自定义材料。
//描述
//高级自定义材质示例展示了更复杂的着色器,并演示了使用 QtQuick 
//用户界面和动画控制着色器属性。 水是一个 3D 网格,在 Blender 
//中建模和 uv 映射,然后作为 .obj 文件带入 Scene 3D。 
//用户可以控制的着色器属性在 advancedcustommaterial/
//WaterMaterial.qm 中定义//控件
//纹理比例滑块
//将顶点着色器内的纹理坐标相乘。 控制水面上纹理的大小。
//texCoord = vertexTexCoord * texCoordScale;//纹理速度滑块
//在advancedcustommaterial/Water.qml 中设置动画然后传
//递给顶点着色器的纹理坐标的偏移值。 创建纹理在表面上滚动的效果。
//FP vec2 waveMovCoord = waveTexCoord;
//waveMovCoord.x += offsetx;
//waveMovCoord.y -= offsety;
//FP vec4 wave = texture2D(waveTexture, waveMovCoord);//镜面反射
//将片段着色器内的镜面反射纹理值相乘。 使水反射。
//vec4 specular = vec4(specularTextureColor.a*specularity);
//vec4 outputColor = phongFunction(ka, diffuse, specular, shininess, worldPosition, worldView, wNormal);//失真
//将片段着色器中波浪纹理的红色和蓝色通道中的偏移量相乘。 使表面纹理更加随机。
//通过waveTexture的r和b颜色摆动newCoord
//FP vec2 newCoord = texCoord;
//newCoord.x += wave.r * waveStrenght;
//newCoord.y -= wave.b * waveStrenght;//2 个动画层的 normalTexture 与 newCoord 混合
//Normal amount
//将片段着色器内的法线贴图值相乘。 控制水面上较小波浪的可见性。
//FP vec3 tNormal = normalAmount * texture2D( normalTexture, movtexCoord+newCoord ).rgb - vec3( 1.0 )+(normalAmount * texture2D( normalTexture, multexCoord+newCoord ).rgb - vec3( 1.0 ));//波速
//修改顶点着色器内正弦波的频率。 控制波浪的速度。
//计算动画顶点位置
//波速
//修改顶点着色器内正弦波的频率。 控制波浪的速度。
//FP float sinPos = (vertexPosition.z)+(vertexPosition.x);
//FP float sinPos2 = (vertexPosition.y/2.0)+(vertexPosition.z);
//FP vec3 vertMod = vec3(vertexPosition.x,vertexPosition.y,vertexPosition.z);//vertMod = vec3(vertMod.x+=sin(vertYpos*2.2-sinPos2)*waveheight,
//               vertMod.y=sin(vertYpos*2.2+sinPos)*waveheight,
//               vertMod.z-=sin(vertYpos*2.2-cos(sinPos2))*waveheight);//FP vec3 vertModCom = vec3(vertMod.x+=cos(vertYpos*2.2-cos(sinPos2))*waveheight,
//                       vertMod.y=sin(vertYpos*2.2+cos(sinPos))*waveheight,
//                       vertMod.z-=cos(vertYpos*2.2-cos(sinPos))*waveheight);//波高
//乘以顶点着色器内的顶点 Y 位置。 控制波浪的高度。
//见上面//网格旋转
//在 advancedcustommaterial/Water.qml 中旋转水网格。#include <QGuiApplication>
#include <QQuickView>
#include <QOpenGLContext>
#include <Qt3DRender/qt3drender-config.h>void setSurfaceFormat()
{QSurfaceFormat format;//QSurfaceFormat 类表示 QSurface 的格式//格式包括颜色缓冲区的大小,红色、绿色和蓝色; alpha 缓冲区的大小; 深度和模板缓冲区的大小; //以及用于多重采样的每个像素的样本数。 此外,该格式还包含表面配置参数,例如用于渲染的 OpenGL //配置文件和版本、是否启用立体缓冲区以及交换行为。
#if QT_CONFIG(opengles2)format.setRenderableType(QSurfaceFormat::OpenGLES);//设置所需的可渲染类型。//在桌面 OpenGL、OpenGL ES 和 OpenVG 之间进行选择。
#elseif (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {format.setVersion(4, 3);format.setProfile(QSurfaceFormat::CoreProfile);}//该枚举定义了底层 OpenGL 实现的类型。//QOpenGLContext::LibGL 0 OpenGL//QOpenGLContext::LibGLES 1 OpenGL ES 2.0 or higher
#endif//将最小深度缓冲区大小设置为 24format.setDepthBufferSize(24);//将启用多重采样时每像素的首选采样数设置为 4 默认情况下,多重采样处于禁用状态。format.setSamples(4);//将首选模板缓冲区大小设置为8位。format.setStencilBufferSize(8);//设置全局默认表面格式。//这种格式在 QOpenGLContext、QWindow、QOpenGLWidget 和类似的类中默认使用。//通过使用相关类自己的 setFormat() 函数,它始终可以在每个实例的基础上被覆盖。 //但是,在应用程序启动时为所有窗口设置一次格式通常更方便。 在需要共享上下文的情况下,它还保证了//正确的行为,因为通过此函数设置格式可保证所有上下文和表面,即使是由 Qt //内部创建的上下文和表面,也将使用相同的格式。//注意:在设置 Qt::AA_ShareOpenGLContexts 时,强烈建议在构造 QGuiApplication 或 //QApplication 之前调用此函数。 //否则格式将不会应用于全局共享上下文,因此之后的上下文共享可能会出现问题。QSurfaceFormat::setDefaultFormat(format);#if !QT_CONFIG(qt3d_rhi_renderer)qputenv("QSG_RHI_BACKEND", "opengl");//此函数设置名为 varName 的环境变量的值。 如果变量不存在,//它将创建变量。 如果无法设置变量,则返回 0。//使用空值调用 qputenv 会删除 Windows 上的环境变量,并使其在 Unix 上设置(但为空)。 //更喜欢使用 qunsetenv() 来实现完全可移植的行为。
#endif
}int main(int argc, char **argv)
{QGuiApplication app(argc, argv);setSurfaceFormat();QQuickView view;//QQuickView 类提供了一个显示 Qt Quick 用户界面的窗口view.resize(1920, 1080);//设置窗口大小view.setResizeMode(QQuickView::SizeRootObjectToView);//此枚举指定如何调整视图大小。//QQuickView::SizeViewToRootObject 0 视图会随着 QML 中的根项调整大小。//QQuickView::SizeRootObjectToView 1 视图会自动将根项调整为视图的大小view.setSource(QUrl("qrc:/main.qml"));//将源设置为 url,加载 QML 组件并实例化它。//确保提供的 URL 完整且正确,特别是在从本地文件系统加载文件时使用 QUrl::fromLocalFile()。//使用相同的 url 多次调用此方法将导致重新实例化 QML 组件。view.show();return app.exec();
}

main.qml


import QtQuick 2.0
//Qt Quick 模块是用于编写 QML 应用程序的标准库。
//Qt QML 模块提供 QML 引擎和语言基础设施,Qt Quick 模块提供使用 QML 创建用户界面所需
//的所有基本类型。它提供了一个可视化画布,包括用于创建和动画可视化组件、接收用户输入、创
//建数据模型和视图以及延迟对象实例化的类型。
//Qt Quick 模块提供了一个 QML API,该 API 提供了用于使用 QML 语言创建用户界面的 
//QML 类型,以及一个用于使用 C++ 代码扩展 QML 应用程序的 C++ API。
//注意:一组基于 Qt Quick 的 UI 控件也可用于创建用户界面。有关更多信息,请参阅 Qt 快速控件。
import QtQuick.Scene3D 2.0 
//Scene3D 类型用于将 Qt3D 场景集成到 QtQuick 2 场景中
//Scene3D 类型将实体提供的 Qt3D 场景渲染到多采样帧缓冲对象中。
//此对象稍后被 blit 为非多重采样的 Framebuffer 对象,然后使用预乘 alpha 进行渲染。
//如果不需要多重采样,可以通过将 multisample 属性设置为 false 来避免。
//在这种情况下,Scene3D 将直接渲染到非多重采样的 Framebuffer 对象中。
//如果要渲染的场景包含非不透明材质,您可能需要使用自定义混合参数修改这些材质,以便正确渲
//染它们。 例如,如果使用 PhongAlphaMaterial 和不透明透明颜色的场景,您可能需要添加:
import Qt3D.Render 2.0
//Qt3DRender::Render
//用于访问类 Renderer 和 QRenderPlugin 的命名空间
import QtQuick.Controls 2.0
//一个基本的可视化 QML 类型
//Item 类型是 Qt Quick 中所有可视项的基本类型。
//Qt Quick 中的所有可视项都继承自 Item。 尽管 Item 
//对象没有视觉外观,但它定义了所有视觉项的通用属性,例如 x 和 y 
//位置、宽度和高度、锚定和关键处理支持。
Item {//绘制一个带有可选边框的填充矩形//矩形项目用于用纯色或渐变填充区域,和/或提供矩形边框。Rectangle {//每个 Rectangle 项目都使用纯填充颜色(使用 color 属性指定)或渐变(使用 //Gradient 类型定义并使用渐变属性设置)绘制。 //如果同时指定了颜色和渐变,则使用渐变。//您可以通过设置 border.color 和 border.width 属性为具有自己颜//色和厚度的矩形添加可选边框。 将颜色设置为“透明”以绘制没有填充颜色的边框。//您还可以使用 radius 属性创建圆角矩形。 //由于这会在矩形的角上引入弯曲边缘,因此设置 Item::antialiasing //属性以改善其外观可能是合适的。id: sceneproperty bool colorChange: trueanchors.fill: parentcolor: "#2d2d2d"//旋转 QML 类型//提供一种旋转项目的方法//Rotation 类型提供了一种通过旋转类型变换来旋转 Item 的方法//它允许(z 轴)相对于任意点旋转,并且还提供了一种为项目指定类似 3D //旋转的方法。 与旋转属性相比,这可以更好地控制项目旋转。//对于类似 3D 的项目旋转,除了原点之外,您还必须指定旋转轴。 以下示例显示了应用于图像的各种类似 3D 的旋转。//要绕其旋转的轴。 对于围绕点的简单 (2D) 旋转,您不需要指定轴,因为默认轴是 z 轴(axis { x: 0; y: 0; z: 1 })。
对于典型的 3D 类旋转,您通常会同时指定原点和轴。transform: Rotation {id: sceneRotationaxis.x: 1axis.y: 0axis.z: 0origin.x: scene.width / 2origin.y: scene.height / 2}Rectangle {id: controlsbganchors.fill: parentanchors.leftMargin: 10anchors.topMargin: 10anchors.rightMargin: 1720anchors.bottomMargin: 10color: "grey"//将其子项放置在列中//Column 是一种将其子项沿单个列定位的类型。 它可以用作在不使用锚点的情况下垂直定位一系列项目的便捷方式。Column {anchors.fill: parentanchors.leftMargin: 5anchors.topMargin: 5//间距是相邻项之间留空的像素量。 默认间距为 0。spacing: 10//8组标签和滑动条Rectangle {id: slidertexscalewidth: 180height: 60color: "#2d2d2d"//指定如何将格式化文本添加到场景中Text {id: scaletextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.top//anchors.margins 属性可用于一次将所有不同的边距设置为相同的值。//它不会覆盖先前设置的特定边距;anchors.topMargin: 10//要显示的文本。 Text 支持纯文本和富文本字符串。text: "TEXTURE SCALE"//文本颜色。//使用十六进制表示法定义的绿色文本示例://color: "#00FF00"//使用 SVG 颜色名称定义的钢蓝色文本示例//color: "steelblue"color: "white"font.bold: truefont.pointSize: 12}//用于通过沿轨道滑动手柄来选择值Slider {id: slider1anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10//此属性保存 from  - to 范围内的值。 默认值为 0.0。value: 1.0//此属性保存范围的起始值。 默认值为 0.0。from: 0.3}}Rectangle {id: slidertexturespeedwidth: 180height: 60color: "#2d2d2d"Text {id: texturespeedtextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "TEXTURE SPEED"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider5anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 1.1to: 4.0from: 0.0}}Rectangle {id: sliderspecularitywidth: 180height: 60color: "#2d2d2d"Text {id: specularitytextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "SPECULARITY"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider3anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 1.0to: 3.0from: 0.0}}Rectangle {id: sliderdistortionwidth: 180height: 60color: "#2d2d2d"Text {id: distortiontextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "DISTORTION"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider7anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 0.015to: 0.1from: 0.0}}Rectangle {id: slidernormalwidth: 180height: 60color: "#2d2d2d"Text {id: normaltextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "NORMAL AMOUNT"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider8anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 2.2to: 4.0from: 0.0}}Rectangle {id: sliderwavespeedwidth: 180height: 60color: "#2d2d2d"Text {id: wawespeedtextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "WAVE SPEED"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider2live: falseanchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 0.75to: 4.0from: 0.1}}Rectangle {id: sliderwaveheightwidth: 180height: 60color: "#2d2d2d"Text {id: waweheighttextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "WAVE HEIGHT"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider6anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 0.2to: 0.5from: 0.02}}Rectangle {id: slidermeshrotationwidth: 180height: 60color: "#2d2d2d"Text {id: meshrotationtextanchors.horizontalCenter: parent.horizontalCenteranchors.top: parent.topanchors.topMargin: 10text: "MESH ROTATION"color: "white"font.bold: truefont.pointSize: 12}Slider {id: slider4anchors.fill: parentanchors.topMargin: 30anchors.rightMargin: 10anchors.leftMargin: 10value: 35.0to: 360.0from: 0.0}}}}//Scene3D 类型用于将 Qt3D 场景集成到 QtQuick 2 场景中。Scene3D {id: scene3danchors.fill: parentanchors.leftMargin: 200anchors.topMargin: 10anchors.rightMargin: 10anchors.bottomMargin: 10focus: true//应为 3D 场景注册的方面列表。//例如,如果场景使用 FrameAction,则“logic”方面应包含在列表中。aspects: ["input", "logic"]//Scene3D.AutomaticAspectRatio 自动纵横比。//Scene3D.UserAspectRatio用户定义的纵横比cameraAspectRatioMode: Scene3D.AutomaticAspectRatio//引入SceneRoot.qmlSceneRoot {id: root}}}
}

SceneRoot.qml

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.0
import Qt3D.Input 2.0
import QtQuick 2.0 as QQ2//要显示的 3D 场景的根实体。
Entity {id: sceneRoot//定义将渲染场景的视点Camera {id: camera//保存相机投影的类型。 默认值为 CameraLens.PerspectiveProjection。projectionType: CameraLens.PerspectiveProjection//以度为单位保持相机的当前垂直视野。//与 aspectRatio一起,此属性确定了相机可见的场景的多少 //在这方面,您可能会认为它类似于选择广角(宽水平视野)或长焦(窄水平视野)//镜头,具体取决于您想要捕捉多少场景。
fieldOfView 仅在projectionType 为fieldOfView: 45//将当前相机保持在相机平面附近。 比 NearPlane 更靠近相机的对象将不会被渲染。nearPlane: 0.1//持有当前相机远平面。 距离相机比 farPlane 更远的对象将不会被渲染。farPlane: 1000.0//相机在相对于父实体的坐标中的当前位置。position: Qt.vector3d(0.0, 4.0, 15.0)//在相对于父实体的坐标中保持相机的当前向上向量。//向上向量表示相机顶部面向的方向 想想拍照:在定位自己并将相机对准目标后,您可以向左或向右旋转相机,为您提供肖像或风景(或倾斜!)拍摄。 upVector 允许您控制这种类型的移动。upVector: Qt.vector3d(0.0, 1.0, 0.0)//相机的当前视图中心,以相对于父实体的坐标表示。直观上,viewCenter 是相机指向的位置。viewCenter: Qt.vector3d(0.0, -2.0, 0.0)}//FirstPersonCameraController 允许从第一人称视角控制场景相机FirstPersonCameraController {camera: camera}//Entity 是一个 Node 子类,它可以聚合多个 Component3D 实例来指定其行为Entity {//在 Qt 3D 场景中封装一个定向光对象//定向光是一种行为类似于太阳光的光源。 来自定向光的光从同一方向以相同的强度照射所有对象,无论它们在场景中的哪个位置。DirectionalLight {id: directional//指定平行光的方向。worldDirection: Qt.vector3d(0.3, -1.0, 5.0).normalized();//光颜色color: "#fff2a3"//光强度。intensity: 0.01}Transform {id: lightpostransformtranslation: Qt.vector3d(0.0, 50.0, 60.0)}//Component3D 实例列表,定义实体的行为components: [lightpostransform, directional]}Entity {//在 Qt 3D 场景中封装点光源对象PointLight {id: pointL//光源颜色//点光源是从一个点向所有方向发光的光源。 从概念上讲,这类似于标准灯泡发出的光。//点光源使用三个衰减因子来描述光强度如何随距离降低。 这些因素被设计为在计算总衰减时一起使用。 对于 Qt3D Extras 中的材质,使用以下公式,其中距离是从灯光到被渲染表面的距离:// totalAttenuation = 1.0 / (constantAttenuation + (linearAttenuation * distance) + (quadraticAttenuation * distance * distance));color: "#fff2a3"}Transform{id: plightpostransformtranslation: Qt.vector3d(0.0, 4.0, 15.0)}components: [plightpostransform, pointL]}components: [//RenderSettings 类型保存与渲染过程相关的设置并托管活动的 FrameGraph。RenderSettings {//当前活动的 FrameGraphactiveFrameGraph: ForwardRenderer {id: rendererclearColor: "black"camera: camera}},InputSettings { }]Water { }
}

Water.qml

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import QtQuick 2.0 as QQ2Entity {id: waterWaterMaterial {id: watermaterialproperty real tox: 0.0property real toy: 0.0property real vertY: 1.0property real waveRandomAnim: 0.0diffuse: "qrc:/textures/WaterDiffuse.jpg"normal: "qrc:/textures/WaterNormal.jpg"specular: "qrc:/textures/WaterSpecular.jpg"wave: "qrc:/textures/Waterwave.jpg"sky: "qrc:/textures/sky.jpg"foam: "qrc:/textures/foam.jpg"textureScale: slider1.valuewavescale: vertY * slider2.valuespecularity: slider3.valueoffsetx: tox * slider5.valueoffsety: toy * slider5.valuenormalAmount: slider8.valuewaveheight: slider6.valuewaveStrenght: slider7.valueshininess: 100waveRandom: waveRandomAnim}//自定义网格加载器。//从各种格式的外部文件加载网格数据。//在 Qt3D 5.9 中,Mesh 支持以下格式:Wavefront OBJ Stanford Triangle Format PLY STL(立体光刻)Mesh {id: watermeshsource: "qrc:/models/waterPlane.obj"}Transform {id: waterTransformproperty real scale: 1.0property real rotx: 0.0scale3D: Qt.vector3d(scale, scale, scale)rotationY: slider4.value}Entity {id: waterEntitycomponents: [watermesh, watermaterial, waterTransform]}//允许动画按顺序运行//SequentialAnimation 和 ParallelAnimation 类型允许多个动画一起运行。 SequentialAnimation 中定义的动画一个接一个运行,而 ParallelAnimation 中定义的动画同时运行。//Transition 中定义的动画自动并行运行,因此如果这是首选行为,SequentialAnimation 可用于将动画包含在 Transition 中。//与任何其他动画类型一样,SequentialAnimation 可以通过多种方式应用,包括过渡、行为和属性值源。 Qt Quick 文档中的动画和过渡展示了多种创建动画的方法。QQ2.SequentialAnimation {QQ2.NumberAnimation {target: watermaterialproperty: "waveRandomAnim"to: 3.0duration: 4000
//            easing.type: Easing.Linear}QQ2.NumberAnimation {target: watermaterialproperty: "waveRandomAnim"to: 1.0duration: 4000
//            easing.type: Easing.Linear}}QQ2.SequentialAnimation {running: trueloops: QQ2.Animation.InfiniteQQ2.ParallelAnimation {QQ2.NumberAnimation {target: watermaterialproperty: "toy"to: 10.0duration: 100000}QQ2.NumberAnimation {target: watermaterialproperty: "tox"to: 10.0duration: 100000}}QQ2.ParallelAnimation {QQ2.NumberAnimation {target: watermaterialproperty: "toy"to: 0.0duration: 0}QQ2.NumberAnimation {target: watermaterialproperty: "tox"to: 0.0duration: 0}}}QQ2.SequentialAnimation {running: trueloops: QQ2.Animation.InfiniteQQ2.NumberAnimation {target: watermaterialproperty: "vertY"to: 200duration: 200000
//            easing.type: Easing.Linear}QQ2.NumberAnimation {target: watermaterialproperty: "vertY"to: 2duration: 200000
//            easing.type: Easing.Linear}}
}

WaterMaterial.qml

import Qt3D.Core 2.0
import Qt3D.Render 2.0Material {id: rootproperty color ambient:  Qt.rgba(0.15, 0.35, 0.50, 1.0)property alias diffuse: diffuseTextureImage.sourceproperty alias normal: normalTextureImage.sourceproperty alias wave: waveTextureImage.sourceproperty alias specular: specularTextureImage.sourceproperty alias sky: skyTextureImage.sourceproperty alias foam: foamTextureImage.sourceproperty color specularColor: Qt.rgba(0.2, 0.2, 0.2, 1.0)property real shininess: 150.0property real textureScale: 1.0property real offsetx: 0.0property real offsety: 0.0property real wavescale: 0.0property real specularity: 1.0property real waveheight: 0.1property real waveStrenght: 0.1property real normalAmount: 2.0property real waveRandom: 1.0//材质使用的参数列表材质使用的参数列表//为名称和值对提供存储空间。 这映射到着色器uniform//详细说明//Parameter 可以被 RenderPass、Technique、Effect、Material、TechniqueFilter、RenderPassFilter 引用。 在运行时,根据为渲染的给定步骤选择了哪个着色器,如果着色器包含名称与参数名称匹配的统一体,则参数中包含的值将被转换并上传。//例子/*Parameter{name:"diffuseColor"value:"blue"}//适用于以下 GLSL 统一着色器声明//uniform vec4 diffuseColor//uniform vec3 diffuseColor//uniform vec2 diffuseColor//uniform float diffuseColor*/parameters: [Parameter { name: "ka"; value: Qt.vector3d(root.ambient.r, root.ambient.g, root.ambient.b) },Parameter {name: "foamTexture"//纹理//Texture2D//具有 Target2D 目标格式的 AbstractTexture//QAbstractTexture 用于提供纹理的基类value: Texture2D {id: foamTexture//保存纹理提供程序的缩小过滤器。minificationFilter: Texture.LinearMipMapLinear//保存纹理提供者的放大过滤器。magnificationFilter: Texture.Linear//保存纹理提供程序的环绕模式。wrapMode {x: WrapMode.Repeaty: WrapMode.Repeat}//保存纹理提供者是否应自动生成 mipmap。generateMipMaps: true//保持纹理提供者的最大各向异性。maximumAnisotropy: 16.0TextureImage { id: foamTextureImage }}},Parameter {name: "skyTexture"value: Texture2D {id: skyTextureminificationFilter: Texture.LinearMipMapLinearmagnificationFilter: Texture.LinearwrapMode {x: WrapMode.Repeaty: WrapMode.Repeat}generateMipMaps: truemaximumAnisotropy: 16.0TextureImage { id: skyTextureImage }}},Parameter {name: "waveTexture"value: Texture2D {id: waveTextureminificationFilter: Texture.LinearMipMapLinearmagnificationFilter: Texture.LinearwrapMode {x: WrapMode.Repeaty: WrapMode.Repeat}generateMipMaps: truemaximumAnisotropy: 16.0TextureImage { id: waveTextureImage }}},Parameter {name: "specularTexture"value: Texture2D {id: specularTextureminificationFilter: Texture.LinearMipMapLinearmagnificationFilter: Texture.LinearwrapMode {x: WrapMode.Repeaty: WrapMode.Repeat}generateMipMaps: truemaximumAnisotropy: 16.0//封装从图像源创建 OpenGL 纹理图像所需的信息TextureImage { id: specularTextureImage }}},Parameter {name: "diffuseTexture"value: Texture2D {id: diffuseTextureminificationFilter: Texture.LinearMipMapLinearmagnificationFilter: Texture.LinearwrapMode {x: WrapMode.Repeaty: WrapMode.Repeat}generateMipMaps: truemaximumAnisotropy: 16.0TextureImage { id: diffuseTextureImage }}},Parameter {name: "normalTexture"value: Texture2D {id: normalTextureminificationFilter: Texture.LinearMipMapLinearmagnificationFilter: Texture.LinearwrapMode {x: WrapMode.Repeaty: WrapMode.Repeat}generateMipMaps: truemaximumAnisotropy: 16.0TextureImage { id: normalTextureImage }}},Parameter {name: "specularColor"value: Qt.vector3d(root.specularColor.r, root.specularColor.g, root.specularColor.b)},Parameter { name: "shininess"; value: root.shininess },Parameter { name: "texCoordScale"; value: textureScale },Parameter { name: "offsetx"; value: root.offsetx },Parameter { name: "offsety"; value: root.offsety },Parameter { name: "vertYpos"; value: root.wavescale },Parameter { name: "specularity"; value: root.specularity },Parameter { name: "waveheight"; value: root.waveheight },Parameter { name: "waveStrenght"; value: root.waveStrenght },Parameter { name: "waveRandom"; value: root.waveRandom },Parameter { name: "normalAmount"; value: root.normalAmount }]//Effect Qt 3D 场景中效果的基类//效果类型结合了一组技术和这些技术使用的参数来为材质产生渲染效果。//一个 Effect 实例应该在可能的情况下在多个 Material 实例之间共享//在 Effect 上定义的参数会覆盖在 Technique 和 RenderPass 中定义的参数(同名),但会被 RenderPassFilter、TechniqueFilter 和 Material 中的参数覆盖。effect: Effect {property string vertex: "qrc:/shaders/gl3/water.vert"property string fragment: "qrc:/shaders/gl3/water.frag"property string vertexES: "qrc:/shaders/es2/water.vert"property string fragmentES: "qrc:/shaders/es2/water.frag"property string vertexRHI: "qrc:/shaders/rhi/water.vert"property string fragmentRHI: "qrc:/shaders/rhi/water.frag"//存储过滤键及其值//FilterKey 是过滤器键值对的存储类型。 Technique 和 RenderPass 使用过滤器键来指定在渲染技术或渲染通道的哪个阶段使用。//注意:FilterKey 节点不能被禁用。FilterKey {id: forward//过滤键的名称name: "renderingStyle"//过滤键的值value: "forward"}//封装一个着色器程序//ShaderProgram 类封装了一个着色器程序。 一个着色器程序由几个不同的着色器组成,例如顶点着色器和片段着色器。//如果在着色器自省阶段遇到它们,Qt3D 将自动填充一组默认 uniforms。ShaderProgram {id: gl3Shader//vertexShaderCode保存此着色器程序使用的顶点着色器代码//loadSource返回从 sourceUrl 加载的着色器代码。vertexShaderCode: loadSource(parent.vertex)fragmentShaderCode: loadSource(parent.fragment)}ShaderProgram {id: esShadervertexShaderCode: loadSource(parent.vertexES)fragmentShaderCode: loadSource(parent.fragmentES)}ShaderProgram {id: rhiShadervertexShaderCode: loadSource(parent.vertexRHI)fragmentShaderCode: loadSource(parent.fragmentRHI)}//启用 alpha-to-coverage 多重采样模式//AlphaCoverage 类型启用 alpha-to-coverage 多重采样模式。 启用后,片段 alpha//值用作样本的覆盖率并与片段覆盖率值结合使用。 如果禁用多重采样,AlphaCoverage 将不执行任何操作。//当需要与顺序无关的混合时,Alpha-to-coverage 最有用,例如在渲染树叶、草和其他丰富的植被时。AlphaCoverage { id: alphaCoverage }//DepthTest 类型根据正在写入的样本的深度测试片段着色器的深度值//深度测试允许在深度测试通过时写入片段颜色值,并拒绝测试失败的片段。 深度测试使用深度函数来测试片段深度值到 //z-buffer 的值。 如果底层表面没有 z 缓冲区,则 DepthTest 什么也不做。DepthTest {id: depth//保存深度测试使用的当前函数。 默认为 DepthTest.NeverdepthFunction: DepthTest.Less }//封装技术//Technique 指定了一组 RenderPass 对象、FilterKey 对象、Parameter 对象和一个 GraphicsApiFilter,//它们共同定义了给定图形 API 可以呈现的呈现技术。TechniqueFilter 使用过滤器键来选择 FrameGraph 特定部分的特定技术。//在 Technique 上定义的参数会覆盖 RenderPass 中定义的参数(同名),但会被 RenderPassFilter、TechniqueFilter、Material 和 Effect 中的参数覆盖。//在创建以图形 API 的多个版本为目标的 Effect 时,创建多个 Technique 节点很有用,每个节点都设置了 graphicsApiFilter 以匹配目标版本之一。//在运行时,Qt3D 渲染器将根据支持的图形 API 版本和(如果指定)满足 FrameGraph 中给定 TechniqueFilter 的 FilterKey 节点来选择最合适的 Techniquetechniques: [// OpenGL 3.1Technique {//指定启用此技术的过滤器键列表filterKeys: [ forward ]//指定正在使用的图形 API 过滤器graphicsApiFilter {//对于 OpenGL,标识附加技术所需的 API。//enum QGraphicsApiFilter::Apiapi: GraphicsApiFilter.OpenGL//此枚举标识所需的配置文件类型profile: GraphicsApiFilter.CoreProfilemajorVersion: 3minorVersion: 1}//RenderPass 指定单个渲染通道 - 着色器程序执行的实例 - 由 Technique 使用。 渲染通道由一个 ShaderProgram 和一个 FilterKey 对象列表、一个 RenderState 对象列表和一个 Parameter 对象列表组成。//当至少一个被引用的 FilterKey 节点与 RenderPassFilter 中的任何 FilterKey 节点匹配或当 FrameGraph 中不存在 RenderPassFilter 时,RenderPass 使用给定的 RenderState 和 Parameter 节点执行 ShaderProgram。//如果 RenderPass 定义了一个 Parameter,并且它在运行时存在于与该 pass 相关联的 Technique、Effect、Material、TechniqueFilter、RenderPassFilter 中的任何一个中,则它将被具有相同名称的 Parameter 覆盖。 这对于定义合理的默认值仍然很有用。//在渲染时,对于 FrameGraph 的每个叶节点,通过累积由 FrameGraph 分支中的所有 RenderStateSet 节点定义的状态来记录基本渲染状态。 每个 RenderPass 都可以通过指定自己的 RenderState 节点来重载此基本渲染状态。renderPasses: RenderPass {shaderProgram: gl3ShaderrenderStates: [alphaCoverage ]}},// OpenGLES 2.0Technique {filterKeys: [ forward ]graphicsApiFilter {api: GraphicsApiFilter.OpenGLESmajorVersion: 2minorVersion: 0}renderPasses: RenderPass {shaderProgram: esShaderrenderStates: [ alphaCoverage ]}},// OpenGL ES 2Technique {filterKeys: [ forward ]graphicsApiFilter {api: GraphicsApiFilter.OpenGLESprofile: GraphicsApiFilter.NoProfilemajorVersion: 2minorVersion: 0}renderPasses: RenderPass {shaderProgram: esShaderrenderStates: [ alphaCoverage ]}},// RHITechnique {filterKeys: [ forward ]graphicsApiFilter {api: GraphicsApiFilter.RHIprofile: GraphicsApiFilter.NoProfilemajorVersion: 1minorVersion: 0}renderPasses: RenderPass {shaderProgram: rhiShaderrenderStates: [ alphaCoverage ]}}]}
}

water.vert

#version 150 corein vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexTexCoord;
in vec4 vertexTangent;out vec3 worldPosition;
out vec3 worldNormal;
out vec4 worldTangent;
out vec2 texCoord;
out vec2 movtexCoord;
out vec2 multexCoord;
out vec2 waveTexCoord;
out vec2 skyTexCoord;
out vec3 vpos;uniform mat4 modelMatrix;
uniform mat3 modelNormalMatrix;
uniform mat4 mvp;uniform float offsetx;
uniform float offsety;
uniform float vertYpos;
uniform float texCoordScale;
uniform float waveheight;
uniform float waveRandom;void main()
{// 为片段着色器缩放纹理坐标//纹理比例滑块//将顶点着色器内的纹理坐标相乘。 控制水面上纹理的大小。texCoord = vertexTexCoord * texCoordScale;movtexCoord = vertexTexCoord * texCoordScale;multexCoord = vertexTexCoord * (texCoordScale*0.5);waveTexCoord = vertexTexCoord * (texCoordScale * 6);skyTexCoord = vertexTexCoord * (texCoordScale * 0.2);// 将动画 x 和 y 偏移添加到 SKY、MOV 和 MUL texCoordsmovtexCoord = vec2(texCoord.x+offsetx,texCoord.y+offsety);multexCoord = vec2(texCoord.x-offsetx,texCoord.y+offsety);skyTexCoord = vec2(texCoord.x-(offsetx/2),texCoord.y-(offsety/2));// 将位置、法线和切线转换为世界坐标worldPosition = vec3(modelMatrix * vec4(vertexPosition, 1.0));worldNormal = normalize(modelNormalMatrix * vertexNormal);worldTangent.xyz = normalize(vec3(modelMatrix * vec4(vertexTangent.xyz, 0.0)));worldTangent.w = vertexTangent.w;// 计算动画顶点位置float sinPos = (vertexPosition.z)+(vertexPosition.x);float sinPos2 = (vertexPosition.y/2)+(vertexPosition.z);vec3 vertMod = vec3(vertexPosition.x,vertexPosition.y,vertexPosition.z);vertMod = vec3(vertMod.x+=sin(vertYpos*2.2-sinPos2)*waveheight,vertMod.y=sin(vertYpos*2.2+sinPos)*waveheight,vertMod.z-=sin(vertYpos*2.2-cos(sinPos2))*waveheight);vec3 vertModCom = vec3(vertMod.x+=cos(vertYpos*2.2-cos(sinPos2))*waveheight,vertMod.y=sin(vertYpos*2.2+cos(sinPos))*waveheight,vertMod.z-=cos(vertYpos*2.2-cos(sinPos))*waveheight);// 仅向世界 pos.y 零上方的顶点添加波浪动画if(vertexPosition.y < 0.0){vertModCom = vertexPosition;}else{vertModCom = vertModCom;}vpos = vertModCom;// 计算剪辑坐标中的顶点位置gl_Position = mvp * vec4(vertModCom, 1.0);
}

water.frag

#version 150 corein vec3 worldPosition;
in vec3 worldNormal;
in vec4 worldTangent;
in vec2 texCoord;
in vec2 waveTexCoord;
in vec2 movtexCoord;
in vec2 multexCoord;
in vec2 skyTexCoord;in vec3 vpos;in vec3 color;uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture;
uniform sampler2D normalTexture;
uniform sampler2D waveTexture;
uniform sampler2D skyTexture;
uniform sampler2D foamTexture;uniform float offsetx;
uniform float offsety;
uniform float specularity;
uniform float waveStrenght;
uniform vec4 ka;
uniform vec3 specularColor;
uniform float shininess;
uniform float normalAmount;
uniform vec3 eyePosition;out vec4 fragColor;#pragma include phong.inc.frag
#pragma include coordinatesystems.incvoid main()
{//移动 waveTexCoords//纹理速度滑块//在advancedcustommaterial/Water.qml 中设置动画然后传//递给顶点着色器的纹理坐标的偏移值。 创建纹理在表面上滚动的效果。vec2 waveMovCoord = waveTexCoord;waveMovCoord.x += offsetx;waveMovCoord.y -= offsety;vec4 wave = texture(waveTexture, waveMovCoord);//失真//将片段着色器中波浪纹理的红色和蓝色通道中的偏移量相乘。 使表面纹理更加随机。//通过waveTexture的r和b颜色摆动newCoordvec2 newCoord = texCoord;newCoord.x += wave.r * waveStrenght;newCoord.y -= wave.b * waveStrenght;// 在插值的 texCoords 处采样纹理// 使用默认的 texCoord 进行漫反射(它不会在 x 或 y 上移动,因此可以用作“水下地面”)。vec4 diffuseTextureColor = texture(diffuseTexture, texCoord);// 2 个与 newCoord 混合的镜面纹理动画层vec4 specularTextureColor = texture( specularTexture, multexCoord+newCoord) + (texture( specularTexture, movtexCoord+newCoord ));// 2 个动画层的 normalTexture 与 newCoord 混合//Normal amount//将片段着色器内的法线贴图值相乘。 控制水面上较小波浪的可见性。vec3 tNormal = normalAmount * texture( normalTexture, movtexCoord+newCoord ).rgb - vec3( 1.0 )+(normalAmount * texture( normalTexture, multexCoord+newCoord ).rgb - vec3( 1.0 ));// 动画天空纹理层vec4 skycolor = texture(skyTexture, skyTexCoord);skycolor = skycolor * 0.4;//动画foamTexture层vec4 foamTextureColor = texture(foamTexture, texCoord);mat3 tangentMatrix = calcWorldSpaceToTangentSpaceMatrix(worldNormal, worldTangent);mat3 invertTangentMatrix = transpose(tangentMatrix);vec3 wNormal = normalize(invertTangentMatrix * tNormal);vec3 worldView = normalize(eyePosition - worldPosition);vec4 diffuse = vec4(diffuseTextureColor.rgb, vpos.y);//将片段着色器内的镜面反射纹理值相乘。 使水反射。vec4 specular = vec4(specularTextureColor.a*specularity);vec4 outputColor = phongFunction(ka, diffuse, specular, shininess, worldPosition, worldView, wNormal);outputColor += vec4(skycolor.rgb, vpos.y);outputColor += (foamTextureColor.rgba*vpos.y);fragColor = vec4(outputColor.rgb,1.0);
}

这篇关于Qt例子学习笔记 - Examples/Qt-6.2.0/qt3d/advancedcustommaterial的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900433

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个