arturoc / FaceSubstitution

Face substitution experiments using ofxFacetracker
Other
436 stars 120 forks source link

About iOS #35

Open MenLonII opened 8 years ago

MenLonII commented 8 years ago

Clone can not work in iOS, What should I do? Xcode prints this: [error] ofShader: sorry,it looks like you can't run 'ARB_shader_objects'; [error] ofShader:ofShader:setupShaderFromSource();failed creating GL_FRAGMENT_SHADER shader; [error] ofShader:please check the capabilites of your graphics card:http://www.ozone3d.net/gpu_caps_viewer; [error] ofShader:linkProgram(): tring to link GLSL program,but no shaders created yet;

fabricioeus commented 8 years ago

you must put your settings to use the ES2 renderer type. settings.glesVersion = OFXIOS_RENDERER_ES2; // type of renderer to use, ES1, ES2, ES3

robertshearing commented 8 years ago

If I set the OPENGL version to ES2 the error goes away but a whole world of pain opens up with the shader as it is not OPEN GLES 2 compatible. Does anyone know how to re-write these shaders for GLES2:

//Blur Shader

#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect tex, mask;
uniform vec2 direction;
uniform int k;
void main() {
    vec2 pos = gl_TexCoord[0].st;
    vec4 sum = texture2DRect(tex, pos);
    int i;
    for(i = 1; i < k; i++) {
        vec2 curOffset = float(i) * direction;
        vec4 leftMask = texture2DRect(mask, pos - curOffset);
        vec4 rightMask = texture2DRect(mask, pos + curOffset);
        bool valid = leftMask.r == 1. && rightMask.r == 1.;
        if(valid) {
            sum +=
                texture2DRect(tex, pos + curOffset) +
                texture2DRect(tex, pos - curOffset);
        } else {
            break;
        }
    }
    int samples = 1 + (i - 1) * 2;
    gl_FragColor = sum / float(samples);
}

//CloneShader

#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect src, srcBlur, dstBlur;
void main() {
    vec2 pos = gl_TexCoord[0].st;
    vec4 srcColorBlur = texture2DRect(srcBlur, pos);
    if(srcColorBlur.a > 0.) {
        vec3 srcColor = texture2DRect(src, pos).rgb;
        vec4 dstColorBlur = texture2DRect(dstBlur, pos);
        vec3 offset = (dstColorBlur.rgb - srcColorBlur.rgb);
        gl_FragColor = vec4(srcColor + offset, 1.);
    } else {
        gl_FragColor = vec4(0.);
    }
}
fabricioeus commented 8 years ago

//CloneShader precision highp float;

uniform sampler2D src, srcBlur, dstBlur;

varying vec2 texCoordVarying;

void main() { vec2 pos = vec2(texCoordVarying.x, texCoordVarying.y); vec4 srcColorBlur = texture2D(srcBlur, pos); if(srcColorBlur.a > 0.){

    vec3 srcColor = texture2D(src, pos).rgb;
    vec4 dstColorBlur = texture2D(dstBlur, pos);
    vec3 offset = dstColorBlur.rgb - srcColorBlur.rgb;

    gl_FragColor = vec4(srcColor + offset, 1.);

}
else{

    gl_FragColor = vec4(0.);

}

}

fabricioeus commented 8 years ago

//MaskShader

precision highp float;

uniform sampler2D tex0, mask; uniform vec2 direction; uniform int k; varying vec2 texCoordVarying;

//#define LOW_RES //#define USE_HARDWARE_INTERPOLATION

define STANDARD

void main() { vec2 pos = vec2(texCoordVarying.x, texCoordVarying.y); vec4 sum = texture2D(tex0, pos); int i;

// 350 fps

ifdef LOW_RES

for(i = 2; i < k; i += 4) {
    vec2 offset = float(i) \* direction;
    vec4 leftMask = texture2D(mask, pos - offset);
    vec4 rightMask = texture2D(mask, pos + offset);
    bool valid = leftMask.r == 1. && rightMask.r == 1.; // ignore black pixels
    if(valid) {
        sum +=
        texture2D(tex0, pos + offset) +
        texture2D(tex0, pos - offset);
    } else {
        break;
    }
}
int samples = 1 + (i - 1) \* 2 / 4;

endif

// 240 fps

ifdef USE_HARDWARE_INTERPOLATION

for(i = 2; i < k; i += 2) {
    vec2 maskOffset = float(i) \* direction;
    vec4 leftMask = texture2D(mask, pos - maskOffset);
    vec4 rightMask = texture2D(mask, pos + maskOffset);
    bool valid = leftMask.r == 1. && rightMask.r == 1.; // ignore black pixels
    if(valid) {
        vec2 sampleOffset = (float(i) - .5) \* direction;
        sum +=
        texture2D(tex0, pos + sampleOffset) +
        texture2D(tex0, pos - sampleOffset);
    } else {
        break;
    }
}
int samples = 1 + (i - 2);

endif

// 140 fps

ifdef STANDARD

int samples = 1;
for(i = 1; i < k; i++) {
    vec2 curOffset = float(i) \* direction;
    vec4 leftMask = texture2D(mask, pos - curOffset);
    vec4 rightMask = texture2D(mask, pos + curOffset);
    bool valid = leftMask.r == 1. && rightMask.r == 1.; // ignore black pixels
    if(valid) { 
        sum += 
        texture2D(tex0, pos + curOffset) +
        texture2D(tex0, pos - curOffset);
        samples += 2;
    } else {
        break;
    }
}

endif

gl_FragColor = sum / float(samples);

}

