LoginSignup
9

More than 1 year has passed since last update.

Mac + pyOpenGLでシェーダーアニメーション描く

Last updated at Posted at 2018-06-05

はじめに

ご覧になった方も多いかと思います。macOS 10.14のOpenGLへのDeprecation
What’s New in macOS(10.14で変わったこと)
Macでの今後のoFの対応、諸々のアプリ開発者の不安が囁かれていますが...
私も今朝、まさにopenGLをpythonで動かしていたこともあり、
ニーズアピールの意味も込めてサンプルをアップします。

できること

LiveCoding用のソフトを使わず、
python のみで GLSL sandboxにあるような時間変化するシェーダープログラムを実行できる。
意外とLiveCodingのように動くpythonコードがなかったです。

環境

  • MacBook Pro (2.7 GHz Intel Core i5,16 GB 1867 MHz DDR3)
  • macOS Sierra
  • python 2.7

手順

環境構築

インストールはnumpyなどの基本的なものを除けば、以下の2つです。

brew install glfw
pip install PyOpenGL

PyOpenGLがpipで入らない場合は、ここを頼りに手で入れましょう。

実装コードはこちらに置いてあります。

git clone https://github.com/mizumasa/pyShaderSample.git
cd pyShaderSample
python shader_loop.py shader_loop.vert shader_loop.frag

import でエラーが出た時

Big Sur 以降、確実にインストールそのままではエラーが出ます

こちらの対策で使えるようになる可能性が高いです。
(2021/11更新 M1 macOS Monterey でもこの修正をすれば使えました!)

コード説明

pyOpenGLでシェーダープログラミングこちらを参考に書きました。
不要な部分などあるかもしれませんが、とりあえずこれで動きます。

重要な部分としては DrawGLScene()の中で毎回呼ばれている、time 変数への値の送信です。

shader_loop.py
glUniform1f( glGetUniformLocation( program, "time" ), time.time() - startTime)

このように time 変数を、毎回描画時にtime.time()関数などの値を利用して更新してあげると、時間変化のあるシェーダープログラムが実行できます。
簡潔に書くために、program変数はglobal化してしまいました。

続いて、シェーダー本体を見ていきます。

shader_loop.frag
uniform float texture_width;
uniform float texture_height;
uniform float time;

void main() {
    vec2 resolution = vec2( texture_height, texture_width );
    vec2 uv = -1. + 2. * gl_FragCoord.xy / resolution.xy;
    gl_FragColor = vec4(
        abs( sin( cos( time + 3. * uv.y ) * 2. * uv.x + time)),
        abs( cos( sin( time + 2. * uv.x ) * 3. * uv.y + time)),
        2.0,
        1.0);
}

texture_width,texture_heightは画面サイズで、InitGL()関数の中でシェーダーに設定しています。KodeLifeやGLSL sandboxなどのLiveCodingソフトでは一般的にtime と resolution変数が使用されているので、resolution変数を作成しています。また、gl_FragCoord.xyが入力の二次元マップ、gl_FragColorが出力のRGBAとなります。(KodeLifeなどからの移植で、出力変数名がfragColorとなっている場合はgl_FragColorと書き換えてください)

shader_loop.frag の中を自由に書き換えれば様々な映像が生成可能です!

実行

python shader_loop.py shader_loop.vert shader_loop.frag

サンプルコードでは、ESCキーを押すと、その時の画像をキャプチャして保存します(output.png)。

以上です!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9