動画であそぼう: シェーダーエフェクトとマルチメディア
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.8 Now!
Download the latest release here: www.qt.io/download.
Qt 6.8 release focuses on technology trends like spatial computing & XR, complex data visualization in 2D & 3D, and ARM-based development for desktop.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.