Pixel Lights working with target 3.0??

Has anyone successfully targeted 3.0 with full lighting support?

I am getting very very strange results:
Black Flickering
Lights Moving
Stats window reversing

Pass
			{		
				Name "PPL"
				Tags { "LightMode" = "Pixel" }

				CGPROGRAM
				#pragma target 3.0
				#pragma vertex vert
				#pragma fragment frag
				#pragma multi_compile_builtin
				#include "UnityCG.cginc"
				#include "AutoLight.cginc"
				 
				uniform sampler2D _MainTex;
				uniform sampler2D _MainTex2;
				uniform sampler2D _MainTex3;
				uniform sampler2D _MainTex4;
				uniform sampler2D _MainTex5;
				uniform sampler2D _MainTex6;
				uniform sampler2D _LightMap;
				uniform sampler2D _Splat1;
				uniform sampler2D _Splat2;
				uniform float _LightMapAlpha;
				uniform float _CloudShadowsAlpha;
				 
				 struct a2v
				{
					float4 vertex : POSITION;
					float3 normal : NORMAL;
					float4 texcoord : TEXCOORD0;
				};
				
				struct v2f 
				{
					V2F_POS_FOG;
					LIGHTING_COORDS
					float4 uv[5];
					float3 normal;
					float3 lightDir;
				};
							
				v2f vert (a2v v)
				{			
					v2f o;
					PositionFog( v.vertex, o.pos, o.fog ); 
					
					o.normal = v.normal;
					
					o.uv[0].xy = TRANSFORM_UV(0);
					o.uv[0].zw = TRANSFORM_UV(1);
					o.uv[1].xy = TRANSFORM_UV(2);
					o.uv[1].zw = TRANSFORM_UV(3);
					o.uv[2].xy = TRANSFORM_UV(4);
					o.uv[2].zw = TRANSFORM_UV(5);
					o.uv[3].x = clamp((v.vertex.x + 988.f) / 2000.f, 0.f, 1.f); // POSITION
					o.uv[3].y = clamp((v.vertex.y - 1059.f) / -2000.f, 0.f, 1.f); // POSITION
					o.uv[3].z = o.uv[3].x;
					o.uv[3].w = clamp((v.vertex.y - 1059.f) / -2000.f, 0.f, 1.f) + _Time[0];
					
					o.lightDir = ObjSpaceLightDir( v.vertex );
					TRANSFER_VERTEX_TO_FRAGMENT(o);
					
					return o;
				};
				 
				half4 frag( v2f i ) : COLOR
				{									
					half4 tex1 = tex2D( _MainTex, i.uv[0].xy );
					half4 tex2 = tex2D( _MainTex2, i.uv[0].zw );
					half4 tex3 = tex2D( _MainTex3, i.uv[1].xy );
					half4 tex4 = tex2D( _MainTex4, i.uv[1].zw );
					half4 tex5 = tex2D( _MainTex5, i.uv[2].xy );
					half4 tex6 = tex2D( _MainTex6, i.uv[2].zw );
					half4 splat1 = tex2D( _Splat1, i.uv[3].xy); 
					half4 splat2 = tex2D( _Splat2, i.uv[3].xy); 
					
					half4 lightMap;
					lightMap.r = tex2D( _LightMap, i.uv[3].xy).r;   // LIGHTMAP1
					lightMap.g = tex2D( _LightMap, i.uv[3].zw).g; // CLOUD SHADOW
					
					// Mix Textures from Splats
					half4 color;
					color = 	tex1 * splat1.r + 
								tex2 * splat1.g + 
								tex3 * splat1.b +	
								tex4 * splat2.r + 
								tex5 * splat2.g + 
								tex6 * splat2.b;		
					
					// Add Lightmaps
					float lm1 = lerp(1, lightMap.r, _LightMapAlpha);
					float lm2 = lerp(1, lightMap.g, _CloudShadowsAlpha);
					
					return DiffuseLight( i.lightDir, i.normal, color, LIGHT_ATTENUATION(i));
				}
				ENDCG
			}

