sphere env mapping in ARB_VERTEX_PROGRAM not same between ATI and NVidia

I had my env sphere mapping working on ATI 9500 Pro , but same code doesnt work on NVIDIA (gf4 go 420 or gf fx 5200 ultra)

I suspect its the Texcoords .zw fields, but
not entirely sure…

here is the current code
this still does not work on NVidia

so how do i get this working on both?

///////////////////////////////

!!ARBvp1.0
###############################################################################

###############################################################################

ATTRIB vColor = vertex.color;
ATTRIB vNormal = vertex.normal;
ATTRIB vPos = vertex.position;

###############################################################################

PARAM ModColor = program.env[0];
PARAM matMVP[4] = { program.env[4…7] };
PARAM matMV[4] = { program.env[8…11] };

###############################################################################

PARAM One = { 1.0, 1.0, 1.0, 1.0 };

PARAM UVOffset2 = { 0.5, 0.5, 0.0, 0.0 };
PARAM UVScale2 = { 0.5, 0.5, 0.0, 0.0 };

###############################################################################

TEMP OutColor, EyeNrm, OutUV;

###############################################################################

DP4 result.position.x, matMVP[0], vPos;
DP4 result.position.y, matMVP[1], vPos;
DP4 result.position.z, matMVP[2], vPos;
DP4 result.position.w, matMVP[3], vPos;

DP4 EyeNrm.x, matMV[0], vNormal;
DP4 EyeNrm.y, matMV[1], vNormal;
DP4 EyeNrm.z, matMV[2], vNormal;
DP4 EyeNrm.w, matMV[3], vNormal;

DP3 EyeNrm.w, EyeNrm, EyeNrm;				
RSQ EyeNrm.w, EyeNrm.w;						
MUL EyeNrm.xyz, EyeNrm.w, EyeNrm;

MUL OutUV, EyeNrm, UVScale2;
ADD OutUV, OutUV, UVOffset2;

###########################################################

MOV	result.texcoord[0], OutUV;

MOV result.texcoord[0].z, Zero;

MOV result.texcoord[0].w, One;

MUL OutColor, ModColor, vColor;
MOV result.color.front.primary, One;

###########################################################

END

//////////////////////////////////////////

here is old working ATI code

!!ARBvp1.0

ATTRIB vUVW = vertex.texcoord[0];
ATTRIB vColor = vertex.color;
ATTRIB vNormal = vertex.normal;
ATTRIB vPos = vertex.position;

PARAM matMVP[4] = { program.env[0…3] };
PARAM matV[4] = { program.env[4…7] };
PARAM matM[4] = { program.env[8…11] };
PARAM matMV[4] = { program.env[12…15] };
PARAM matITMV[4] = { program.env[16…19] };

PARAM mycolor = program.env[20];

PARAM uvBase = { 0.0, 0.0, 0.0, 1.0 };
PARAM uvscale = { 0.5, 0.5, 0.0, 1.0 };
PARAM uvoffset = { 0.5, 0.5, 0.0, 0.0 };

PARAM One = { 1.0, 1.0, 1.0, 1.0 };
PARAM Half = { 0.5, 0.5, 0.5, 0.5 };
PARAM Zero = { 0.0, 0.0, 0.0, 0.0 };

PARAM MyColor = { 0.5, 0.5, 0.5, 1.0 };

PARAM UVOffset2 = { 0.5, 0.5, 0.0, 0.0 };
PARAM UVScale2 = { 0.5, 0.5, 0.0, 1.0 };

TEMP OutColor, EyeNrm, OutUV;

DP4 result.position.x, matMVP[0], vPos;
DP4 result.position.y, matMVP[1], vPos;
DP4 result.position.z, matMVP[2], vPos;
DP4 result.position.w, matMVP[3], vPos;

DP4 EyeNrm.x, matMV[0], vNormal;
DP4 EyeNrm.y, matMV[1], vNormal;
DP4 EyeNrm.z, matMV[2], vNormal;
DP4 EyeNrm.w, matMV[3], vNormal;

DP3 EyeNrm.w, EyeNrm, EyeNrm;				
RSQ EyeNrm.w, EyeNrm.w;						
MUL EyeNrm.xyz, EyeNrm.w, EyeNrm;

MUL OutColor, MyColor, vColor;

MUL OutUV, EyeNrm, UVScale2;
ADD OutUV, OutUV, UVOffset2;

###########################################################

MOV	result.texcoord[0], OutUV;
MOV	result.texcoord[0].z, Zero;
MOV	result.texcoord[0].w, One;
MOV result.color.front.primary, OutColor;

###########################################################

END

When you say “doesn’t work” what does that mean?

Do you get the wrong texture? No texture? An error loading the program? Something else?

What other states are going on in your main program? If you replace the fragment program with something that just moves a constant into the output color, does it do what you expect? If you replace the texture with a simple 2D texture, using screen-space coordinates as input, does it do the right thing?

I’d be very carefull with the w coordinate, because i’ve found that, when you are sampling a 2D texture, one of the vendor (Nvidia or ATI, i don’t remember which) defaults w to 1, while the other uses the actual value in w. So if you’re computing the texture coordinates in a vertex shader, make sure you w value is 1.

Y.

You probably want to review your normal calculations, too.
DP4 seems unnecessary, use DP3.
And DP4 EyeNrm.w, matMV[3], vNormal; is obsolete becaause the next instruction is:
DP3 EyeNrm.w, EyeNrm, EyeNrm;
And for the constants, you need only one which is (1.0, 0.5, 0.0) the rest can be done with swizzling.