Why is the result of this GLSL shader asymetric when rendering with stereo "Side-By-Side"? I am trying to achieve an inverse lens ditortion for the Oculus Rift during Side-By-Side stereo in the game engine. I am using a custom Filter2D with this GLSL shader. 

The distortion can be achieved as described here. Another fragment shader for that cause can be found in the OpenHMD examples.

The distortion looks good without stereo, but is asymmetric when I render it with Side-By-Side. For other stereo options, the output is not correct, but symmetric. Where is the problem here?

uniform sampler2D bgl_RenderedTexture;

const vec4 kappa = vec4(1.0,1.7,0.7,15.0);

uniform float screen_width;
uniform float screen_height;

const float scaleFactor = 0.9;

const vec2 leftCenter = vec2(0.25, 0.5);
const vec2 rightCenter = vec2(0.75, 0.5);

// Scales input texture coordinates for distortion.
vec2 hmdWarp(vec2 LensCenter, vec2 texCoord, vec2 Scale, vec2 ScaleIn) {
    vec2 theta = (texCoord - LensCenter) * ScaleIn; 
    float rSq = theta.x * theta.x + theta.y * theta.y;
    vec2 rvector = theta * (kappa.x + kappa.y * rSq + kappa.z * rSq * rSq + kappa.w * rSq * rSq * rSq);
    vec2 tc = LensCenter + Scale * rvector;
    return tc;
}

bool validate(vec2 tc, int left_eye) {
    //keep within bounds of texture 
    if ((left_eye == 1 &amp;&amp; (tc.x &lt; 0.0 || tc.x &gt; 0.5)) ||   
        (left_eye == 0 &amp;&amp; (tc.x &lt; 0.5 || tc.x &gt; 1.0)) ||
        tc.y &lt; 0.0 || tc.y &gt; 1.0) {
        return false;
    }
    return true;
}

void main() {
    vec2 screen = vec2(screen_width, screen_height);

    float as = float(screen.x / 2.0) / float(screen.y);
    vec2 Scale = vec2(0.5, as);
    vec2 ScaleIn = vec2(2.0 * scaleFactor, 1.0 / as * scaleFactor);

    vec2 texCoord = gl_TexCoord[0].st;

    vec2 tc = vec2(0);
    vec4 color = vec4(0);

    if (texCoord.x &lt; 0.5) {
        tc = hmdWarp(leftCenter, texCoord, Scale, ScaleIn );
        color = texture2D(bgl_RenderedTexture, tc);
        if (!validate(tc, 1))
            color = vec4(0);
    } else {
        tc = hmdWarp(rightCenter, texCoord, Scale, ScaleIn);
        color = texture2D(bgl_RenderedTexture, tc);
        if (!validate(tc, 0))
            color = vec4(0);
    }   
    gl_FragColor = color;
}


These are my render results.

First Image: Rendered with Above-Below, the result is at least symmetric.

Second Image: Rendered with no stereo, looking good, but unusable for the glasses.

Third Image: Asymmetric Side-By-Side rendering cropped.

Fourth Image: Aysmmetric Side-By-Side rendering without crop (validate function commented out)

The relevant stereo code is in RAS_OpenGLRasterizer.cpp, but I couldn't find the cause of the asymmetry.

Edit: A blend file with this issue can be downloaded here
Moguri answered my question on the forums by posting this patch that fixes the Filter 2D issue in Blender.

The patch:

diff --git blender/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp blender/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index 79ce853..1781852 100644
--- blender/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ blender/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -429,6 +429,9 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
        glActiveTextureARB(GL_TEXTURE0);
        canvas-&gt;SetViewPort(0, 0, rect_width-1, rect_height-1);  
+       RAS_Rect scissor_rect = canvas-&gt;GetDisplayArea();
+       glScissor(scissor_rect.GetLeft()+viewport[0], scissor_rect.GetBottom()+viewport[1], scissor_rect.GetWidth()+1, scissor_rect.GetHeight()+1);
+
        glDisable(GL_DEPTH_TEST);
        // in case the previous material was wire
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


Note: This patch is already included in the trunk, verified at 08/25/2013