openframeworksでシェーダを使おう①

難しい話は公式にまかせておくとして、とりあえずシェーダを使ってみましょう。 今回は、フラグメントシェーダを使っ…

難しい話は公式にまかせておくとして、とりあえずシェーダを使ってみましょう。

今回は、フラグメントシェーダを使って画像全体の輝度を上げます。

            • ポイント
              ◯シェーダの使い方
              – openframeworksでシェーダを使うにはofShaderオブジェクトを使用する。
              – シェーダを使って描画したい画像をshader.begin()とshader.end()で挟み込む。
              – シェーダにはsetUniform1f◯◯関数で変数を渡す。
              ◯シェーダ内の記述
              – tex0にはこれから描画しようとしているテクスチャが格納される。
              – シェーダ内では色を4次元のベクトル(vec4)で扱う。
              – シェーダでプログラムから何らかのデータを受け取るには変数にuniformを付ける。
              – 出力する画素値をgl_FragColorに入れる。
            • 結果
              ◯入力画像
              元画像
              ◯輝度を下げて出力
              暗い
              ◯輝度を上げて出力
              明るい
            • サンプルコード

ダウンロードはこちらから
testApp.h

#pragma once

#include "ofMain.h"

class testApp : public ofBaseApp{

public:
void setup();
void update();
void draw();

void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);

// openframeworksではofShaderオブジェクトを通してシェーダを使う
ofShader shader;

ofImage sampleImage;
};

testApp.cpp

#include "testApp.h"

#define STRINGIFY(A) #A

//--------------------------------------------------------------
void testApp::setup(){

// shader
string shaderProgram = STRINGIFY(
uniform sampler2DRect tex0; // これから描画するテクスチャが入っている
uniform float brightness; // メインプログラムから渡された変数を受け取る

void main (void){
vec2 pos = gl_TexCoord[0].st; // テクスチャ上の座標を取得する

float r = texture2DRect(tex0, pos).r;
float g = texture2DRect(tex0, pos).g;
float b = texture2DRect(tex0, pos).b;
float a = texture2DRect(tex0, pos).a;

vec4 color = vec4(r,g,b,a);

gl_FragColor = color * brightness; // gl_FragColorの値が最終的に画面に出力される画素値になる。
}
);

shader.setupShaderFromSource(GL_FRAGMENT_SHADER, shaderProgram);
shader.linkProgram();

sampleImage.loadImage("bg.jpg");

}

//--------------------------------------------------------------
void testApp::update(){

}

//--------------------------------------------------------------
void testApp::draw(){

ofBackground(0);

shader.begin();
//shader.setUniform1f("brightness", 0.5 ); // 暗く
shader.setUniform1f("brightness", 1.5 ); // 明るく

sampleImage.draw(0, 0);

shader.end();

}

//--------------------------------------------------------------
void testApp::keyPressed(int key){

}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){

}