GLSL Optimization failed: xlv_ redeclared

Hello everyone,

I wrote a vertex and fragment shader that works just fine on Direct3D, but when it compiles on a Mac gives strange vertex errors. I tried forcing it to compile to glsl, to see if that would fix the problem, and I get the following problem in the compiled shader:

varying vec4 xlv_;
varying vec2 xlv_;
varying float xlv_;
varying vec4 xlv_;
varying float xlv_;
void main() {
    v2f xl_retval;
    appdata_img xlt_v;
    xlt_v.vertex = vec4( gl_Vertex);
    xlt_v.texcoord = vec2( gl_MultiTexCoord0);
    xl_retval = vert( xlt_v);
    gl_Position = vec4( xl_retval.pos);
    xlv_ = vec4( xl_retval.pos2);
    xlv_ = vec2( xl_retval.uv1);
    xlv_ = float( xl_retval.svc);
    xlv_ = vec4( xl_retval.vr);
    xlv_ = float( xl_retval.draw);
}
/* NOTE: GLSL optimization failed
0:0(0): error: `xlv_' redeclared
0:0(0): error: `xlv_' redeclared
0:0(0): error: `xlv_' redeclared
0:0(0): error: `xlv_' redeclared
0:450(7): error: type mismatch
0:451(7): error: type mismatch
0:453(7): error: type mismatch
*/

What is the solution to this error? Is there a way to force the compiler to not redeclare a variable? Is there a misconception I have about writing shaders that is causing this problem? I declared this struct for the vertex shader, this is what it’s having trouble with I think?

struct v2f 
	{
		float4 pos : POSITION; //internal, used for display
		float4 pos2; //Position in world, relative to player position in world
		float2 uv1; //Used to specify what part of the texture to grab in the fragment shader(not relativity specific, general shader variable)
		float svc; //sqrt( 1 - (v-c)^2), calculated in vertex shader to save operations in fragment. It's a term used often in lorenz and doppler shift calculations, so we need to keep it cached to save computing
		float4 vr; //Relative velocity of object vpc - viw
		float draw; //Draw the vertex?  Used to not draw objects that are calculated to be seen before they were created. Object's start time is used to determine this. If something comes out of a building, it should not draw behind the building.
	};

Any help would be appreciated!
Thanks

Well… you’re defining the variable _xlv 5 times in the first 5 lines of the code you pasted.

Edit; Misread, nevermind.

Since it works fine in D3D, I assume Zarro wrote the shader in Cg. The pasted GLSL is produced by Unity.

My bad, I misread it as attempting to write a GLSL shader copy/pasted from a D3D one (it’s been a long day).

Sounds like one for Aras and his GLSL optimiser.

Original code?

zarro45: I had the same problem today and it seems to be caused by the struct, just as you say.
In my case it was enough to add a type after each variable in the struct, such as TEXCOORD for uv:s and so on.
The typename is probably used as a suffix, and without one there’ll be multiple variables in the GLSL code with the same name.

Do you mean like the first line in my struct, pos: POSITION? I’m new to shaders, basically porting over code written by another member of the team. Thank you for your reply!

That’s exactly what I mean. But I’m also new to shaders, so I don’t know which types you should use for your custom values.
It’s strange that we (atleast me) don’t get any errors in Unity during the compilation of the shader…

I hope someone more into shaders will come along and give some pointers.

For anything other than normals, tangents, position and colour, you’ll need to use TEXCOORD0 through to TEXCOORD7.

While it sounds like they’re for UVs, each one will take anything up to a float4.

That fixed the problem immediately. Thanks!

It seems like there are a few silent or confusing problems that arise from not declaring semantics everywhere possible. Perhaps someone who has encountered these issues would like to file a comprehensive bug report?

Thank you for that Mistale, I struggled on this thing all day.