Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

用ShaderEffectItem为应用加入特效

From Wiki
Jump to: navigation, search

Delete instructional text in italic

This article explains how to ... Replace the abstract text with a short paragraph (or sentence) describing what the topic covers.

Enter article metadata as described below. Note that this template can be placed anywhere in the article. Do not remove parameters that you do not use

Article Metadata
Article
Created: ()
Last edited: hamishwillee (13 Jun 2012)

Contents

Introduction

Meego 1.2 Harmattan支持Qt Shaders, 关于在Meego中使用Shaders的详情可以参考使用Shaders, Shader 的使用可以使应用界面更加灵动,达到很多我们在3D中才能实现的效果。目前一些Symbian手机未加入GPU硬件,可能并不支持openGL。
ShaderEffectItem就是一个简单的带着定制化顶点和片段着色器的矩形。传给顶点着色器的顶点来自于通过定义在元素中的 “width”和“height”属性计算出的矩形的角 (还有一个属性可以让你来把矩形切分成多个行和列,不过默认情况下,只有4个顶点)。ShaderEffectItem中可以在QML元素上定义自己的属性,然后这些属性就可以在着色器的代码中做为 uniform变量使用。比如,你可以定义一个“real”类型的“color”属性,然后在QML中进行动态变化,在着色器代码中,这个属性可以做为 “uniform vec4 float”类型来读取。这一特性支持的类型包括:real、point、size、color、vector3d以及一个新类型:ShaderEffectSource,这个类型对应着色器代码中的“sampler2D”类型。ShaderEffectSource可以把一个 QML元素渲染成一个OpenGL材质,然后传给ShaderEffectItem。ShaderEffectSource有一些独有属性比如包装模式 (wrap mode)和MIP贴图(mipmapping),以及需要渲染的QML元素的引用。同时多个ShaderEffectItem元素还可以通过让一个做为另一个的渲染源的方式串接起来。 ShaderEffectItem是个很强大的功能,不过正如所有其它强大的事物一样,你要小心使用它。一个写得很糟糕的着色器或者一次性激活太多的特效,将会很容易地大幅降低性能,至少是在移动或者嵌入式设备上是如此。

实现一个简单的例程

在这个例程中,使一幅背景图片具有雨点打击到水面时水波扩散的效果,并且使文字具有被扭曲的效果,如图片所示。 Shadereffect.png
为了使Shader能发挥作用,我们必须用到openGL库,使QGLWidget 作为 QDeclarativeView的viewport,使opengl作为应用的Graphic System,所以在pro文件中加入Qt+= opengl,在main函数中设置viewport和Graphic system.

Q_DECL_EXPORT int main(int argc, char *argv[])
{
QApplication::setGraphicsSystem("opengl");
QScopedPointer<QApplication> app(createApplication(argc, argv));
QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());
 
viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer->setMainQmlFile(QLatin1String("qml/testshadereffects/main.qml"));
viewer->setViewport(new QGLWidget());
viewer->showExpanded();
return app->exec();
}
定义你想要实现特效的元素对象作为ShaderEffectSource
<code>
ShaderEffectSource{
id:sourceItem
sourceItem:Image{source:"images/bg.jpg"} //
...
}
//或者直接在定义source 属性加入ShaderEffectSource
property variant source: ShaderEffectSource { sourceItem: textLabel; hideSource: true }

在ShaderEffectItem中定义要在Shader编程中使用的属性

     property variant source: sourceItem
property real wave: 0.0 //波峰与原点的距离
property real waveWidth: 0.1 //波纹的宽度
property real waveOriginX:0.5 //波形产生的原点坐标
property real waveOriginY:0.5
property real aspectRatio:width/height //

然后在ShaderEffectItem的fragmentShader 和vertexShader属性进行Shader编程,本文使用了ShaderEffectItem默认的vertextshader。

   fragmentShader:
"
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform highp float waveWidth;
uniform highp float waveOriginX;
uniform highp float waveOriginY;
uniform highp float wave;
uniform highp float aspectRatio;
void main(void)
{
mediump vec2 texCoord2 = qt_TexCoord0;
mediump vec2 origin = vec2(waveOriginX, (1.0 - waveOriginY) / aspectRatio);
 
highp float fragmentDistance = distance(vec2(texCoord2.s, texCoord2.t / aspectRatio), origin);
highp float waveLength = waveWidth + fragmentDistance * 0.25;
 
if ( fragmentDistance > wave && fragmentDistance < wave + waveLength) {
highp float distanceFromWaveEdge = min(abs(wave - fragmentDistance), abs(wave + waveLength - fragmentDistance));
texCoord2 += sin(1.57075 * distanceFromWaveEdge / waveLength) * distanceFromWaveEdge * 0.08 / fragmentDistance;
}
 
gl_FragColor = texture2D(source, texCoord2.st);
}
"

文字扭曲的效果参考自Qt的帮助文档

 fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
uniform highp float wiggleAmount;
void main(void)
{
highp vec2 wiggledTexCoord = qt_TexCoord0;
wiggledTexCoord.s += sin(4.0 * 3.141592653589 * wiggledTexCoord.t) * wiggleAmount;
gl_FragColor = texture2D(source, wiggledTexCoord.st);
}
"

可以在这里Media:Testshadereffects.zip下载源码。在Windows 桌面环境和Meego 1.2环境下测试运行。 我相信理解ShaderEffectItem并不难,对大部分没有shader编程经验的人来说,学习Shader编程并实现一些纹理需要些时间,作者也才开始探索。目前的手机终端配置越来越高而且成为一种趋势,在手机终端的应用加入3D效果,为用户提供丰富多彩的应用界面成为目标,QML中的ShaderEffectItem简单易用是不错的选择。

相关连接

参考资料

Add categories below. Remove Category:Draft when the page is complete or near complete

This page was last modified on 13 June 2012, at 10:59.
175 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×