[/list:u:4243a49c4b]

I think you might be using slightly too many texture interpolators.

Lighting itself (LIGHTING_COORDS) can use from 0 to 3 interpolators. In your code you try to use 7 more. Which is 10 texture coordinates already, which can be too much for Cg to generate proper code.

Just a guess.

I just had a similar issue. My “frag” function contains a lot of “tex2D()” calls, and commenting one out seems to fix everything. Why is this the case? Isn’t “tex2D()” a type of function call, or does it just get replaced with in-line code? Funny thing is, the scene renders it correctly, but the game view does not…? :confused:

				float4 frag (v2f i) : COLOR
				{ 
					// The eternal tradeoff: do we normalize the normal? 
					float3 normal = normalize(i.normal); 
					//float3 normal = i.normal;
					
					float dist = sqrt(i.vertex.x*i.vertex.x + i.vertex.y*i.vertex.y + i.vertex.z*i.vertex.z);
					
					// ... based on distance from the center of the object, find the two textures to blend ...
					
					float mixPos1, mixPos2;
					float4 texcol1, texcol2;
					
					if (dist < _WaterFoamStart)
					{
						mixPos1 = _WaterFloorStart;
						mixPos2 = _WaterFoamStart;
						texcol1 = tex2D(_WaterFloorTex, i.uv);
						texcol2 = tex2D(_WaterFoamTex, i.uv);
					}
					else if (dist < _ShoreLineStart)
					{
						mixPos1 = _WaterFoamStart;
						mixPos2 = _ShoreLineStart;
						texcol1 = tex2D(_WaterFoamTex, i.uv);
						texcol2 = tex2D(_ShoreLineTex, i.uv);
					}
					else if (dist < _DirtStart)
					{
						mixPos1 = _ShoreLineStart;
						mixPos2 = _DirtStart;
						texcol1 = tex2D(_ShoreLineTex, i.uv);
						texcol2 = tex2D(_DirtTex, i.uv);
					}
					else if (dist < _GrassStart)
					{
						mixPos1 = _DirtStart;
						mixPos2 = _GrassStart;
						texcol1 = tex2D(_DirtTex, i.uv);
						texcol2 = tex2D(_GrassTex, i.uv);
					}
					else if (dist < _MountainBaseStart)
					{
						mixPos1 = _GrassStart;
						mixPos2 = _MountainBaseStart;
						texcol1 = tex2D(_GrassTex, i.uv);
						texcol2 = tex2D(_MountainBaseTex, i.uv);
					}
					else if (dist < _MountainSideStart)
					{
						mixPos1 = _MountainBaseStart;
						mixPos2 = _MountainSideStart;
						texcol1 = tex2D(_MountainBaseTex, i.uv);
						texcol2 = tex2D(_MountainSideTex, i.uv);
					}
					else
					{
						mixPos1 = _MountainSideStart;
						mixPos2 = _MountainTopEnd;
						texcol1 = tex2D(_MountainSideTex, i.uv);
						texcol2 = tex2D(_MountainTopTex, i.uv);
					}
					
					// ... calculate the "mix" amount between the textures ...
					
					float mixAmount = dist - mixPos1;
					float mixRange = mixPos2 - mixPos1;
					float percentMix2 = 0;
					if (mixRange != 0) percentMix2 = mixAmount / mixRange;
					if (percentMix2 < 0) percentMix2 = 0;
					if (percentMix2 > 1) percentMix2 = 1;
					float percentMix1 = 1 - percentMix2;
					
					// ... interpolate the color ...
					
					float4 texcolA = (texcol1 * percentMix1);
					float4 texcolB = (texcol2 * percentMix2);
					float4 texcol = texcolA + texcolB;
					
					return DiffuseLight(i.lightDir, normal, texcol, LIGHT_ATTENUATION(i) );
				}