openFrameworks で Shader を使う方法について。

今回は頂点シェーダ(Vertex Shader)を中心にみてゆきます。


準備

開始するにあたり、前回のプログラムを少しだけ変更しておきます。

...略...

class ofApp : public ofBaseApp {
    public:
    ...略...
    
    ofShader shader;
    
    ofPlanePrimitive plane;
    ofImage image0;
    ofImage image1;
};
void ofApp::setup() {
    float planeScale = 0.75;
    int planeWidth = ofGetWidth() * planeScale;
    int planeHeight = ofGetHeight() * planeScale;
    int planeGridSize = 20;
    int planeColums = planeWidth / planeGridSize;
    int planeRows = planeHeight / planeGridSize;
    plane.set(planeWidth, planeHeight, planeColums, planeRows, OF_PRIMITIVE_TRIANGLES);
    
    // plane.mapTexCoords(0, 0, 1, 1);
    plane.mapTexCoords(0, 0, ofGetWidth(), ofGetHeight());
    
    shader.load("shader");
    
    image0.load("MonaLisa.jpg");
    image1.load("img.jpg");
}

void ofApp::draw() {
    shader.begin();
    shader.setUniform1f("time", ofGetElapsedTimef());
    shader.setUniformTexture("tex0", image0, 0);
    shader.setUniformTexture("tex1", image1, 1);
    shader.setUniform2f("texSize0", image0.getWidth(), image0.getHeight());
    shader.setUniform2f("texSize1", image1.getWidth(), image1.getHeight());
    
    ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
    plane.drawWireframe();
    // plane.draw();
    
    shader.end();
}
#version 150

uniform mat4 modelViewProjectionMatrix;

in vec4 position;
in vec2 texcoord;

out vec2 texcoordFrag;

void main() {
    texcoordFrag = texcoord;
    
    gl_Position = modelViewProjectionMatrix * position;
}
#version 150

uniform float time;
uniform sampler2DRect tex0;
uniform sampler2DRect tex1;
uniform vec2 texSize0;
uniform vec2 texSize1;

in vec2 texcoordFrag;

out vec4 outputColor;

void main()
{
    vec4 color;
    vec4 texColor0, texColor1;

    texColor0 = texture(tex0, mod(texcoordFrag, texSize0));
    texColor1 = texture(tex1, mod(texcoordFrag, texSize1));

    // color = texColor0;
    color = vec4(1.0, 1.0, 1.0, 1.0);

    outputColor = color;
}

長方形メッシュが白色のワイヤーフレームで描かれます。この状態からはじめます。

shader07.png


マウスで視点を変更できるようにする

カメラオブジェクト ofEasyCam を追加して、マウスで視点を変更できるようにします。

...略...

class ofApp : public ofBaseApp {
    public:
    ...略...
    
    ofShader shader;
    
    ofPlanePrimitive plane;
    ofImage image0;
    ofImage image1;
    
    ofEasyCam camera;
};
void ofApp::draw() {
    camera.begin();
    
    shader.begin();
    shader.setUniform1f("time", ofGetElapsedTimef());
    shader.setUniformTexture("tex0", image0, 0);
    shader.setUniformTexture("tex1", image1, 1);
    shader.setUniform2f("texSize0", image0.getWidth(), image0.getHeight());
    shader.setUniform2f("texSize1", image1.getWidth(), image1.getHeight());
    
    // ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
    plane.drawWireframe();
    // plane.draw();
    
    shader.end();
    
    camera.end();
}

視点の移動ができるようになった。

視点の移動ができるようになった。


頂点の位置にサイン波の揺らぎを加える

頂点シェーダを編集して、ofPlanePrimitive の各頂点に対して、サイン波による揺らぎを加えてみます。