ComputeScreenPos works bad on Mali-450MP Opengl 2.0

HELP!
Only on this android 4.4.2 pad failed this shader to work normal on the right side of the screen, exceeding 1024pixel of x-axis, as shown on this screen scratch, the right portion of the bars becomes unequal spaced:
52983-right-error.png

	Pass {
		ZTest Always Cull Off ZWrite Off
    	Fog { Mode off }
    	
    	CGPROGRAM
    	#pragma vertex vert
      	#pragma fragment frag
      	#pragma target 2.0
      	#include "UnityCG.cginc"
      	#include "UnityShaderVariables.cginc"
      	
      	uniform sampler2D _LeftTex;
      	uniform sampler2D _RightTex;
      		      	
      	struct vertOut {
      		float4 pos : SV_POSITION;
      		float4 scrPos : TEXCOORD1;
      		float2 uv : TEXCOORD0;
      	};
      	
      	// Vertex Shader
      	vertOut vert(appdata_base v) {
			vertOut o;
      		o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
      		o.scrPos = ComputeScreenPos(o.pos);
      		o.uv = v.htexcoord;  		
      		return o;
		}
      	
      	// Fragment Shader
      	float4 frag(vertOut i) : COLOR {
        	float4 texRGB;
        	float2 wcoord = (i.scrPos.xy/i.scrPos.w);
      		float2 scoord = wcoord *  _ScreenParams.xy;	
      		float2 vuv = i.uv;      
            if( fmod(scoord.x, 10.0 )  < 5.0 ){
 			   //texRGB = tex2D(_LeftTex,vuv);                   
 			   texRGB = float4(1,1,1,0);//white
             }else{
 			   //texRGB = tex2D(_RightTex,vuv);
 			   texRGB = float4(1,0,0,0);//red 
             } 
	        return texRGB;
		}
      	ENDCG
	}

ComputeScreenPos is most likely not “wrong” as it is just this:

// See around line 570+ in "\Unity\Editor\Data\CGIncludes\UnityCG.cginc"
inline float4 ComputeScreenPos (float4 pos) {
    float4 o = pos * 0.5f;
    #if defined(UNITY_HALF_TEXEL_OFFSET)
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w * _ScreenParams.zw;
    #else
    o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;
    #endif
    
    o.zw = pos.zw;
    return o;
}

The little differences seem to be more related to floating point accuracy. Maybe try the reverse. Instead of scaling the screen position up with the screen dimension you could simply scale your 10.0 and 5.0 down by the screen width. This should give you the same result but you stay in the float range 0 to 1

edit
Since you work with pixel coordinates in your shader another solution could be to “floor” the coordinates to the nearest pixel coordinate.

Hi,

Here is an interesting article about precision in GPUs: http://www.youi.tv/mobile-gpu-floating-point-accuracy-variances/

The Mali 400 MP4 is rated worst of the bunch. Perhaps this explains the behaviour of your Mali 450 MP. You could try the shader from the article above to see how it compares.

Unfortunately Mali 450 MP devices are quite rare, and I don’t have one to run some tests with.

Having said that, I would like to help if I can. What are you actually trying to draw? Do you really want to see this pattern of red and white lines?

Dan

Unity Support