Search Unity

Corrupt shader in one project, not in another project

Discussion in 'Shaders' started by guavaman, Jun 17, 2012.

  1. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    I have a particular shader that just will not work right in my main project. Even if I make a copy of the shader and rename it something else, it still has weird and random errors. However, if I copy the shader to a new project, everything works perfectly.

    Nothing seems to make sense with this problem shader. One day it will be exhibiting one error, the next day its totally different. I had another thread here concerning the same shader. But now I'm getting different problems than I was then. Now it seems to be completely ignoring the _Color.a value in Deferred rendering, but not in Forward.

    The line in the Deferred surface shader that's currently causing me problems:
    o.Alpha = _Color.a * emis; // glow based on glow intensity, and emissive map

    This should make the alpha channel output of the shader variable based on the _Color.a, so when you change the alpha value it should change, but it does not -- at least not in deferred rendering. It works perfectly in forward. If I replace _Color.a with a const of 0.5, it renders that correctly (half-bright emissive map). It's completely ignoring any value in _Color.a and seems to be just substituting a value of 1 because the alpha output is always 100% emissive map.

    Nothing I do seems to be able to fix this shader in my project. Not renaming, copying, or even going back to using the normal BlinnPhong lighting model instead of my custom one. It's possessed or something! Has anyone seen weird corruption like this before and, if so, how can I clear it from my project so this shader works again?

    The evil shader from hell is posted below with all its includes/components:

    Code (csharp):
    1. Shader "BakedVertexLighting/Emissive/Bumped Specular" {
    2.  
    3.     Properties {
    4.         _Color ("Glow Intensity (A)", Color) = (1,1,1,1)
    5.         _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
    6.         _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
    7.         _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
    8.         _Emis ("Emissive (R)", 2D) = "white" {}
    9.         _BumpMap ("Normalmap", 2D) = "bump" {}
    10.         _EmissionLM ("Emission (Lightmapper)", Float) = 0
    11.     }
    12.    
    13.     SubShader {
    14.         Tags { "RenderType"="Opaque" }
    15.         LOD 400
    16.  
    17.         // DEFERRED SURFACE SHADER
    18.         CGPROGRAM
    19.         #pragma target 3.0
    20.         #pragma surface surf BlinnPhong_BakedVertexLighting nolightmap nodirlightmap noambient exclude_path:forward vertex:vert
    21.         #include "Assets/Shaders/includes/SurfaceOutputVtxC.cginc"
    22.         #include "Assets/Shaders/includes/LightingModels.cginc"
    23.        
    24.         sampler2D _MainTex;
    25.         sampler2D _BumpMap;
    26.         sampler2D _Emis;
    27.         fixed4 _Color;
    28.         half _Shininess;
    29.        
    30.         struct Input {
    31.             float2 uv_MainTex;
    32.             float2 uv_Emis;
    33.             float2 uv_BumpMap;
    34.             float4 color : COLOR; // vertex color
    35.             half fog;
    36.         };
    37.        
    38.         void surf (Input IN, inout SurfaceOutputVtxC o) {
    39.             fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    40.             fixed emis = tex2D(_Emis, IN.uv_Emis).r;
    41.             o.Albedo = tex.rgb;
    42.             o.Emission = tex.rgb * emis;
    43.             o.Gloss = tex.a;
    44.             o.Alpha = _Color.a * emis; // glow based on glow intensity, and emissive map
    45.             o.Specular = _Shininess;
    46.             o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    47.             o.VertexColor = IN.color;
    48.             o.AlphaFog = IN.fog;
    49.         }
    50.        
    51.         // Alpha fog vertex function
    52.         #include "Assets/Shaders/includes/AlphaFog_Vert.cginc"
    53.         ENDCG
    54.        
    55.         // FORWARD SURFACE SHADER
    56.         CGPROGRAM
    57.         #pragma target 3.0
    58.         #pragma surface surf BlinnPhong_BakedVertexLighting nolightmap nodirlightmap noambient fullforwardshadows exclude_path:prepass vertex:vert
    59.         #include "Assets/Shaders/includes/SurfaceOutputVtxC.cginc"
    60.         #include "Assets/Shaders/includes/LightingModels.cginc"
    61.        
    62.         sampler2D _MainTex;
    63.         sampler2D _BumpMap;
    64.         sampler2D _Emis;
    65.         fixed4 _Color;
    66.         half _Shininess;
    67.        
    68.         struct Input {
    69.             float2 uv_MainTex;
    70.             float2 uv_Emis;
    71.             float2 uv_BumpMap;
    72.             float4 color : COLOR; // vertex color
    73.             half fog;
    74.         };
    75.        
    76.         void surf (Input IN, inout SurfaceOutputVtxC o) {
    77.             fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
    78.             fixed emis = tex2D(_Emis, IN.uv_Emis).r;
    79.             o.Albedo = tex.rgb;
    80.             o.Emission = tex.rgb * emis + IN.color.rgb * tex.rgb; // emission plus vertex color
    81.             o.Gloss = tex.a;
    82.             o.Alpha = _Color.a * emis; // glow based on glow intensity, and emissive map
    83.             o.Specular = _Shininess;
    84.             o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
    85.             o.AlphaFog = IN.fog;
    86.         }
    87.        
    88.         // Alpha fog vertex function
    89.         #include "Assets/Shaders/includes/AlphaFog_Vert.cginc"
    90.         ENDCG
    91.     }
    92.     FallBack "Emissive/Bumped Specular"
    93. }
    94.  
    Code (csharp):
    1. // Assets/Shaders/includes/LightingModels.cginc
    2. // BlinnPhong_BakedVertexLighting
    3.  
    4.     // Forward lighting mode
    5.     inline fixed4 LightingBlinnPhong_BakedVertexLighting (SurfaceOutputVtxC s, fixed3 lightDir, half3 viewDir, fixed atten) {
    6.         // note: in forward rendering, baked vertex lighting is added to the emission channel in the surface shader, not in the lighting model
    7.         half3 h = normalize (lightDir + viewDir);
    8.         fixed diff = max (0, dot (s.Normal, lightDir));
    9.         float nh = max (0, dot (s.Normal, h));
    10.         float spec = pow (nh, s.Specular*128.0) * s.Gloss;
    11.         fixed4 c;
    12.         c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * _SpecColor.rgb * spec) * (atten * 2);
    13.         c.a = (s.Alpha + _LightColor0.a * _SpecColor.a * spec * atten) * s.AlphaFog; // attenuate alpha by fog
    14.         return c;
    15.     }
    16.    
    17.     // Deferred lighting mode
    18.     inline fixed4 LightingBlinnPhong_BakedVertexLighting_PrePass (SurfaceOutputVtxC s, half4 light) {
    19.         fixed spec = light.a * s.Gloss;
    20.         fixed4 c;
    21.         light.rgb += s.VertexColor; // add baked vertex colors to lighting
    22.         c.rgb = s.Albedo * light.rgb + light.rgb * _SpecColor.rgb * spec;
    23.         c.a = (s.Alpha + spec * _SpecColor.a) * s.AlphaFog; // Add specular to alpha channel for glow and such, attenuate by fog
    24.         return c;
    25.     }
    Code (csharp):
    1. // Assets/Shaders/includes/SurfaceOutputVtxC.cginc
    2. struct SurfaceOutputVtxC {
    3.     fixed3 Albedo;
    4.     fixed3 Normal;
    5.     fixed3 Emission;
    6.     half Specular;
    7.     fixed Gloss;
    8.     fixed Alpha;
    9.     fixed3 VertexColor;
    10.     half AlphaFog;
    11. };
    Code (csharp):
    1. // Assets/Shaders/includes/AlphaFog_Vert.cginc
    2. void vert (inout appdata_full v, out Input o) {
    3.   // Linear Alpha Fog
    4.   float4 pos = mul(UNITY_MATRIX_MV, v.vertex); // get pos in camera space
    5.   float distFromViewport = length(pos.xyz);
    6.   o.fog = saturate((35 - distFromViewport) / (35 - 20)); // linear fog
    7. }
     
    Last edited: Jun 19, 2012
  2. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Ok, this is beginning to feel like a big bug with surface shaders to me. Or else a pretty big oversight on warning about exceeding register/instruction limits in target 3.0 surface shaders. (How am I supposed to know how many registers/instructions are being used when all the lighting/shadowing/fog code is auto-generated?)

    I've got ANOTHER shader showing up in wild color tints like my previous two problem shaders. Basically when I make a fairly long surface shader, at any point one single extra addition or multiplication may end up turning my whole texture wild green, red, or blue tints on the final output, sometimes in deferred mode only, sometimes in forward mode only, and sometimes in both modes. There is NO warning or error displayed in the inspector when the shader is selected.

    Is this how surface shaders are supposed to behave? Is there any other tool in unity (like Profiler) that I don't know about that tells you how many registers/instructions a surface shader is using? This is getting to be a big pain.

    Yet even this doesn't explain why the exact same shader would work in one project and not another...
     
    Last edited: Jun 19, 2012
  3. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    I created yet another surface shader that is completely ignoring two float properties I've set which control the speed of UV scrolling. I've done this many times before in other shaders with no problem, but on certain shaders (usually bumped, specular shaders), I start getting random properties being ignored (like the _Color property problem I mentioned in the 1st post).

    The more of these wild bugs I get I feel my project is somehow corrupted but I'm not sure if there's any way to go about fixing it. My project is currently 6.5GB so it's a little bit hairy to think about dumping out and importing back in.

    Another thing I see ALL the time is a "Repainting while performing asset operations!" error every single time anything compiles (shader, script, etc.) This even shows up on a new scene in a new project. Maybe I should just reinstall Unity...
     
    Last edited: Jun 20, 2012
  4. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    The past week I've started getting even more errors when importing fbx meshes...

    Moving file failed
    Moving C:/.../Temp/tempFile to
    C:/.../Assets/... .mat failed: The filename, directory name, or volume label syntax is incorrect.

    I fails to create a material with the name of the texture like it usually does. It's trying to make a new material named TEXTURENAME.tga instead of just TEXTURENAME like it normally does. In the imported mesh, it keeps a reference to the broken TEXTURENAME.tga material, and even if I manually create the proper TEXTURENAME material and reimport the mesh, it still keeps the broken link to the missing TEXTURENAME.tga material. Even closing and opening unity does not reimport the mesh with the proper material.

    I know this is a shader forum, but I can't help but feel like all this is related to my shader woes.

    Posted in this better thread: http://forum.unity3d.com/threads/24363-Unity-Alert
     
    Last edited: Jun 20, 2012
  5. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Back to the first post in the thread, my problem with the emissive bumped specular shader...

    The line:
    o.Alpha = _Color.a * emis; // glow based on glow intensity, and emissive map

    I've done a little more testing and it seems to me that, for some reason, fixed values are being locked in for certain variables in the Properties section. I tried using different color channels and got different results even though the color value set were 1, 1, 1, 0.2

    Substituting _Color.r for _Color.a, I get a fixed value of 0 even though value is 1.0
    Substituting _Color.g for _Color.a, I get a fixed value of 0.153 even though value is 1.0
    Substituting _Color.b for _Color.a, I get a fixed value of 0.153 even though value is 1.0
    Using _Color.a gives me a fixed value of 1.0 even though value is set to 0.2

    -----------------

    After further testing, I'm pretty sure it all boils down some weird bug relating to my custom lighting model for vertex lighting. I found that if I pass any constant through VertexColor EXCEPT 0, it works. If I pass 0, it fails as before. If I pass the real vertex color, it fails as well. This makes no sense to me.

    Code (csharp):
    1. // Deferred lighting mode
    2. inline fixed4 LightingBlinnPhong_BakedVertexLighting_PrePass (SurfaceOutputVtxC s, half4 light) {
    3.     fixed spec = light.a * s.Gloss;
    4.     fixed4 c;
    5.     light.rgb += s.VertexColor; // add vertex color lighting
    6.     c.rgb = s.Albedo * light.rgb + light.rgb * _SpecColor.rgb * spec;
    7.     c.a = (s.Alpha + spec * _SpecColor.a) * s.AlphaFog; // Add specular to alpha channel for glow and such
    8. }
    This makes no sense at all because I'm getting bad values in ALPHA output and s.VertexColor is NOT involved in the c.a output calculation at all, therefore having a fixed value (other than zero) in s.VertexColor shouldn't do a thing to my alpha output.

    I just tried something else. I let the shader pass the real vertex color through s.VertexColor, but this time I substituted a constant of 0.5 in place of s.VertexColor directly in the custom lighting model and IT WORKED. Again, substituting a constant of 0 FAILED. What kind of magic is going on with light.rgb that a plain old zero can't be added to it or it borks the Alpha channel output?

    Edit: Even if I change the alpha output calculation to a simple "c.a = s.Alpha;", it still breaks.

    Edit 2: What the... if I totally rem out the line "light.rgb += s.VertexColor;" and ADD NOTHING to light, it FAILS, but if I change it to "light.rgb += 1;" it WORKS. This is starting to feel like the world of web development where 1+1 MIGHT = 2.

    Edit 3: Okay this is stupid. If I do NOTHING but "o.VertexColor = IN.color + 0.00001;", suddenly IT WORKS. The act of adding an infinitesimally small value to the vertex color, which then gets added to light.rgb in the custom lighting model makes _Color.a contain the value it was supposed to have in the first place instead of some random fixed value, even though _Color is completely unrelated to VertexColor, makes utterly no sense whatsoever.

    This is not an instruction limit problem like I kept assuming I guess. It's something totally different. I don't even begin to know how to report this bug.

    I mentioned in my 3rd post:
    In this case I was trying to create two float properties that also got corrupted just like the _Color property. I saw the same exact behavior. The value would get arbitrarily locked to some constant value and would accept no settings input in the inspector. So I'm concluding there's some kind of property variable corruption going on with surface shaders, yet I haven't found a specific reason yet, but it seems to have a connection to using custom lighting models or creating custom structs to pass to a custom lighting model.
     
    Last edited: Jun 21, 2012
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Sigh.......... Yet again.

    Another shader decides to get it's underwear in a knot and midway during writing it, it decides to start corrupting the .R channel of a 2D texture. (A greyscale 24-bit texture, I was using the R channel for the 0-1 value, but had to switch to using the G channel because any time I'd multiply anything by the R value in the shader, the whole thing would show up grey instead of the proper color.)

    I'm wasting so many hours a day fighting these dang property input corruption bugs. I guess I'm the only one who has ever encountered this. What a joke.

    Edit. Even a complete uninstall and reinstall didn't help.
     
    Last edited: Jun 21, 2012
  7. HypnoToad

    HypnoToad

    Joined:
    Jan 8, 2013
    Posts:
    8
    I am getting a whole bunch of input issues as well.. it happens a lot on the skinned mesh renderers for me... spent a whole day figuring out why on earth my characters are messed up.. I am not using surface shaders though.. I am using plain cg
     
  8. HypnoToad

    HypnoToad

    Joined:
    Jan 8, 2013
    Posts:
    8

    I have been getting very similar issues and I am on the latest version of unity.. 4.1.5. I feel your pain. I am having issues at certain camera angles where a constant in the shader that is exposed as a property would get its value corrupted some how.. but if i hard code the value in the shader it works fine..
     
  9. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Sorry to hear you're running into this too. And I'm very sad to hear its still a problem in the latest builds. I haven't messed with this since last year. I never did find a solution. I just switched channels holding the data if something was broken. Still, I wonder what's going to happen on end-users' machines when I get to the final build...
     
  10. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    The Cg compiler seems to be optimizing some values away that it shouldn't.
     
  11. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    5,624
    Very interesting information! Thank you for posting that. At least that's a partial explanation to some of these shader problems.