着色器在平板电脑上产生错误结果

时间:2013-03-13 18:11:59

标签: android opengl-es shader

我只使用着色器几天,并编写了一个简单的边缘检测着色器,添加了阴影和内部阴影。它在我的galaxy s2和iphone 4上运行得很好,但是Galaxy tab和ipad2在边缘两侧只产生一个非常薄且粗糙的阴影。我花了几个小时试图找出原因,但没有快乐,请帮忙!如果我在模拟器中模拟ipad2分辨率,效果是正确的。

着色器在所有设备(640x480像素)上的屏幕缓冲区大小相同。

vertex shader:
{
    attribute highp vec4    inVert; //vertex stream
    uniform highp mat4   inPMVMat; //transform to projected space
    attribute mediump vec2 inUV0;
    attribute lowp vec4 inCol;
    uniform mediump vec2 inUVOffset;
            uniform mediump vec2 inUVScale;
    varying mediump vec2 vTexCoord;
    varying mediump float FragColor;
    void main(void)
    {
        gl_Position = inPMVMat * inVert;//set vertex position in projected space
        vTexCoord = inUV0*inUVScale;// + inUVOffset;//pass texture to fragment shader
        FragColor = inCol.a;
    }
}


fragment shader:
{
    uniform sampler2D myTexture;
    varying mediump vec2 vTexCoord;
    varying mediump float FragColor;
    lowp float MaxDistance, Distance;
    lowp float Shift;
    void main(void)
    {
        gl_FragColor = texture2D(myTexture, vTexCoord);
        mediump vec2 PixelSize = vec2(1.0 / 640.0, 1.0 / 480.0);
        mediump vec2 Direction = vec2(PixelSize.x*0.5,PixelSize.y*0.5);

        if(gl_FragColor.a >= 0.5)
        {
            //inner shadow
            MaxDistance = 15.0;
        } else {
            //drop shadow
            MaxDistance = 12.0;
            Direction = -Direction;
        }


        mediump vec2 Position = vTexCoord;
        mediump float c;
        for(Distance = MaxDistance; Distance > 0.0;Distance -= 1.0)
        {
            Position += Direction;
            c = texture2D(myTexture,Position).a;
            if(c < 0.5)
            {
                if(gl_FragColor.a >= 0.5)
                {
                    //found transparent edge - do inner shadow
                    Shift = 1.0-((0.5/MaxDistance)*Distance);
                    gl_FragColor.r *= Shift;
                    gl_FragColor.g *= Shift;
                    gl_FragColor.b *= Shift;
                    break;
                }
            } else {
                if(gl_FragColor.a < 0.5)
                {
                    //found opaque edge - do dropshadow
                    gl_FragColor.a = ((0.8/MaxDistance)*Distance);
                    break;
                }
            }
        }
        gl_FragColor.a *= FragColor;
    }
}

图片:

gs2

tab

1 个答案:

答案 0 :(得分:1)

经过大量的实验,我终于找到了解决方案。 lowp MaxDistance,Distance和Shift变量是罪魁祸首 - 在更改为mediump之后,它在所有设备上运行良好。我猜设备之间的精度存在一些差异