private void UpdateShader()
    {
        var starDirection       = planetLightSource != null ? (planetLightSource.transform.position - transform.position).normalized : Vector3.up;
        var lightSourcePosition = planetLightSource != null ? planetLightSource.transform.position : Vector3.zero;
        var transformPosition   = transform.position;
        var uniformScale        = UniformScale;
        var observerPosition    = planetObserver != null ? planetObserver.transform.position : Vector3.zero;
        var distance            = (observerPosition - transformPosition).magnitude;

        float maxSurfaceDepth, maxAtmosphereDepth;

        SGT_Helper.CalculateHorizonAtmosphereDepth(surfaceRadius * uniformScale, AtmosphereRadius * uniformScale, distance, out maxSurfaceDepth, out maxAtmosphereDepth);

        // Common shader variables
        SGT_ShaderHelper.SetVector(surfaceMaterials, "centrePosition", transformPosition);
        SGT_ShaderHelper.SetVector(surfaceMaterials, "starDirection", starDirection);

        if (surfaceTextureNormal != null)
        {
            var starDirectionM = surfaceGameObject.transform.worldToLocalMatrix.MultiplyVector(starDirection).normalized;

            SGT_ShaderHelper.SetVector(surfaceMaterials, "starDirectionM", starDirectionM);
        }

        if (atmosphereMaterial != null)
        {
            var altitudeUnclamped = distance - surfaceRadius * uniformScale;
            var altitude          = Mathf.Clamp(altitudeUnclamped, 0.0f, atmosphereHeight * uniformScale);
            var atmoAlt           = SGT_Helper.RemapClamped(atmosphereHeight * uniformScale * atmosphereSkyAltitude, atmosphereHeight * uniformScale, altitude, 0.0f, 1.0f);

            SGT_ShaderHelper.SetFloat(surfaceMaterials, "maxDepth", maxSurfaceDepth * (1.0f - atmosphereFog));             // FOG

            atmosphereMaterial.SetFloat("maxDepth", maxAtmosphereDepth);
            atmosphereMaterial.SetVector("centrePosition", transformPosition);
            atmosphereMaterial.SetVector("starDirection", starDirection);
            atmosphereMaterial.SetFloat("atmosphereFalloff", Mathf.SmoothStep(atmosphereFalloffInside, atmosphereFalloffOutside, atmoAlt));

            if (atmosphereScattering == true)
            {
                SGT_ShaderHelper.SetVector(surfaceMaterials, "starPosition", lightSourcePosition);

                atmosphereMaterial.SetVector("starPosition", lightSourcePosition);
            }
        }

        if (cloudsMaterials != null)
        {
            SGT_ShaderHelper.SetVector(cloudsMaterials, "centrePosition", transformPosition);
            SGT_ShaderHelper.SetVector(cloudsMaterials, "starDirection", starDirection);
        }

        if (shadow == true)
        {
            var shadowMatrix = Matrix4x4.identity;

            switch (shadowCasterType)
            {
            case SGT_ShadowOccluder.Planet:
            {
                if (shadowCasterGameObject != null)
                {
                    shadowMatrix = SGT_Helper.CalculateSphereShadowMatrix(ShadowCasterRadiusOuter, shadowCasterGameObject.transform.position, lightSourcePosition, transformPosition, uniformScale);
                }
            }
            break;

            case SGT_ShadowOccluder.Ring:
            {
                shadowMatrix = SGT_Helper.CalculateCircleShadowMatrix(ShadowCasterRadiusOuter, transform.position, transform.up, lightSourcePosition, transformPosition, uniformScale);
            }
            break;
            }

            SGT_ShaderHelper.SetMatrix(surfaceMaterials, "shadowMatrix", shadowMatrix);

            if (atmosphereMaterial != null)
            {
                atmosphereMaterial.SetMatrix("shadowMatrix", shadowMatrix);
            }
            if (cloudsMaterials != null)
            {
                SGT_ShaderHelper.SetMatrix(cloudsMaterials, "shadowMatrix", shadowMatrix);
            }
        }

        // Uncommon shader variables
        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.ShadowSettings) == true)
        {
            var cutoff       = ShadowCasterRadiusInner / ShadowCasterRadiusOuter;
            var invCutoff    = SGT_Helper.Reciprocal(1.0f - cutoff);
            var shadowValues = new Vector3(cutoff, invCutoff, 1.0f + ShadowCasterRadiusOuter);

            SGT_ShaderHelper.SetVector(surfaceMaterials, "shadowValues", shadowValues);

            if (atmosphereMaterial != null)
            {
                atmosphereMaterial.SetVector("shadowValues", shadowValues);
            }
            if (cloudsMaterials != null)
            {
                SGT_ShaderHelper.SetVector(cloudsMaterials, "shadowValues", shadowValues);
            }
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureDay) == true)
        {
            for (var i = 0; i < surfaceMaterials.Length; i++)
            {
                surfaceMaterials[i].SetTexture("dayTexture", surfaceTextureDay.GetTexture((CubemapFace)i));
            }
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureNight) == true)
        {
            for (var i = 0; i < surfaceMaterials.Length; i++)
            {
                surfaceMaterials[i].SetTexture("nightTexture", surfaceTextureNight.GetTexture((CubemapFace)i));
            }
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureNormal) == true)
        {
            for (var i = 0; i < surfaceMaterials.Length; i++)
            {
                surfaceMaterials[i].SetTexture("normalTexture", surfaceTextureNormal.GetTexture((CubemapFace)i));
            }
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureSpecular) == true)
        {
            for (var i = 0; i < surfaceMaterials.Length; i++)
            {
                surfaceMaterials[i].SetTexture("specularTexture", surfaceTextureSpecular.GetTexture((CubemapFace)i));
            }
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceSpecularSettings) == true)
        {
            SGT_ShaderHelper.SetFloat(surfaceMaterials, "specularPower", surfaceSpecularPower * surfaceSpecularPower);
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureDetail) == true)
        {
            SGT_ShaderHelper.SetTexture(surfaceMaterials, "detailTexture", surfaceTextureDetail);
            SGT_ShaderHelper.SetFloat(surfaceMaterials, "detailRepeat", surfaceDetailRepeat);
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureLighting) == true)
        {
            SGT_ShaderHelper.SetTexture(surfaceMaterials, "lightingTexture", surfaceLightingTexture);
        }

        if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureShadow) == true)
        {
            SGT_ShaderHelper.SetTexture(surfaceMaterials, "shadowTexture", shadowTextureSurface);
        }

        if (atmosphereMaterial != null)
        {
            SGT_ShaderHelper.SetFloat(surfaceMaterials, "atmosphereRadius", AtmosphereRadius * uniformScale);
            SGT_ShaderHelper.SetFloat(surfaceMaterials, "atmosphereFalloff", atmosphereFalloffSurface);
            SGT_ShaderHelper.SetFloat(surfaceMaterials, "surfaceRadius", surfaceRadius * uniformScale);
            SGT_ShaderHelper.SetFloat(surfaceMaterials, "atmosphereHeight", atmosphereHeight * uniformScale);

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.SurfaceTextureAtmosphere) == true)
            {
                SGT_ShaderHelper.SetTexture(surfaceMaterials, "atmosphereTexture", atmosphereSurfaceTexture);
            }

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.AtmosphereTexture) == true)
            {
                atmosphereMaterial.SetTexture("atmosphereTexture", atmosphereTexture);
            }

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.AtmosphereTextureShadow) == true)
            {
                atmosphereMaterial.SetTexture("shadowTexture", shadowTextureAtmosphere);
            }

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.ScatteringSettings) == true)
            {
                var mie  = -(1.0f - 1.0f / Mathf.Pow(10.0f, atmosphereScatteringMie * 5.0f));
                var mie4 = new Vector4(mie * 2.0f, 1.0f - mie * mie, 1.0f + mie * mie, 1.5f);
                var ray2 = new Vector2(0.0f, atmosphereScatteringRayleigh);

                SGT_ShaderHelper.SetVector(surfaceMaterials, "rayleighValues", ray2);

                atmosphereMaterial.SetVector("mieValues", mie4);
                atmosphereMaterial.SetVector("rayleighValues", ray2);
            }
        }

        if (cloudsMaterials != null)
        {
            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.CloudsTextureShadow) == true)
            {
                SGT_ShaderHelper.SetTexture(cloudsMaterials, "shadowTexture", shadowTextureClouds);
            }

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.CloudsTexture) == true)
            {
                for (var i = 0; i < cloudsMaterials.Length; i++)
                {
                    cloudsMaterials[i].SetTexture("cloudsTexture", cloudsTexture.GetTexture((CubemapFace)i));
                }
            }

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.CloudsTextureLighting) == true)
            {
                SGT_ShaderHelper.SetTexture(cloudsMaterials, "lightingTexture", cloudsLightingTexture);
            }

            if (SGT_Helper.FlagIsSet(updateShader, ShaderFlags.CloudsFalloffSettings) == true)
            {
                SGT_ShaderHelper.SetFloat(cloudsMaterials, "falloff", cloudsFalloff * cloudsFalloff);
            }
        }

        updateShader = 0;
    }