robertshearing commented 8 years ago

Massive thanks for re-writing the fragment shader! I'm trying to implement these new shaders in Clone.cpp. I have turned each of your shaders into .frag shader files. For the vertex shader I put this together:

attribute vec4 position;
varying vec2 texCoordVarying;
uniform mat4 modelViewProjectionMatrix;

void main(){
    gl_Position = modelViewProjectionMatrix * position;
    texCoordVarying = vec2( position.xy );
}

But I'm just not getting anywhere with it - the clone image doesn't appear, but the shaders are executing (setting the fragment shader to gl_FragColor = vec4(1, 0, 1, 1); outputs purple) Do you know what I'm doing wrong? This is my modified Clone.cpp:

#include "Clone.h"

void Clone::setup(int width, int height) {
    ofFbo::Settings settings;
    settings.width = width;
    settings.height = height;

    buffer.allocate(settings);
    srcBlur.allocate(settings);
    dstBlur.allocate(settings);

    maskBlurShader.load("MaskBlurShader");
    cloneShader.load("CloneShader");

    maskBlurShader.linkProgram();
    cloneShader.linkProgram();

    strength = 0;
}

void Clone::maskedBlur(ofTexture& tex, ofTexture& mask, ofFbo& result) {
    int k = strength;

    buffer.begin();
    maskBlurShader.begin();

    maskBlurShader.setUniformTexture("tex0", tex, 1);
    maskBlurShader.setUniformTexture("mask", mask, 2);
    maskBlurShader.setUniform2f("direction", 1, 0);
    maskBlurShader.setUniform1i("k", k);
    tex.draw(0, 0);
    maskBlurShader.end();
    buffer.end();

    result.begin();
    maskBlurShader.begin();
    maskBlurShader.setUniformTexture("tex0", buffer, 1);
    maskBlurShader.setUniformTexture("mask", mask, 2);
    maskBlurShader.setUniform2f("direction", 0, 1);
    maskBlurShader.setUniform1i("k", k);
    buffer.draw(0, 0);
    maskBlurShader.end();
    result.end();
}

void Clone::setStrength(int strength) {
    this->strength = strength;
}

void Clone::update(ofTexture& src, ofTexture& dst, ofTexture& mask) {
    maskedBlur(src, mask, srcBlur);
    maskedBlur(dst, mask, dstBlur);

    buffer.begin();
    ofPushStyle();
    ofEnableAlphaBlending();
    dst.draw(0, 0);
    cloneShader.begin();
    cloneShader.setUniformTexture("src", src, 1);
    cloneShader.setUniformTexture("srcBlur", srcBlur, 2);
    cloneShader.setUniformTexture("dstBlur", dstBlur, 3);
    dst.draw(0, 0);
    cloneShader.end();
    ofDisableAlphaBlending();
    ofPopStyle();
    buffer.end();
}

void Clone::draw(float x, float y) {
    buffer.draw(x, y);
}
fabricioeus commented 8 years ago

the only difference that i can see is in the maskedBlur method(i didn't changed it). Its the same from the sample i think.

void Clone::maskedBlur(ofTexture& tex, ofTexture& mask, ofFbo& result) { int k = strength;

buffer.begin();
maskBlurShader.begin();
maskBlurShader.setUniformTexture("tex0", tex, 1);
maskBlurShader.setUniformTexture("mask", mask, 2);
**maskBlurShader.setUniform2f("direction", 1./(tex.getWidth()*2), 0.);**
maskBlurShader.setUniform1i("k", k);
tex.draw(0, 0);
maskBlurShader.end();
buffer.end();

result.begin();
maskBlurShader.begin();
maskBlurShader.setUniformTexture("tex0", buffer, 1);
maskBlurShader.setUniformTexture("mask", mask, 2);
**maskBlurShader.setUniform2f("direction", 0., 1./(buffer.getHeight()));**
maskBlurShader.setUniform1i("k", k);
buffer.draw(0, 0);
maskBlurShader.end();
buffer.draw(0, 0);
result.end();

}

fabricioeus commented 8 years ago

and my cloneshader is:

precision highp float;

uniform sampler2D src, srcBlur, dstBlur;

varying vec2 texCoordVarying;

void main() { vec2 pos = vec2(texCoordVarying.x, texCoordVarying.y); vec4 srcColorBlur = texture2D(srcBlur, pos); if(srcColorBlur.a > 0.){

    vec3 srcColor = texture2D(src, pos).rgb;
    vec4 dstColorBlur = texture2D(dstBlur, pos);
    vec3 offset = dstColorBlur.rgb - srcColorBlur.rgb;

    gl_FragColor = vec4(srcColor + offset, 1.);

}
else{

    gl_FragColor = vec4(0.);

}

}