Shader not working after Unity update

Hi! I ran in to a little problem when opening an old project in unity (5.5), and that is that my shader stopped working. Before it drew circles on the on the materials based on the distance from the camera as seen here: https://gfycat.com/FeminineBelatedCuscus.

But now it’s just dark, anybody got an idea why that is?

The code is

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/HihglightShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma target 3.0   
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            const static int _NumberOfHighlights = 30;
           
            //float2 arrays because for some reason float  arrays doesn't work, seems to be a bug.
            float2 _HighlightWidth[_NumberOfHighlights];
            float2 _HighlightDistance[_NumberOfHighlights];
            float4 _BackgroundColor;
            float4 _HighlightColor[_NumberOfHighlights];
            float4 _HighlightStartPosition[_NumberOfHighlights];

            struct v2f
            {
                float4 position : SV_POSITION;
                float4 worldSpacePosition : TEXCOORD0;
            };

            v2f vert(appdata_full vertIn)
            {
                v2f o;
                o.position = mul(UNITY_MATRIX_MVP, vertIn.vertex);
                o.worldSpacePosition = mul(unity_ObjectToWorld, vertIn.vertex);
                return o;
            }

            float4 frag(v2f fragIn) : COLOR
            {
               
                float4 pixelWorldSpacePosition = fragIn.worldSpacePosition; //The pixel position in the world grid
                float4 c_out = _BackgroundColor;

                for (int i = 0; i < _NumberOfHighlights; i++)
                {
                    //The pixel distance from the current higlights starting position, if the distance is 0, the width has been set to 0 through script.
                    float _PixelDistance = length(pixelWorldSpacePosition - _HighlightStartPosition[i]);
                    //_Colordifference is calculated to make shure the highlights gets the correct color if the background isn't black.
                    float4 _ColorDifference = _HighlightColor[i] - _BackgroundColor;
                   
                    //The first step function makes shure no color is added to the backgorund before _HighlightDistance[i].x, then a smoothstep to add a fade over the highlight and last one more step function to make shur no color is added after the highlight.
                    c_out += _ColorDifference *step(_HighlightDistance[i].x, _PixelDistance) * smoothstep(_HighlightDistance[i].x, _HighlightDistance[i].x + _HighlightWidth[i].x, _PixelDistance) * step(_PixelDistance, _HighlightDistance[i].x + _HighlightWidth[i].x);
                }
                return c_out;
            }
            ENDCG
        }
    }
}

How about:

float _PixelDistance = length(pixelWorldSpacePosition.xyz - _HighlightStartPosition[i].xyz);

Unfortunately that didn’t solve it

Are you sure it’s the shader? How were you setting the values in the arrays? If you were using SetFloat() or SetVector() there are proper SetFloatArray() functions now.

I have a similar issue, the same setup on OSX works fine, but on windows it looks wrong. I’m pretty sure it has something to do with the depth texture:

Windows 10

OSX:

Shader "Test/Render Depth"
{
    Properties
    {
        _RegularColor("Main Color", Color) = (1, 1, 1, .5)
        _HighlightColor("Highlight Color", Color) = (1, 1, 1, .5)
        _HighlightThresholdMax("Highlight Threshold Max", Float) = 1
    }
    SubShader
    {
        Tags { "Queue" = "Transparent" "RenderType"="Transparent"  }
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
            Cull Off
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            uniform sampler2D_float _CameraDepthTexture;
            uniform float4 _RegularColor;
            uniform float4 _HighlightColor;
            uniform float _HighlightThresholdMax;
            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 projPos : TEXCOORD1;
            };
            v2f vert(appdata_base v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.projPos = ComputeScreenPos(o.pos);
                return o;
            }
            half4 frag(v2f i) : COLOR
            {
                float4 finalColor = _RegularColor;
                float sceneZ = LinearEyeDepth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r);
                float partZ = i.projPos.z;
                float diff = (abs(sceneZ - partZ)) / _HighlightThresholdMax;
                if(diff <= 1)
                {
                    finalColor = lerp(_HighlightColor, _RegularColor, float4(diff, diff, diff, diff));
                }

                half4 c = diff;
               
                return c;
            }
            ENDCG
        }
    }
    FallBack "VertexLit"
}

I’ve tried to rewrite the shader using fixed values to avoid any problem like that, but it still doesn’t work.

The modified code:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Custom/HihglightShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma target 3.0   
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            const static int _NumberOfHighlights = 30;
           
            //float2 arrays because for some reason float  arrays doesn't work, seems to be a bug.
            float2 _HighlightWidth[_NumberOfHighlights];
            float2 _HighlightDistance[_NumberOfHighlights];
            float4 _BackgroundColor;
            float4 _HighlightColor[_NumberOfHighlights];
            float4 _HighlightStartPosition[_NumberOfHighlights];

            struct v2f
            {
                float4 position : SV_POSITION;
                float4 worldSpacePosition : TEXCOORD0;
            };

            v2f vert(appdata_full vertIn)
            {
                v2f o;
                o.position = mul(UNITY_MATRIX_MVP, vertIn.vertex);
                o.worldSpacePosition = mul(unity_ObjectToWorld, vertIn.vertex);
                return o;
            }

            float4 frag(v2f fragIn) : COLOR
            {
               
                float4 pixelWorldSpacePosition = fragIn.worldSpacePosition; //The pixel position in the world grid
                float4 c_out = _BackgroundColor;

                for (int i = 0; i < _NumberOfHighlights; i++)
                {
                    //The pixel distance from the current higlights starting position, if the distance is 0, the width has been set to 0 through script.
                    float _PixelDistance = length(pixelWorldSpacePosition.xyz - _HighlightStartPosition[i].xyz);
                    //_Colordifference is calculated to make shure the highlights gets the correct color if the background isn't black.
                    float4 _ColorDifference = _HighlightColor[i] - _BackgroundColor;
                   
                    //The first step function makes shure no color is added to the backgorund before _HighlightDistance[i].x, then a smoothstep to add a fade over the highlight and last one more step function to make shur no color is added after the highlight.
                    c_out += float4(1, 0, 1, 0) *step(5, _PixelDistance) * smoothstep(5, 5 + 1, _PixelDistance) * step(_PixelDistance, 5 + 1);
                }
                return c_out;
            }
            ENDCG
        }
    }
}

That’s going to make things worse. Going forward you should use UnityObjectToClipPos(vertPos); instead of mul(UNITY_MATRIX_MVP, vertpos); but that’s totally different than world position.

Indeed, it should be the o.pos that is set to that. I shouldn’t be replying when I’m sleep deprived haha. Their shader seems to work for me though, but I removed the arrays to test it with just a single point.

I think you need to check if the platform is reversed depth buffer.

float sceneZ = LinearEyeDepth(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r);
#ifdef UNITY_REVERSED_Z
    sceneZ = 1 - sceneZ;
#endif

After some poking around in the scripts it turns out you where right, and now it all works! Thank you all how took the time to help me =)

After upgrading from Unity5 to Unity2017 I had a similar issue.

In one case I had to undo the automatic update to my shader:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
//o.vertex = UnityObjectToClipPos( v.vertex );  // <-- Unity added this
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  // <-- original code, Unity removed this

In another case with a different shader I had to disable MSAA on my camera.

I haven’t investigated either of these issues, but this was how I fixed it.