Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

variable 'c1' used without having been completely initialized ( error on line 96 )

Discussion in 'Shaders' started by Dark_Seth, Mar 15, 2017.

  1. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    134
    Hi all. I am looking for assistance on a shader after upgrading to V5 of unity. All I manage to find out is that I need something like UNITY_INITIALIZE_OUTPUT(c1,o) . It didn't work. My know how about shaders are limited.

    Please help me to get this working again.

    The Shader

    Code (CSharp):
    1.  
    2. Shader "Custom/Echo/MultipleUsingTexture" {
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.         _EchoTex ("Echo (RGBA)", 2D) = "white" {}
    6.         _MainColor ("Main Color",Color) = (1.0,1.0,1.0,1.0)  
    7.         _DistanceFade("Distance Fade",float) = 1.0  
    8.         _MaxRadius("MaxRadius",float) = 1.0
    9.         _MaxFade("MaxFade",float) = 1.0
    10.        
    11.     }
    12.     SubShader {
    13.         Tags { "RenderType"="Opaque" }
    14.         LOD 200
    15.        
    16.         CGPROGRAM
    17.        
    18.         // Target Shader Model 3.0 or you won't have enough arithmetic instructions for float unpack
    19.         #pragma target 3.0
    20.         #pragma surface surf NoLighting
    21.         #include "UnityCG.cginc"
    22.        
    23.         struct Input {
    24.             float2 uv_MainTex;
    25.             float3 worldPos;  
    26.         };
    27.        
    28.         sampler2D _MainTex;
    29.         sampler2D _EchoTex;
    30.        
    31.         float4 _MainColor;
    32.         float _DistanceFade;
    33.         float _MaxRadius;
    34.         float _MaxFade;
    35.        
    36.         // Custom light model that ignores actual lighting.
    37.         half4 LightingNoLighting (SurfaceOutput s, half3 lightDir, half atten) {
    38.             half4 c;
    39.             c.rgb = s.Albedo;
    40.             c.a = s.Alpha;
    41.             return c;
    42.         }
    43.        
    44.         //unpack float from pixel
    45.         float unpackFloat4( float4 _packed)
    46.         {
    47.             float4 rgba = 255.0 * _packed;
    48.             float sign =  step(-128.0, -rgba[1]) * 2.0 - 1.0;
    49.             float exponent = rgba[0] - 127.0;  
    50.             if (abs(exponent + 127.0) < 0.001){
    51.                 return 0.0;    
    52.             } else {    
    53.                 float mantissa =  fmod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + (0x800000);
    54.                 return sign *  exp2(exponent-23.0) * mantissa ;    
    55.             }
    56.         }
    57.         float ApplyFade(Input IN,float textureOffset){
    58.             float3 position;
    59.             float size = 128.0;         //hard coded texture width/height
    60.            
    61.             //NOTE:  UV's are [0,1] so divide by the width(or height, they should be equal) of the image.
    62.             //In this example the texture is 128x128.
    63.             position[0] = unpackFloat4(tex2D(_EchoTex,float2(textureOffset/size,0.0)));
    64.             position[1] = unpackFloat4(tex2D(_EchoTex,float2(textureOffset/size,1.0/size)));
    65.             position[2] = unpackFloat4(tex2D(_EchoTex,float2(textureOffset/size,2.0/size)));
    66.            
    67.             float radius = unpackFloat4(tex2D(_EchoTex,float2(textureOffset/size,3.0/size)));
    68.             float infade = unpackFloat4(tex2D(_EchoTex,float2(textureOffset/size,4.0/size)));
    69.            
    70.             float dist = distance(IN.worldPos, position);    // Distance from current pixel (from its world coord) to center of echo sphere
    71.            
    72.             if(radius >= 3*_MaxRadius || dist >= radius){
    73.                 return 0.0;
    74.             } else {
    75.                 // If _DistanceFade = true, fading is related to vertex distance from echo origin.
    76.                 // If false, fading is even across entire echo.
    77.                 float c1 = (_DistanceFade>=1.0)?dist/radius:1.0;
    78.                
    79.                 // Apply fading effect.
    80.                 c1 *= (infade<=_MaxFade)?1.0-infade/_MaxFade:0.0;    //adjust by fade distance.
    81.                
    82.                 // Ignore Fade values <= 0 (meaning no fade.)
    83.                 c1 = (infade<=0)?1.0:c1;
    84.                
    85.                 return c1;
    86.             }
    87.         }
    88.         // Custom surfacer that mimics an echo effect
    89.         void surf (Input IN, inout SurfaceOutput o) {
    90.            
    91.             float c1;
    92.             //UNITY_INITIALIZE_OUTPUT(c1, o);
    93.             //Unity was not pleased with my use of a for loop.  Somewhere
    94.             //in the loop unroll Unity blew up and crashed.  So echo count
    95.             //is hardcoded to be 3 here.
    96.             c1 += ApplyFade(IN,0.0);
    97.             c1 += ApplyFade(IN,1.0);
    98.             c1 += ApplyFade(IN,2.0);
    99.             c1 /= 3.0;
    100.            
    101.             float c2 = 1.0 - c1;
    102.            
    103.             o.Albedo = _MainColor.rgb * c2 + tex2D (_MainTex, IN.uv_MainTex).rgb * c1 ;      
    104.         }
    105.         ENDCG
    106.     }
    107.     FallBack "Diffuse"
    108. }
    109.  
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    float c1 = 0.0;

    Your code is taking a variable that's not been assigned any value and adding to it. Most of the time shader compilers can figure out that value should probably be a zero in your case, but there's nothing in the shader language spec that says it has to be that as it's uninitialized, and what shaders do when adding to an uninitialized variable is undefined. There's a programming quote I like that goes something like "using an undefined behavior may cause unicorns to fly out of my butt"; in short it's undefined, so anything could happen.

    Setting it to 0.0 instead of leaving it uninitialized should solve your problem. That UNITY_INITIALIZE_OUTPUT macro is for setting all values in a struct to 0.0 for similar reasons. It didn't work for you since you're using it wrong as it should be:

    UNITY_INITIALIZE_OUTPUT(float, c1)

    But that produced identical results to the first line of this post.
     
    Last edited: Mar 15, 2017
    Dark_Seth likes this.
  3. FuzzyQuills

    FuzzyQuills

    Joined:
    Jun 8, 2013
    Posts:
    2,871
    On the other hand, I've found only Direct3D targets get this, while OpenGL build targets don't.
    Just another D3D annoyance everyone has to deal with.
    And yes, UNITY_INITIALIZE_OUTPUT is overkill in this case, just setting the value to 0 on declaration should fix it.
     
    Dark_Seth likes this.
  4. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    134
    Thanks you both. Will test and give feedback. The unicorn thing.. will always remember that now. So funny but true
     
  5. Dark_Seth

    Dark_Seth

    Joined:
    May 28, 2014
    Posts:
    134
    Confirmed. Working 100%