Turning Cull Off in rimlight shader makes the 2nd side of mesh the color of the rim

Hey, guys. I’ve recently looked up how to turn culling off for meshes. I am using the Toony Gooch Rimlight Shader and I’ve added Cull Off to the script. While the backfaces became visible, they also become completely covered with the same color of the rimlight I am using for the model. For the sake of seeing it easier, I made the rimlight green. You’ll see at the back of the character the backface of his scarf. It’s supposed to be a textured blood red, but it’s being blanketed with a harsh green.


Shader "Toony Gooch/Toony Gooch RimLight"




        _Color ("Main Color", Color) = (1,1,1,1)


        _MainTex ("Base (RGB)", 2D) = "white" {}

        _Ramp ("Toon Ramp (RGB)", 2D) = "gray" {}


        _RimColor ("Rim Color", Color) = (0.8,0.8,0.8,0.6)

        _RimPower ("Rim Power", Float) = 1.4


        _SColor ("Shadow Color", Color) = (0.0,0.0,0.0,1)

        _LColor ("Highlight Color", Color) = (0.5,0.5,0.5,1)





        Tags { "RenderType"="Opaque" }

        LOD 200

        Cull Off




        #pragma surface surf ToonRamp


        sampler2D _MainTex;

        sampler2D _Ramp;

        float4 _LColor;

        float4 _SColor;

        float4 _Color;

        float _RimPower;

        float4 _RimColor;


        // custom lighting function that uses a texture ramp based

        // on angle between light direction and normal

        #pragma lighting ToonRamp exclude_path:prepass

        inline half4 LightingToonRamp (SurfaceOutput s, half3 lightDir, half atten)


            #ifndef USING_DIRECTIONAL_LIGHT

            lightDir = normalize(lightDir);



            half d = dot (s.Normal, lightDir)*0.5 + 0.5;

            half3 ramp = tex2D(_Ramp, float2(d,d)).rgb;

            ramp = lerp(_SColor,_LColor,ramp);


            half4 c;

            c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);

            c.a = 0;


            return c;



        struct Input


            float2 uv_MainTex : TEXCOORD0;

            float3 pos : POSITION0;

            float3 viewDir;



        void surf (Input IN, inout SurfaceOutput o)


            half4 c = tex2D(_MainTex, IN.uv_MainTex);


            o.Albedo = c.rgb * _Color.rgb;

            o.Alpha = c.a;


            //Rim Light

            half rim = 1.0f - saturate( dot(normalize(IN.viewDir), o.Normal) );

            o.Emission = (_RimColor.rgb * pow(rim, _RimPower)) * _RimColor.a;






    Fallback "Toon/Lighted"


I understand this question is dated, but I’m providing an answer for archive purposes.

The rim light from what I understand follows a fresnel method, so for the light color, everything except what is facing the camera is visible. Considering that ‘Cull Off’ just turns on rendering of polygons on the other side, that doesn’t mean that the normals of the mesh are flipped as well. Here is what I have done.

             //Rim Light
             //Default rim light, seen in the front
             half rim = 1.0f - saturate( dot(normalize(IN.viewDir), o.Normal) );

             //My extra instruction that does the same thing above, but in reverse
             half backRim = 1.0f - saturate( dot(normalize(-IN.viewDir), o.Normal) );

             //Final assembled result
             o.Emission = ((_RimColor.rgb * pow(rim, _RimPower)) *
             (_RimColor.rgb * pow(backRim, _RimPower)) ) * _RimColor.a;