文章目录
Wireframe 效果
该程序,实现了一种单通道线框渲染方法,用自己的着色器来实现渲染。
代码阅读
代码结构
main.qml
import QtQuick 2.1 as QQ2
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
Entity {
id: root
// Render from the mainCamera
components: [
RenderSettings {
activeFrameGraph: ForwardRenderer {
id: renderer
camera: mainCamera
}
},
// Event Source will be set by the Qt3DQuickWindow
InputSettings { }
]
BasicCamera {
id: mainCamera
position: Qt.vector3d( 0.0, 0.0, 15.0 )
}
FirstPersonCameraController { camera: mainCamera }
WireframeMaterial {
id: wireframeMaterial
effect: WireframeEffect {}
ambient: Qt.rgba( 0.2, 0.0, 0.0, 1.0 )
diffuse: Qt.rgba( 0.8, 0.0, 0.0, 1.0 )
QQ2.SequentialAnimation {
loops: QQ2.Animation.Infinite
running: true
QQ2.NumberAnimation {
target: wireframeMaterial;
property: "lineWidth";
duration: 1000;
from: 0.8
to: 1.8
}
QQ2.NumberAnimation {
target: wireframeMaterial;
property: "lineWidth";
duration: 1000;
from: 1.8
to: 0.8
}
QQ2.PauseAnimation { duration: 1500 }
}
}
TrefoilKnot {
id: trefoilKnot
material: wireframeMaterial
}
}
WireframeMaterial.qml //
import Qt3D.Core 2.0
import Qt3D.Render 2.0
Material {
id: root
property color ambient: Qt.rgba( 0.05, 0.05, 0.05, 1.0 )
property color diffuse: Qt.rgba( 0.7, 0.7, 0.7, 1.0 )
property color specular: Qt.rgba( 0.95, 0.95, 0.95, 1.0 )
property real shininess: 150.0
property real lineWidth: 0.8
property color lineColor: Qt.rgba( 0.0, 0.0, 0.0, 1.0 )
parameters: [
Parameter { name: "ka"; value: Qt.vector3d(root.ambient.r, root.ambient.g, root.ambient.b) },
Parameter { name: "kd"; value: Qt.vector3d(root.diffuse.r, root.diffuse.g, root.diffuse.b) },
Parameter { name: "ksp"; value: Qt.vector3d(root.specular.r, root.specular.g, root.specular.b) },
Parameter { name: "shininess"; value: root.shininess },
Parameter { name: "line.width"; value: root.lineWidth },
Parameter { name: "line.color"; value: root.lineColor }
]
}
WireframeEffect.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
Effect {
id: root
parameters: [
Parameter { name: "ka"; 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 ) },
Parameter { name: "line.width"; value: 1.0 },
Parameter { name: "line.color"; value: Qt.vector4d( 1.0, 1.0, 1.0, 1.0 ) }
]
renderPasses: [
RenderPass {
shaderProgram: ShaderProgram {
vertexShaderCode: loadSource("qrc:/shaders/robustwireframe.vert")
geometryShaderCode: loadSource("qrc:/shaders/robustwireframe.geom")
fragmentShaderCode: loadSource("qrc:/shaders/robustwireframe.frag")
}
}
]
}
]
}
TrefoilKnot.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
Entity {
id: root
property real x: 0.0
property real y: 0.0
property real z: 0.0
property real scale: 1.0
property real theta: 0.0
property real phi: 0.0
property Material material
components: [ transform, mesh, root.material ]
Transform {
id: transform
translation: Qt.vector3d(root.x, root.y, root.z)
rotation: fromEulerAngles(theta, phi, 0)
scale: root.scale
}
Mesh {
id: mesh
source: "assets/obj/trefoil.obj"
}
}
BasicCamera.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
Camera {
id: mainCamera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 22.5
aspectRatio: _window.width / _window.height
nearPlane: 0.01
farPlane: 1000.0
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
}
二、涉及组件学习
FirstPersonCameraController
允许从第一人称视角控制场景摄影机。
Properties
acceleration : real
camera : Camera
deceleration : real
linearSpeed : real
lookSpeed : real
控制:
输入 | 行为 |
---|---|
鼠标左键 | 按下鼠标左键时,鼠标沿x轴移动会平移相机,沿y轴移动会使相机倾斜。 |
Shift 键 | 按下时激活精细运动控制。使鼠标的平移和倾斜不那么敏感。 |
方向键 | 相对于“摄影机”视口水平移动摄影机 |
上下翻页键 | 相对于摄影机视口垂直移动摄影机。 |
Material
Material提供了一种实体渲染的方法。任何aspect都可以定义自己的Material子类型,以便Material可以用来描述视觉元素;例如,声音在元素上的反射方式、表面温度等等。
Material本身没有任何作用。只有在引用Effect 节点时,Material才会变得有用。
在实践中,一个Effect经常被多个材质组件引用。这样只创建一次effect、techniques、passes和shaders,可以同时被多个实例指定材质。
Material上定义的参数将被TechniqueFilter或RenderPassFilter中定义的参数(同名)覆盖。
Properties
effect : Effect
parameters : list //参数列表
Effect
Effect 结合了使用的一组techniques 和parameters ,以生成材质的渲染效果。
如果可能,效果实例应在多个Material实例之间共享。
Effect上定义的参数由材Material、TechniqueFilter、RenderPassFilter中定义的QParameter(同名)覆盖。
注意:不能禁用Effect。
Properties
parameters : list
techniques : list
Technique
Technique指定一组RenderPass对象、FilterKey对象、Parameter对象和GraphicsAPI过滤器,它们共同定义了渲染用那种opengl 技术。因为OpenGL有多个版本,分OpenGL和OpenGL ES,还分core profile和compatibility profile,这样使得种种技术变得十分繁杂。所以Qt 3D提出了Technique这个概念。通过指定api、profile以及majorVersion和minorVersion版本,来使用我们需要的OpenGL API。
TechniqueFilter使用过滤键在帧图的特定部分选择特定Technique。如果在Technique和RenderPass中指定了两个同名的参数实例,则Technique中的参数实例将覆盖RenderPass中使用的参数实例。
当opengl存在多个版本时,创建多个Technique节点非常有用,每个节点都设置了GraphicsAPI过滤器,以匹配其中一个目标版本。在运行时,Qt3D渲染器将根据支持的图形API版本和(如果指定)满足帧图中给定TechniqueFilter的FilterKey节点选择最合适的技术。
注意:当使用OpenGL作为图形API进行渲染时,Qt3D依赖运行时QSurfaceFormat::defaultFormat()返回的QSurfaceFormat来决定可用的最合适的GL版本。如果需要自定义QSurfaceFormat,请不要忘记使用QSurfaceFormat::setDefaultFormat()。在视图上设置QSurfaceFormat可能对Qt3D相关渲染没有影响。
Properties
filterKeys : list
graphicsApiFilter : GraphicsApiFilter
parameters : list
renderPasses : list
RenderPass
RenderPass指定该Technique使用的单个渲染过程(着色器程序执行的实例)。渲染过程由一个着色器程序和一个FilterKey对象列表、一个RenderState对象列表和一个Parameter对象列表组成。
Properties
filterKeys : list
parameters : list
renderStates : list
shaderProgram : ShaderProgram
Parameter
Parameter可以由RenderPass、Technique、Effect、Material、TechniqueFilter、RenderPassFilter引用。在运行时,根据为渲染的给定步骤选择的着色器,如果着色器包含名称与参数名称匹配的uniform ,则参数中包含的值将被引用。
三、总结
该demo,trefoilKnot(Entity)从模型中加载,然后自定实现Material渲染Entity。QMl 实现了与 顶点着色器、片段着色器,几何着色器的交互。本章需要深度理解。