Qt3D的研究(四):指定渲染的材质以及效果

在上一篇文章中我了解到了怎样简单地显示模型。Qt3D内置了一个obj模型的解析器,这样可以将简单的obj模型载入并且显示出来。其实Qt3D对于渲染的配置还是很厉害的,通过设定材质,我们可以得到很不错的渲染效果,而且可以通过设定Effect,将自己指定的着色器载入,让Qt 3D和OpenGL进行编译,得到自己想要的渲染效果。

蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/43983493。欢迎同行前来探讨。

在上一篇文章介绍的QML代码的基础上,我们简单地添加一个材质。代码如下:

    Entity
    {
        Mesh
        {
            id: mesh
            objectName: "toyPlane"
            source: "qrc:/toyplane.obj"
        }

        //! [4]
        PhongMaterial
        {
            id: phongMaterial
        }
        //! [4]

        components: [ mesh, phongMaterial ]
    }

运行结果如下:

这里我们在//! [4]之间添加了一个常用的材质:Phong材质。Phong光照模型是一种常见的光照模型,他揭示了生成高光的方法。以前我的博客也介绍并且实现了这样的光照模型。之所以它的广泛性,Qt 3D将其封装了一个类,方便操作。图中显示的是使用Phong光照模型,让玩具飞机呈现光滑透明的效果。我们也可以设定具体的参数,让光照呈现不同的效果:设定全局光(ambient)、漫反射(diffuse)、镜面反射(specular)以及自发光亮度(shininess)。添加的代码如下所示:


import Qt3D 2.0
import Qt3D.Render 2.0

Entity
{
    id: root

    Camera
    {
        id: camera
        position: Qt.vector3d( 0.0, 0.0, 40.0 )
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 45
        aspectRatio: 16.0 / 9.0
        nearPlane : 0.1
        farPlane : 1000.0
        upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
        viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
    }

    components: FrameGraph
    {
        ForwardRenderer
        {
            clearColor: Qt.rgba( 0, 0, 0, 1 )
            camera: camera
        }
    }

    Entity
    {
        Mesh
        {
            id: mesh
            objectName: "toyPlane"
            source: "qrc:/toyplane.obj"
        }

        //! [4]
        PhongMaterial
        {
            id: phongMaterial
            ambient: Qt.rgba( 0.6, 0.2, 0.1, 1 )
            diffuse: Qt.rgba( 0.2, 0.6, 0.1, 1 )
            specular: Qt.rgba( 0.2, 0.9, 0.1, 1 )
            shininess: 0.6
        }
        //! [4]

        components: [ mesh, phongMaterial ]
    }

    Configuration
    {
        controlledCamera: camera
    }
}

程序运行结果如下所示:

这里呈现了一个金光闪闪的玩具飞机模型。

如果我们想自己写着色器来为我们的模型着色,Qt 3D也提供了相应的方法,可以不借助C++代码来实现,直接在QML指定即可。这里我们需要设定Effect(效果)、Technique(使用的OpenGL技术)、RenderPass(渲染遍数)、ShaderProgram(着色器)。下面是QML代码:


import Qt3D 2.0
import Qt3D.Render 2.0

Entity
{
    id: root

    Camera
    {
        id: camera
        position: Qt.vector3d( 0.0, 0.0, 40.0 )
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 45
        aspectRatio: 16.0 / 9.0
        nearPlane : 0.1
        farPlane : 1000.0
        upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
        viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
    }

    components: FrameGraph
    {
        ForwardRenderer
        {
            clearColor: Qt.rgba( 0, 0, 0, 1 )
            camera: camera
        }
    }

    Entity
    {
        Mesh
        {
            id: mesh
            source: "qrc:/toyplane.obj"
        }

        //! [5]
        Material
        {
            id: material
            effect: effect

            Effect
            {
                id: effect
                techniques: [ technique ]

                Technique
                {
                    id: technique
                    openGLFilter
                    {
                        api: OpenGLFilter.Desktop
                        profile: OpenGLFilter.None
                        majorVersion: 2
                        minorVersion: 0
                    }

                    renderPasses: [ renderPass ]

                    RenderPass
                    {
                        id: renderPass
                        shaderProgram: simpleSP

                        ShaderProgram
                        {
                            id: simpleSP
                            vertexShaderCode: loadSource( "qrc:/Simple.vert" )
                            fragmentShaderCode: loadSource( "qrc:/Simple.frag" )
                        }
                    }
                }
            }
        }
        //! [5]

        components: [ mesh, material ]
    }

    Configuration
    {
        controlledCamera: camera
    }
}

