動画であそぼう: シェーダーエフェクトとマルチメディア
3月 05, 2012 by 鈴木 佑 | Comments
この記事は Qt Blog の "Pimp my video: shader effects and multimedia" を翻訳したものです。
執筆: Gareth Stockwell, 2012年2月29日
はじめに
Qt Quick のアプリケーションでのシェーダー言語によるエフェクトが注目を集めてきています。シェーダー言語の基本さえ分かってしまえば、Qt Quick のアプリケーションにシェーダーを埋め込むのは本当に簡単で、素晴らしいビジュアルエフェクトが驚くほど少ないソースコードで実現できます。
今までブログでは取り上げてきませんでしたが、(動画再生やカメラの映像などの)マルチメディアのコンテンツへのシェーダーエフェクトの適用も、他の QML 要素と同様に簡単にできます。この記事は QtMultimedia とシェーダーの組み合わせについて紹介したいと思います。
どのようなエフェクトが使用できるかは、デモを見てもらうのが一番です。ということでこの動画からはじめましょう。
qmlvideofx デモ: デスクトップ Linux 上の Qt 5 |
この動画は Qt Quick 2 のデモアプリで、デスクトップの Linux で動いています。(フレームレートを計算するためにシーングラフのシグナルを監視したり、ファイルからシェーダーを読み込むための)補助的な C++ のコードを除くと、このアプリはすべて QML で書かれています。
詳細
以前に紹介したとおり、Qt Quick 2 では QML の ShaderEffect 要素を通してシェーダーエフェクトをサポートしています。これを動画やカメラのファインダーに対して適用するのは他の QML の要素に対して適用するのとなにも変わりません。以下のコードでは動画ファイルの再生にゆらめき効果を適用した例です。
import QtQuick 2.0
import QtMultimedia 5.0Rectangle {
width: 600
height: 400MediaPlayer {
id: mediaPlayer
autoplay: true
source: "test.ogg"
}VideoOutput {
id: videoOutput
anchors.fill: parent
source: mediaPlayer
}ShaderEffect {
anchors.fill: parent// Properties which will be passed into the shader as uniforms
property real amplitude: 0.02
property real frequency: 20
property real time: 0NumberAnimation on time {
loops: Animation.Infinite
from: 0
to: Math.PI * 2
duration: 600
}property variant source: ShaderEffectSource {
sourceItem: videoOutput
hideSource: true
}fragmentShader: "
uniform highp float amplitude;
uniform highp float frequency;
uniform highp float time;
uniform sampler2D source;
uniform lowp float qt_Opacity;
varying highp vec2 qt_TexCoord0;
void main() {
highp vec2 p = sin(time + frequency * qt_TexCoord0);
highp vec2 tc = qt_TexCoord0 + amplitude * vec2(p.y, -p.x);
gl_FragColor = qt_Opacity * texture2D(source, tc);
}
"
}
}
動画再生の代わりにカメラのファインダーに対してエフェクトを適用するには、ただ単に Video 要素を Camera 要素に替えるだけです。
今回の qmlvideofx のデモでは、それぞれのエフェクトは ShaderEffect を継承した QML の要素として実装されていて、メニューでエフェクトが切り替えられた場合に、これらの要素を動的に読み込み適用するようになっています。それぞれのソース(画像、動画、カメラ)も同様に QML 要素になっていて、必要に応じて動的に読み込んでいます。
それぞれのエフェクトのパラメーター(Pixelate の 'granularity' や Magnify の 'radius' と 'diffraction' など)は ListModel として実装していて、スライダーを作成するのに使われています。これによってパラメーターの値が変更できるようになっています。
コード(Qt 5.x)
qmlvideofx のデモは qtmultimedia リポジトリの中にすでに含まれています。
https://qt.gitorious.org/qt/qtmultimedia/trees/master/examples/video/qmlvideofx
Qt 5.0 がリリースされるまでは、自分でソースコードからビルドしてこのデモを試す必要があります。この手順は こちらの Wiki ページ にまとまっています。このデモを動かすために必要な Qt のモジュールだけをクローンする場合、以下のようにすることもできます。
$QTDIR/init-repository --module-subset=qtbase,qtdeclarative,qtjsbackend,qtmultimedia,qtxmlpatterns
コード(Qt 4.x)
Qt Quick 1 自体ではシェーダーエフェクトをサポートしていませんが、Qt 4.7.4 以降に含まれる Qt.labs.shaders プラグインを使うことで利用可能です。Qt 4 でのデモは以下から取得してください。
https://qt.gitorious.org/qt-mobility/qt-mobility/trees/master/demos/video/qmlvideofx
デスクトッププラットフォームでの動作(Linux と Windows で確認)に加えて、Qt 4 版のデモはモバイル端末上でも動作するでしょう。以下の動画は、Symbian 端末(Nokia 701)で動かしてみたものです。
qmlvideofx デモ: Symbian(Nokia 701) 上の Qt 4 |
デスクトップ版とほんの少し UI が異なることに気づいた方もいるでしょう。柔軟な Qt Quick のおかげで、レイアウト用の QML ファイルを1つ差し替えただけでこれはできました。
ここで注意が必要です。このアプリは現在の Symbian プラットフォームのバージョンでは動作しません。これは動画のデコーダーの出力結果を OpenGL ES でテクスチャとして扱える必要があるためです。動画とグラフィックススタックをこのように連携させるための EGL 拡張(EGL_NOK_image_endpoint2) が今後の Symbian のリリースに追加される予定です。これがリリースされた場合には QtMultimediaKit は自動的に対応するため(QTMOBILITY-1818)、このデモも動作するでしょう。
一方、Nokia N9 では現時点でも動作します。以下の動画を御覧下さい。
qmlvideofx デモ: MeeGo Harmattan(Nokia N9) 上の Qt 4 |
おわりに
今までシェーダーエフェクトの素晴らしさに気づいていなかった方も、この記事で納得してもらえたらいいなと思います。最後に関連するコンテンツへのリンクを貼っておきます。
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.9 Now!
Download the latest release here: www.qt.io/download.
Qt 6.9 is now available, with new features and improvements for application developers and device creators.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.