ofDisableArbTex() + ofxBlur = incompatible?

Hello,

Actually this question has been raised before

but I can’t figure out what’s the solution… so I ask it again.

I use ofxBlur in my code, which works fine.

I also need to use Shadertoy addon, which works fine if I call ofDisableArbTex();

However this exact call prevents ofxBlur from working.

I’m sure they can co-exist, but how ?

Thanks
M

Hey @SFR75 , they can work together. You can try enabling and disabling as needed and see if that works OK. Call ofDisableArbTex() before a shader that uses sampler2D, or uses normalized texture coordinates. Then call ofEnableArbTex() before a shader that uses sampler2DRect (like ofxBlur), and needs non-normalized coordinates. Non-normalized texture coordinates and sampler2DRect are default.

Alternatively, you could modify ofxBlur to use normalized texture coordinates. This might be as simple as replacing sampler2DRect with sampler2D in ofxBlur.cpp, and calling ofDisableArbTex() once in ofApp::setup().

Hello TimChi

Strangely enough none of these solution work for me.

Replacing sampler2DRect with sampler2D wreaks havoc in ofxBlur. It starts behaving very strangely.

Executing ofEnableArbTex() before using blur strangely enough doesn’t make any effect either. It just simple ignores this it seems. I run ofDisableArbTex() in setup and then re-enable it in draw().

UPDATE: actually enabling/disabling is working now. For some reason it shouldn’t be called from “setup”… only in draw/update. Doesn’t make much sense, but ok…

Curious why replacing sampler2DRect with sampler2D didn’t work… >

Anyway, problem seems to be sovled!

Thanks
M

Hey I’m not sure that enabling/disabling is the best approach, but it may be OK.

The blur works by sampling the texture at some distance (step size) around each pixel, multiplying those values by “weights” from a Gaussian, and then summing. Each pixel gets fractional contributions from its neighbors, which blurs the image.

A texture with normalized coordinates should have a fractional step size. The step size could be 1.0 with non-normalized coordinates. So maybe lines 84 and 85 (from the GitHub page of ofxBlur) could be changed to include a uniform vec2 step, so that the texture is sampled with a fractional step as follows:

// in OF, in psudeo code
glm::vec2 stepSize;
stepSize = glm::vec2(1.f / fbo.getWidth(), 1.f / fbo.getHeight());
shader.setUniform2f("stepSize", stepSize);

// stepSize comes into the fragment shader for sampling the texture
uniform vec2 stepSize;
// before lines 84 and 85
direction *= stepSize;

I have to admit that I have some trouble following ofxBlur to see where to modify it for a sampler2D texture.

If it helps, the Gaussian blur I often use is below; it came from the GitHub page of Adam Ferriss. stepSize describes both the magnitude and direction of the blur:

// in OF, a basic diagonal step:
stepSize = glm::vec2(1.0 / fbo.getWidth(), 1.0 / fbo.getHeight());
// modify for direction and/or magnitude
stepSize *= glm::vec2(1.0, 0.0); // horizontal
// stepSize *= glm::vec2(0.0, 1.0); // vertical
// stepSize *= glm::vec2(-1.0, 1.0); // opposite diagonal
// stepSize *= 1.3; // a larger step

blur shader:

#version 330
uniform sampler2D tex0;
uniform vec2 stepSize;

in vec2 vTexcoord;
out vec4 fragColor;

vec3 gaussianBlur(sampler2D tex, vec2 texUV, vec2 stepSize){
        // a variable for output
        vec3 colorOut = vec3(0.0);
        const int stepCount = 9;

        // gaussian weights
        float gWeights[stepCount];
            gWeights[0] = 0.10855;
            gWeights[1] = 0.13135;
            gWeights[2] = 0.10406;
            gWeights[3] = 0.07216;
            gWeights[4] = 0.04380;
            gWeights[5] = 0.02328;
            gWeights[6] = 0.01083;
            gWeights[7] = 0.00441;
            gWeights[8] = 0.00157;

        // gaussian offsets
        float gOffsets[stepCount];
            gOffsets[0] = 0.66293;
            gOffsets[1] = 2.47904;
            gOffsets[2] = 4.46232;
            gOffsets[3] = 6.44568;
            gOffsets[4] = 8.42917;
            gOffsets[5] = 10.41281;
            gOffsets[6] = 12.39664;
            gOffsets[7] = 14.38070;
            gOffsets[8] = 16.36501;

        // 9 samples in the blur
        for(int i = 0; i < stepCount; i++)
        {
            // multiply the texel size by the by the offset value
            vec2 texCoordOffset = gOffsets[i] * stepSize;

            // sample to the left and to the right of the texture and add them together
            vec3 color = texture(tex, texUV + texCoordOffset).rgb;
            color += texture(tex, texUV - texCoordOffset).rgb;

            // multiply col by the gaussian weight value from the array
            color *= gWeights[i];

            // add it all up
            colorOut += color;
        }

        // our final value is returned as col out
        return colorOut;
}

void main(){
    // normalized coords
    vec2 tc = vTexcoord;
    vec3 color = gaussianBlur(tex0, tc, stepSize);
    fragColor = vec4(color, 1.0);
}

Yes, I agree that disabling/enabling ArbTex is not very pretty solution. Ok, well I’m not limited to ofxBlur, so maybe I can use the one you’ve suggested. Thanks for you answer!

if it was me, I’d create fbos with and without arb tex, and draw from one into another and use the add-on on the appropriate fbo. for example, I’d diableArbTex, allocate an fbo for shader toy, enableArbTex and allocate an fbo for blur, then draw the output of the shader toy fbo into the blur fbo for blurring, etc.

1 Like

yes, apparently it’s a way to go… no need to turn ArbTex every time you perform an operation.
thanks!