代码新添加的部分在//! [5]中。这里我们没有使用默认的PhoneMaterial,而是使用它的父类Material,并且通过指定Effect来实现自己需要的渲染效果。Effect中含有的Technique表示使用的OpenGL技术,因为OpenGL有多个版本,分OpenGL和OpenGL ES,还分core profile和compatibility profile,这样使得种种技术变得十分繁杂。所以Qt 3D提出了Technique这个概念。通过指定api、profile以及majorVersion和minorVersion版本,来使用我们需要的OpenGL
API。接着是RenderPass渲染遍(这个翻译总感觉不好),它表示一次渲染需要多少遍渲染操作。比如说在shadow map这个技术中,需要渲染不止一遍,所以要指定两个RenderPass。而每一遍的RenderPass,需要指定着色器程序。因此,我们载入相应的着色器文件,来让系统编译以及链接之,最后得以渲染。本例中,我们实现一个最简单的着色器Simple.vert以及Simple.frag,他们如下所示:


// Simple.vert
#version 100

attribute vec3 vertexPosition;
uniform mat4 mvp;

void main( void )
{
    gl_Position = mvp * vec4( vertexPosition, 1.0 );
}
// Simple.frag
#version 100

void main( void )
{
    gl_FragColor = vec4( 1.0, 0.8, 0.2, 1.0 );
}

这里需要说明的是,Qt 3D在MeshData中指定了默认的属性(attribute)变量和一致性(uniform)变量,它们如下:


属性(attribute)变量


一致性(uniform)变量


vertexPosition


modelMatrix


vertexTexCoord


viewMatrix


vertexNormal


projectionMatrix


vertexColor


modelView


vertexTangent


modelViewProjection


 


mvp


 


inverseModelMatrix


 


inverViewMatrix


 


inverseProjectionMatrix


 


inverseModelView


 


inverseModelViewProjection


 


modelNormalMatrix


 


modelViewNormal


 


viewportMatrix


 


inverseViewportMatrix


 


time

※这些变量并没有在文档中列出,可能随着版本的变化而变得不同

这是一个非常简单的着色器,它以单色输出。下面是运行截图:

通过逐渐丰富着色器的内容,可以让程序获取更加美妙的渲染效果。

时间: 2024-08-30 09:03:53

Qt3D的研究(四):指定渲染的材质以及效果的相关文章

[WebGL入门]四,渲染准备

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正. 必须准备的东西 上次介绍了3D绘图的基础知识.讲了一下由Z坐标的不同决定的两种坐标系,以及坐标变换的种类.这一次,说一说实际WebGL绘图的时候必须准备的东西. 首先,HTML,javascript相关的基础知识就不解释了.如果,有不明白的单词或概念的话,请自己查一下.我是认为你有一定的HTM

画线缩放、瞳距缩放、Line延长到指定长度,内附效果,源码供应,解压就跑

原文:画线缩放.瞳距缩放.Line延长到指定长度,内附效果,源码供应,解压就跑 前言 公司项目需要做个画线缩放,我司称之为瞳距缩放,简而言之就是:2张图,从第一张图画一条线,再从第二个图画一条线,第二条线以第一条为基准,延长到一致的长度,并同比缩放图片:文字太枯燥,请先实例图 例子1:以皮卡丘为例,我要把路飞的拳头缩放到皮卡丘头那么大 例子2:以皮卡丘的基准,缩小路飞,与其身高一致 好了,相比看了上面的2个效果图,就明白了大致意思,这个demo可以获得,Canvas里面的Line如何顺着线条方向

需求分析:用户需求研究四要素

用户真相是什么?无疑是最难的环节.作为产品经理,天天都在围绕吃透用户真相运转.但是总是会出现对于用户的需求过于自信,大多时候以参与人员为蓝本,研究结果远离用户真相,形成了"产品经理人体验","运营人员体验","领导人体验"等.作为产品经理,在每细化一个需求时,大家有跳出产品人经验,深挖过需求的背后吗? 真正的用户研究应该建立在以用户为中心的逻辑上,对于用户的每一个确定要做的需求都能形成一个闭环,回到产品需求上. 产品经理应该据有透过表面挖本质的能

王爽-汇编语言-综合研究四-不使用main函数编程

(一) 研究目的 使用C语言编程,我们一定要使用main函数么? (二) 研究过程 1) 最初的程序 首先,我们编写一个不写main函数的C语言程序. 程序如下: 在编译的过程中,没有发现错误.在链接的过程中发现出现的错误如下: 链接时出现Undefined symbol ‘_main’ in module c0s 这样的错误信息,可能main函数与c0s.obj这个文件有关系. 这时我们想,C语言编译之后的文件后缀名是什么?是.obj.那汇编语言编译后的文件名是什么?也是.obj.这两个文件有

CEF3研究(四)之javascript集成

一.介绍 谷歌浏览器和CEF使用V8JavaScript Engine作为内容的JavaScript实现.在浏览器中的每个窗口都有它自己在的JS上下文提供作用域和在窗口中安全的执行JS代码.CEF暴露大量JS功能集成在客户端应用程序.CEF3的Webkit和JS在单独的渲染进程中运行.在渲染进程的主线程中使用TID_RENDERER 作为唯一标识.所有V8的执行必须放置在这个线程中.与JS执行相关的回调函数被暴露是通过CefRenderProcessHandler接口实现.当一个新的渲染进程被初

Chrome自带恐龙小游戏的源码研究(四)

在上一篇<Chrome自带恐龙小游戏的源码研究(三)>中实现了让游戏昼夜交替,这一篇主要研究如何绘制障碍物. 障碍物有两种:仙人掌和翼龙.仙人掌有大小两种类型,可以同时并列多个:翼龙按高.中.低的随机飞行高度出现,不可并行.仙人掌和地面有着相同的速度向左移动,翼龙则快一些或慢一些,因为添加了随机的速度修正.我们使用一个障碍物列表管理它们,当它们移出屏幕外时则将其从列表中移除.同时再用一个列表记录它们的类型: 1 Obstacle.obstacles = []; //存储障碍物的数组 2 Obs

关于园子客户端实现的研究四

接着学习研究制作:关于园子客户端实现的研究一 这篇博文不讲技术方面的东西,纯粹的界面学习 1.经过一线码农的辛苦劳作,终于可以看到界面了: >头部是共用的布局,通过include加载到每一个页面 >首页是个GridView控件,充当了大家常用的底部菜单 >“被自己帅醒”是个小动画,网上找的图画 >列表ListView页显示了部分数据,感觉不是很美观 >内容详细页相当凑合,就是一个WebView显示网页链接,适配什么的木有 >博友搜索界面还要优化,显示太简单了 2.从前天

关于多核游览器指定渲染内核的方法。

代码示例 在head标签中添加一行代码: 1 <html> 2 <head> 3 <meta name="renderer" content="webkit|ie-comp|ie-stand"> 4 </head> 5 <body> 6 </body> 7 </html> content的取值为webkit,ie-comp,ie-stand之一,区分大小写,分别代表用webkit内核

外挂辅助技术研究-打开指定NPC对话

1.打开指定NPC对话功能 DWORD GetNpcObjForName(char* szpNpcName); DWORD OpenNpcTalkForName(char* szpNpcName); //获取指定NPC对象 push 0 push 0 push 0x401 mov ecx,2DF25598 //NPC对象地址 mov eax,[ecx] mov eax,[eax+4]  //打开NPC,测试通过 call eax push 3 mov ecx,0XF598C0 mov ecx,[