{
  "__type__": "cc.EffectAsset",
  "_name": "pipeline/deferred-lighting",
  "_objFlags": 0,
  "_native": "",
  "techniques": [
    {
      "passes": [
        {
          "pass": "deferred-lighting",
          "program": "pipeline/deferred-lighting|lighting-vs|lighting-fs",
          "depthStencilState": {
            "depthFunc": 4,
            "depthTest": true,
            "depthWrite": false
          }
        }
      ]
    }
  ],
  "shaders": [
    {
      "blocks": [],
      "samplerTextures": [
        {
          "name": "gbuffer_albedoMap",
          "type": 28,
          "count": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 0
        },
        {
          "name": "gbuffer_normalMap",
          "type": 28,
          "count": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 1
        },
        {
          "name": "gbuffer_emissiveMap",
          "type": 28,
          "count": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 2
        },
        {
          "name": "depth_stencil",
          "type": 28,
          "count": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 3
        }
      ],
      "samplers": [],
      "textures": [],
      "buffers": [
        {
          "name": "b_ccLightsBuffer",
          "memoryAccess": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 4
        },
        {
          "name": "b_clusterLightIndicesBuffer",
          "memoryAccess": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 5
        },
        {
          "name": "b_clusterLightGridBuffer",
          "memoryAccess": 1,
          "defines": [],
          "stageFlags": 16,
          "binding": 6
        }
      ],
      "images": [],
      "subpassInputs": [],
      "attributes": [
        {
          "name": "a_position",
          "defines": [],
          "format": 32,
          "location": 0
        },
        {
          "name": "a_normal",
          "defines": [],
          "format": 32,
          "location": 1
        },
        {
          "name": "a_texCoord",
          "defines": [],
          "format": 21,
          "location": 2
        },
        {
          "name": "a_tangent",
          "defines": [],
          "format": 44,
          "location": 3
        },
        {
          "name": "a_joints",
          "defines": [
            "CC_USE_SKINNING"
          ],
          "location": 4
        },
        {
          "name": "a_weights",
          "defines": [
            "CC_USE_SKINNING"
          ],
          "format": 44,
          "location": 5
        },
        {
          "name": "a_jointAnimInfo",
          "defines": [
            "USE_INSTANCING",
            "CC_USE_BAKED_ANIMATION"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 6
        },
        {
          "name": "a_matWorld0",
          "defines": [
            "USE_INSTANCING"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 7
        },
        {
          "name": "a_matWorld1",
          "defines": [
            "USE_INSTANCING"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 8
        },
        {
          "name": "a_matWorld2",
          "defines": [
            "USE_INSTANCING"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 9
        },
        {
          "name": "a_lightingMapUVParam",
          "defines": [
            "USE_INSTANCING",
            "CC_USE_LIGHTMAP"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 10
        },
        {
          "name": "a_localShadowBias",
          "defines": [
            "USE_INSTANCING",
            "CC_RECEIVE_SHADOW"
          ],
          "format": 21,
          "isInstanced": true,
          "location": 11
        },
        {
          "name": "a_sh_linear_const_r",
          "defines": [
            "USE_INSTANCING",
            "CC_USE_LIGHT_PROBE"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 12
        },
        {
          "name": "a_sh_linear_const_g",
          "defines": [
            "USE_INSTANCING",
            "CC_USE_LIGHT_PROBE"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 13
        },
        {
          "name": "a_sh_linear_const_b",
          "defines": [
            "USE_INSTANCING",
            "CC_USE_LIGHT_PROBE"
          ],
          "format": 44,
          "isInstanced": true,
          "location": 14
        },
        {
          "name": "a_vertexId",
          "defines": [
            "CC_USE_MORPH"
          ],
          "format": 11,
          "location": 15
        }
      ],
      "varyings": [
        {
          "name": "v_uv",
          "type": 14,
          "count": 1,
          "defines": [],
          "stageFlags": 17,
          "location": 0
        },
        {
          "name": "v_sh_linear_const_r",
          "type": 16,
          "count": 1,
          "defines": [
            "CC_USE_LIGHT_PROBE",
            "USE_INSTANCING"
          ],
          "stageFlags": 16,
          "location": 1
        },
        {
          "name": "v_sh_linear_const_g",
          "type": 16,
          "count": 1,
          "defines": [
            "CC_USE_LIGHT_PROBE",
            "USE_INSTANCING"
          ],
          "stageFlags": 16,
          "location": 2
        },
        {
          "name": "v_sh_linear_const_b",
          "type": 16,
          "count": 1,
          "defines": [
            "CC_USE_LIGHT_PROBE",
            "USE_INSTANCING"
          ],
          "stageFlags": 16,
          "location": 3
        }
      ],
      "fragColors": [
        {
          "name": "fragColor",
          "typename": "vec4",
          "type": 16,
          "count": 1,
          "defines": [],
          "stageFlags": 16,
          "location": 0
        }
      ],
      "descriptors": [
        {
          "rate": 0,
          "blocks": [
            {
              "tags": {
                "builtin": "local"
              },
              "name": "CCSH",
              "members": [
                {
                  "name": "cc_sh_linear_const_r",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                },
                {
                  "name": "cc_sh_linear_const_g",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                },
                {
                  "name": "cc_sh_linear_const_b",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                },
                {
                  "name": "cc_sh_quadratic_r",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                },
                {
                  "name": "cc_sh_quadratic_g",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                },
                {
                  "name": "cc_sh_quadratic_b",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                },
                {
                  "name": "cc_sh_quadratic_a",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1
                }
              ],
              "defines": [
                "CC_USE_LIGHT_PROBE",
                "!USE_INSTANCING"
              ],
              "stageFlags": 16
            },
            {
              "tags": {
                "builtin": "local"
              },
              "name": "CCForwardLight",
              "members": [
                {
                  "name": "cc_lightPos",
                  "typename": "vec4",
                  "type": 16,
                  "count": 0,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_lightColor",
                  "typename": "vec4",
                  "type": 16,
                  "count": 0,
                  "isArray": true
                },
                {
                  "name": "cc_lightSizeRangeAngle",
                  "typename": "vec4",
                  "type": 16,
                  "count": 0,
                  "isArray": true
                },
                {
                  "name": "cc_lightDir",
                  "typename": "vec4",
                  "type": 16,
                  "count": 0,
                  "isArray": true
                }
              ],
              "defines": [
                "CC_ENABLE_CLUSTERED_LIGHT_CULLING"
              ],
              "stageFlags": 16
            }
          ],
          "samplerTextures": [
            {
              "tags": {
                "builtin": "local"
              },
              "name": "cc_reflectionProbeCubemap",
              "typename": "samplerCube",
              "type": 31,
              "count": 1,
              "defines": [
                "CC_USE_REFLECTION_PROBE"
              ],
              "stageFlags": 16
            },
            {
              "tags": {
                "builtin": "local"
              },
              "name": "cc_reflectionProbePlanarMap",
              "typename": "sampler2D",
              "type": 28,
              "count": 1,
              "defines": [
                "CC_USE_REFLECTION_PROBE"
              ],
              "stageFlags": 16
            }
          ],
          "samplers": [],
          "textures": [],
          "buffers": [],
          "images": [],
          "subpassInputs": []
        },
        {
          "rate": 1,
          "blocks": [],
          "samplerTextures": [],
          "samplers": [],
          "textures": [],
          "buffers": [
            {
              "name": "b_ccLightsBuffer",
              "memoryAccess": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 4
            },
            {
              "name": "b_clusterLightIndicesBuffer",
              "memoryAccess": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 5
            },
            {
              "name": "b_clusterLightGridBuffer",
              "memoryAccess": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 6
            }
          ],
          "images": [],
          "subpassInputs": []
        },
        {
          "rate": 2,
          "blocks": [],
          "samplerTextures": [],
          "samplers": [],
          "textures": [],
          "buffers": [],
          "images": [],
          "subpassInputs": []
        },
        {
          "rate": 3,
          "blocks": [
            {
              "tags": {
                "builtin": "global"
              },
              "name": "CCGlobal",
              "members": [
                {
                  "name": "cc_time",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_screenSize",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_nativeSize",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_debug_view_mode",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_debug_view_composite_pack_1",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_debug_view_composite_pack_2",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_debug_view_composite_pack_3",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                }
              ],
              "defines": [],
              "stageFlags": 17
            },
            {
              "tags": {
                "builtin": "global"
              },
              "name": "CCCamera",
              "members": [
                {
                  "name": "cc_matView",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_matViewInv",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_matProj",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_matProjInv",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_matViewProj",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_matViewProjInv",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_cameraPos",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_surfaceTransform",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_screenScale",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_exposure",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_mainLitDir",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_mainLitColor",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_ambientSky",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_ambientGround",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_fogColor",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_fogBase",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_fogAdd",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_nearFar",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_viewPort",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                }
              ],
              "defines": [],
              "stageFlags": 17
            },
            {
              "tags": {
                "builtin": "global"
              },
              "name": "CCShadow",
              "members": [
                {
                  "name": "cc_matLightView",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_matLightViewProj",
                  "typename": "mat4",
                  "type": 25,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_shadowInvProjDepthInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_shadowProjDepthInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_shadowProjInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "highp "
                },
                {
                  "name": "cc_shadowNFLSInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_shadowWHPBInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_shadowLPNNInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                },
                {
                  "name": "cc_shadowColor",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "lowp "
                },
                {
                  "name": "cc_planarNDInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "mediump "
                }
              ],
              "defines": [],
              "stageFlags": 16
            },
            {
              "tags": {
                "builtin": "global"
              },
              "name": "CCCSM",
              "members": [
                {
                  "name": "cc_csmViewDir0",
                  "typename": "vec4",
                  "type": 16,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_csmViewDir1",
                  "typename": "vec4",
                  "type": 16,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_csmViewDir2",
                  "typename": "vec4",
                  "type": 16,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_csmAtlas",
                  "typename": "vec4",
                  "type": 16,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_matCSMViewProj",
                  "typename": "mat4",
                  "type": 25,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_csmProjDepthInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_csmProjInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 4,
                  "precision": "highp ",
                  "isArray": true
                },
                {
                  "name": "cc_csmSplitsInfo",
                  "typename": "vec4",
                  "type": 16,
                  "count": 1,
                  "precision": "highp "
                }
              ],
              "defines": [
                "CC_SUPPORT_CASCADED_SHADOW_MAP"
              ],
              "stageFlags": 16
            }
          ],
          "samplerTextures": [
            {
              "tags": {
                "builtin": "global"
              },
              "name": "cc_shadowMap",
              "typename": "sampler2D",
              "type": 28,
              "count": 1,
              "precision": "highp ",
              "defines": [
                "CC_RECEIVE_SHADOW"
              ],
              "stageFlags": 16
            },
            {
              "tags": {
                "builtin": "global"
              },
              "name": "cc_spotShadowMap",
              "typename": "sampler2D",
              "type": 28,
              "count": 1,
              "precision": "highp ",
              "defines": [
                "CC_RECEIVE_SHADOW"
              ],
              "stageFlags": 16
            },
            {
              "tags": {
                "builtin": "global"
              },
              "name": "cc_environment",
              "typename": "samplerCube",
              "type": 31,
              "count": 1,
              "defines": [
                "CC_USE_IBL"
              ],
              "stageFlags": 16
            },
            {
              "tags": {
                "builtin": "global"
              },
              "name": "cc_diffuseMap",
              "typename": "samplerCube",
              "type": 31,
              "count": 1,
              "defines": [
                "CC_USE_IBL",
                "CC_USE_DIFFUSEMAP"
              ],
              "stageFlags": 16
            },
            {
              "name": "gbuffer_albedoMap",
              "type": 28,
              "count": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 0
            },
            {
              "name": "gbuffer_normalMap",
              "type": 28,
              "count": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 1
            },
            {
              "name": "gbuffer_emissiveMap",
              "type": 28,
              "count": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 2
            },
            {
              "name": "depth_stencil",
              "type": 28,
              "count": 1,
              "defines": [],
              "stageFlags": 16,
              "binding": 3
            }
          ],
          "samplers": [],
          "textures": [],
          "buffers": [],
          "images": [],
          "subpassInputs": []
        }
      ],
      "hash": 3554769488,
      "glsl4": {
        "vert": "\nprecision highp float;\n#define QUATER_PI         0.78539816340\n#define HALF_PI           1.57079632679\n#define PI                3.14159265359\n#define PI2               6.28318530718\n#define PI4               12.5663706144\n#define INV_QUATER_PI     1.27323954474\n#define INV_HALF_PI       0.63661977237\n#define INV_PI            0.31830988618\n#define INV_PI2           0.15915494309\n#define INV_PI4           0.07957747155\n#define EPSILON           1e-6\n#define EPSILON_LOWP      1e-4\n#define LOG2              1.442695\n#define EXP_VALUE         2.71828183f\n#define FP_MAX            65504.0\n#define FP_SCALE          0.0009765625\n#define FP_SCALE_INV      1024.0\n#define GRAY_VECTOR       vec3(0.299, 0.587, 0.114)\n#define LIGHT_MAP_TYPE_DISABLED 0\n#define LIGHT_MAP_TYPE_ALL_IN_ONE 1\n#define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2\n#define REFLECTION_PROBE_TYPE_NONE 0\n#define REFLECTION_PROBE_TYPE_CUBE 1\n#define REFLECTION_PROBE_TYPE_PLANAR 2\n#define LIGHT_TYPE_DIRECTIONAL 0.0\n#define LIGHT_TYPE_SPHERE 1.0\n#define LIGHT_TYPE_SPOT 2.0\n#define IS_DIRECTIONAL_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_DIRECTIONAL)) < EPSILON)\n#define IS_SPHERE_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPHERE)) < EPSILON)\n#define IS_SPOT_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPOT)) < EPSILON)\nstruct StandardVertInput {\n  highp vec4 position;\n  vec3 normal;\n  vec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\n    layout(location = 4) in u32vec4 a_joints;\n  layout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n  #if CC_USE_BAKED_ANIMATION\n    layout(location = 6) in highp vec4 a_jointAnimInfo;\n  #endif\n  layout(location = 7) in vec4 a_matWorld0;\n  layout(location = 8) in vec4 a_matWorld1;\n  layout(location = 9) in vec4 a_matWorld2;\n  #if CC_USE_LIGHTMAP\n    layout(location = 10) in vec4 a_lightingMapUVParam;\n  #endif\n  #if CC_RECEIVE_SHADOW\n    layout(location = 11) in vec2 a_localShadowBias;\n  #endif\n  #if CC_USE_LIGHT_PROBE\n    layout(location = 12) in vec4 a_sh_linear_const_r;\n    layout(location = 13) in vec4 a_sh_linear_const_g;\n    layout(location = 14) in vec4 a_sh_linear_const_b;\n  #endif\n#endif\n#if CC_USE_MORPH\n#endif\nlayout(set = 0, binding = 0) uniform CCGlobal {\n  highp   vec4 cc_time;\n  mediump vec4 cc_screenSize;\n  mediump vec4 cc_nativeSize;\n  mediump vec4 cc_debug_view_mode;\n  mediump vec4 cc_debug_view_composite_pack_1;\n  mediump vec4 cc_debug_view_composite_pack_2;\n  mediump vec4 cc_debug_view_composite_pack_3;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\n  highp   mat4 cc_matView;\n  highp   mat4 cc_matViewInv;\n  highp   mat4 cc_matProj;\n  highp   mat4 cc_matProjInv;\n  highp   mat4 cc_matViewProj;\n  highp   mat4 cc_matViewProjInv;\n  highp   vec4 cc_cameraPos;\n  mediump vec4 cc_surfaceTransform;\n  mediump vec4 cc_screenScale;\n  mediump vec4 cc_exposure;\n  mediump vec4 cc_mainLitDir;\n  mediump vec4 cc_mainLitColor;\n  mediump vec4 cc_ambientSky;\n  mediump vec4 cc_ambientGround;\n  mediump vec4 cc_fogColor;\n  mediump vec4 cc_fogBase;\n  mediump vec4 cc_fogAdd;\n  mediump vec4 cc_nearFar;\n  mediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\n  vec4 position;\n    position = vec4(a_position, 1.0);\n  position.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\n  gl_Position = vec4(position.x, position.y, 1.0, 1.0);\n  v_uv = a_texCoord;\n}",
        "frag": "\n  precision highp float;\n  layout(set = 0, binding = 0) uniform CCGlobal {\n    highp   vec4 cc_time;\n    mediump vec4 cc_screenSize;\n    mediump vec4 cc_nativeSize;\n    mediump vec4 cc_debug_view_mode;\n    mediump vec4 cc_debug_view_composite_pack_1;\n    mediump vec4 cc_debug_view_composite_pack_2;\n    mediump vec4 cc_debug_view_composite_pack_3;\n  };\n  layout(set = 0, binding = 1) uniform CCCamera {\n    highp   mat4 cc_matView;\n    highp   mat4 cc_matViewInv;\n    highp   mat4 cc_matProj;\n    highp   mat4 cc_matProjInv;\n    highp   mat4 cc_matViewProj;\n    highp   mat4 cc_matViewProjInv;\n    highp   vec4 cc_cameraPos;\n    mediump vec4 cc_surfaceTransform;\n    mediump vec4 cc_screenScale;\n    mediump vec4 cc_exposure;\n    mediump vec4 cc_mainLitDir;\n    mediump vec4 cc_mainLitColor;\n    mediump vec4 cc_ambientSky;\n    mediump vec4 cc_ambientGround;\n    mediump vec4 cc_fogColor;\n    mediump vec4 cc_fogBase;\n    mediump vec4 cc_fogAdd;\n    mediump vec4 cc_nearFar;\n    mediump vec4 cc_viewPort;\n  };\n  #define QUATER_PI         0.78539816340\n  #define HALF_PI           1.57079632679\n  #define PI                3.14159265359\n  #define PI2               6.28318530718\n  #define PI4               12.5663706144\n  #define INV_QUATER_PI     1.27323954474\n  #define INV_HALF_PI       0.63661977237\n  #define INV_PI            0.31830988618\n  #define INV_PI2           0.15915494309\n  #define INV_PI4           0.07957747155\n  #define EPSILON           1e-6\n  #define EPSILON_LOWP      1e-4\n  #define LOG2              1.442695\n  #define EXP_VALUE         2.71828183f\n  #define FP_MAX            65504.0\n  #define FP_SCALE          0.0009765625\n  #define FP_SCALE_INV      1024.0\n  #define GRAY_VECTOR       vec3(0.299, 0.587, 0.114)\n      #define LIGHT_MAP_TYPE_DISABLED 0\n  #define LIGHT_MAP_TYPE_ALL_IN_ONE 1\n  #define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2\n  #define REFLECTION_PROBE_TYPE_NONE 0\n  #define REFLECTION_PROBE_TYPE_CUBE 1\n  #define REFLECTION_PROBE_TYPE_PLANAR 2\n  #define LIGHT_TYPE_DIRECTIONAL 0.0\n  #define LIGHT_TYPE_SPHERE 1.0\n  #define LIGHT_TYPE_SPOT 2.0\n  #define IS_DIRECTIONAL_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_DIRECTIONAL)) < EPSILON)\n  #define IS_SPHERE_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPHERE)) < EPSILON)\n  #define IS_SPOT_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPOT)) < EPSILON)\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_COLOR 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_NORMAL CC_SURFACES_DEBUG_VIEW_VERTEX_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_TANGENT CC_SURFACES_DEBUG_VIEW_VERTEX_NORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_WORLD_POS CC_SURFACES_DEBUG_VIEW_VERTEX_TANGENT + 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_MIRROR CC_SURFACES_DEBUG_VIEW_WORLD_POS + 1\n  #define CC_SURFACES_DEBUG_VIEW_FACE_SIDE CC_SURFACES_DEBUG_VIEW_VERTEX_MIRROR + 1\n  #define CC_SURFACES_DEBUG_VIEW_UV0 CC_SURFACES_DEBUG_VIEW_FACE_SIDE + 1\n  #define CC_SURFACES_DEBUG_VIEW_UV1 CC_SURFACES_DEBUG_VIEW_UV0 + 1\n  #define CC_SURFACES_DEBUG_VIEW_UVLIGHTMAP CC_SURFACES_DEBUG_VIEW_UV1 + 1\n  #define CC_SURFACES_DEBUG_VIEW_PROJ_DEPTH CC_SURFACES_DEBUG_VIEW_UVLIGHTMAP + 1\n  #define CC_SURFACES_DEBUG_VIEW_LINEAR_DEPTH CC_SURFACES_DEBUG_VIEW_PROJ_DEPTH + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_NORMAL CC_SURFACES_DEBUG_VIEW_LINEAR_DEPTH + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_TANGENT CC_SURFACES_DEBUG_VIEW_FRAGMENT_NORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_BINORMAL CC_SURFACES_DEBUG_VIEW_FRAGMENT_TANGENT + 1\n  #define CC_SURFACES_DEBUG_VIEW_BASE_COLOR CC_SURFACES_DEBUG_VIEW_FRAGMENT_BINORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIFFUSE_COLOR CC_SURFACES_DEBUG_VIEW_BASE_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_SPECULAR_COLOR CC_SURFACES_DEBUG_VIEW_DIFFUSE_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_TRANSPARENCY CC_SURFACES_DEBUG_VIEW_SPECULAR_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_METALLIC CC_SURFACES_DEBUG_VIEW_TRANSPARENCY + 1\n  #define CC_SURFACES_DEBUG_VIEW_ROUGHNESS CC_SURFACES_DEBUG_VIEW_METALLIC + 1\n  #define CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY CC_SURFACES_DEBUG_VIEW_ROUGHNESS + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_ALL CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE CC_SURFACES_DEBUG_VIEW_DIRECT_ALL + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_ALL CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR + 1\n  #define CC_SURFACES_DEBUG_VIEW_EMISSIVE CC_SURFACES_DEBUG_VIEW_ENV_ALL + 1\n  #define CC_SURFACES_DEBUG_VIEW_LIGHT_MAP CC_SURFACES_DEBUG_VIEW_EMISSIVE + 1\n  #define CC_SURFACES_DEBUG_VIEW_SHADOW CC_SURFACES_DEBUG_VIEW_LIGHT_MAP + 1\n  #define CC_SURFACES_DEBUG_VIEW_AO CC_SURFACES_DEBUG_VIEW_SHADOW + 1\n  #define CC_SURFACES_DEBUG_VIEW_FOG CC_SURFACES_DEBUG_VIEW_AO + 1\n  #define CC_SURFACES_DEBUG_VIEW_SINGLE 1\n  #define CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC 2\n  #define IS_DEBUG_VIEW_ENABLE_WITH_CAMERA (cc_surfaceTransform.y != 3.0)\n    #define IS_DEBUG_VIEW_LIGHTING_ENABLE_WITH_ALBEDO ((cc_debug_view_mode.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_MISC_ENABLE_CSM_LAYER_COLORATION ((cc_debug_view_mode.z > 0.0) && IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_DIFFUSE ((cc_debug_view_composite_pack_1.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_SPECULAR ((cc_debug_view_composite_pack_1.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_DIFFUSE ((cc_debug_view_composite_pack_1.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_SPECULAR ((cc_debug_view_composite_pack_1.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_EMISSIVE ((cc_debug_view_composite_pack_2.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_LIGHT_MAP ((cc_debug_view_composite_pack_2.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_SHADOW ((cc_debug_view_composite_pack_2.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_AO ((cc_debug_view_composite_pack_2.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_NORMAL_MAP ((cc_debug_view_composite_pack_3.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_FOG ((cc_debug_view_composite_pack_3.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING ((cc_debug_view_composite_pack_3.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION ((cc_debug_view_composite_pack_3.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  vec3 SRGBToLinear (vec3 gamma) {\n  #ifdef CC_USE_SURFACE_SHADER\n    #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC\n      if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION) {\n        return gamma;\n      }\n    #endif\n  #endif\n    return gamma * gamma;\n  }\n  vec3 LinearToSRGB(vec3 linear) {\n  #ifdef CC_USE_SURFACE_SHADER\n    #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC\n      if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION) {\n        return linear;\n      }\n    #endif\n  #endif\n    return sqrt(linear);\n  }\n  layout(set = 0, binding = 2) uniform CCShadow {\n    highp mat4 cc_matLightView;\n    highp mat4 cc_matLightViewProj;\n    highp vec4 cc_shadowInvProjDepthInfo;\n    highp vec4 cc_shadowProjDepthInfo;\n    highp vec4 cc_shadowProjInfo;\n    mediump vec4 cc_shadowNFLSInfo;\n    mediump vec4 cc_shadowWHPBInfo;\n    mediump vec4 cc_shadowLPNNInfo;\n    lowp vec4 cc_shadowColor;\n    mediump vec4 cc_planarNDInfo;\n  };\n  #if CC_SUPPORT_CASCADED_SHADOW_MAP\n    layout(set = 0, binding = 3) uniform CCCSM {\n      highp vec4 cc_csmViewDir0[4];\n      highp vec4 cc_csmViewDir1[4];\n      highp vec4 cc_csmViewDir2[4];\n      highp vec4 cc_csmAtlas[4];\n      highp mat4 cc_matCSMViewProj[4];\n      highp vec4 cc_csmProjDepthInfo[4];\n      highp vec4 cc_csmProjInfo[4];\n      highp vec4 cc_csmSplitsInfo;\n    };\n  #endif\n  vec2 GetPlanarReflectScreenUV(vec3 worldPos, mat4 matVirtualCameraViewProj, float flipNDCSign, vec3 viewDir, vec3 reflectDir)\n  {\n    vec4 clipPos = matVirtualCameraViewProj * vec4(worldPos, 1.0);\n    vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5;\n    screenUV = vec2(1.0 - screenUV.x, screenUV.y);\n    screenUV = flipNDCSign == 1.0 ? vec2(screenUV.x, 1.0 - screenUV.y) : screenUV;\n    return screenUV;\n  }\n  float GetCameraDepthRH(float depthHS, mat4 matProj)\n  {\n      return -matProj[3][2] / (depthHS + matProj[2][2]);\n  }\n  float GetCameraDepthRH(float depthHS, float matProj32, float matProj22)\n  {\n      return -matProj32 / (depthHS + matProj22);\n  }\n  vec4 GetWorldPosFromNDCPosRH(vec3 posHS, mat4 matProj, mat4 matViewProjInv)\n  {\n      float w = -GetCameraDepthRH(posHS.z, matProj);\n      return matViewProjInv * vec4(posHS * w, w);\n  }\n  float GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\n    float dist = length(viewPos);\n    return (dist - near) / (far - near);\n  }\n  vec3 RotationVecFromAxisY(vec3 v, float cosTheta, float sinTheta)\n  {\n      vec3 result;\n      result.x = dot(v, vec3(cosTheta, 0.0, -sinTheta));\n      result.y = v.y;\n      result.z = dot(v, vec3(sinTheta, 0.0,  cosTheta));\n      return result;\n  }\n  float CCGetLinearDepth(vec3 worldPos, float viewSpaceBias) {\n  \tvec4 viewPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\n    viewPos.z += viewSpaceBias;\n  \treturn GetLinearDepthFromViewSpace(viewPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n  }\n  float CCGetLinearDepth(vec3 worldPos) {\n  \treturn CCGetLinearDepth(worldPos, 0.0);\n  }\n  #if CC_RECEIVE_SHADOW\n    layout(set = 0, binding = 4) uniform highp sampler2D cc_shadowMap;\n    layout(set = 0, binding = 6) uniform highp sampler2D cc_spotShadowMap;\n        highp float unpackHighpData (float mainPart, float modPart) {\n          highp float data = mainPart;\n          return data + modPart;\n        }\n        highp float unpackHighpData (float mainPart, float modPart, const float modValue) {\n          highp float data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\n          highp vec2 data = mainPart;\n          return data + modPart;\n        }\n        highp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\n          highp vec2 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\n          highp vec3 data = mainPart;\n          return data + modPart;\n        }\n        highp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\n          highp vec3 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\n          highp vec4 data = mainPart;\n          return data + modPart;\n        }\n        highp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\n          highp vec4 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n    float NativePCFShadowFactorHard (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      #if CC_SHADOWMAP_FORMAT == 1\n        return step(shadowNDCPos.z, dot(texture(shadowMap, shadowNDCPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        return step(shadowNDCPos.z, texture(shadowMap, shadowNDCPos.xy).x);\n      #endif\n    }\n    float NativePCFShadowFactorSoft (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      vec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap;\n      float block0, block1, block2, block3;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\n        block1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)).x);\n        block2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)).x);\n        block3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)).x);\n      #endif\n      float coefX   = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\n      float resultX = mix(block0, block1, coefX);\n      float resultY = mix(block2, block3, coefX);\n      float coefY   = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\n      return mix(resultX, resultY, coefY);\n    }\n    float NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      float shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x;\n      float shadowNDCPos_offset_R = shadowNDCPos.x + oneTap.x;\n      float shadowNDCPos_offset_U = shadowNDCPos.y - oneTap.y;\n      float shadowNDCPos_offset_D = shadowNDCPos.y + oneTap.y;\n      float block0, block1, block2, block3, block4, block5, block6, block7, block8;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block4 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block5 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block6 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block7 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block8 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)).x);\n        block1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)).x);\n        block2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)).x);\n        block3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)).x);\n        block4 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\n        block5 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)).x);\n        block6 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)).x);\n        block7 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)).x);\n        block8 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)).x);\n      #endif\n      float coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\n      float coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\n      float shadow = 0.0;\n      float resultX = mix(block0, block1, coefX);\n      float resultY = mix(block3, block4, coefX);\n      shadow += mix(resultX , resultY, coefY);\n      resultX = mix(block1, block2, coefX);\n      resultY = mix(block4, block5, coefX);\n      shadow += mix(resultX , resultY, coefY);\n      resultX = mix(block3, block4, coefX);\n      resultY = mix(block6, block7, coefX);\n      shadow += mix(resultX, resultY, coefY);\n      resultX = mix(block4, block5, coefX);\n      resultY = mix(block7, block8, coefX);\n      shadow += mix(resultX, resultY, coefY);\n      return shadow * 0.25;\n    }\n    float NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      vec2 twoTap = oneTap * 2.0;\n      vec2 offset1 = shadowNDCPos.xy + vec2(-twoTap.x, -twoTap.y);\n      vec2 offset2 = shadowNDCPos.xy + vec2(-oneTap.x, -twoTap.y);\n      vec2 offset3 = shadowNDCPos.xy + vec2(0.0, -twoTap.y);\n      vec2 offset4 = shadowNDCPos.xy + vec2(oneTap.x, -twoTap.y);\n      vec2 offset5 = shadowNDCPos.xy + vec2(twoTap.x, -twoTap.y);\n      vec2 offset6 = shadowNDCPos.xy + vec2(-twoTap.x, -oneTap.y);\n      vec2 offset7 = shadowNDCPos.xy + vec2(-oneTap.x, -oneTap.y);\n      vec2 offset8 = shadowNDCPos.xy + vec2(0.0, -oneTap.y);\n      vec2 offset9 = shadowNDCPos.xy + vec2(oneTap.x, -oneTap.y);\n      vec2 offset10 = shadowNDCPos.xy + vec2(twoTap.x, -oneTap.y);\n      vec2 offset11 = shadowNDCPos.xy + vec2(-twoTap.x, 0.0);\n      vec2 offset12 = shadowNDCPos.xy + vec2(-oneTap.x, 0.0);\n      vec2 offset13 = shadowNDCPos.xy + vec2(0.0, 0.0);\n      vec2 offset14 = shadowNDCPos.xy + vec2(oneTap.x, 0.0);\n      vec2 offset15 = shadowNDCPos.xy + vec2(twoTap.x, 0.0);\n      vec2 offset16 = shadowNDCPos.xy + vec2(-twoTap.x, oneTap.y);\n      vec2 offset17 = shadowNDCPos.xy + vec2(-oneTap.x, oneTap.y);\n      vec2 offset18 = shadowNDCPos.xy + vec2(0.0, oneTap.y);\n      vec2 offset19 = shadowNDCPos.xy + vec2(oneTap.x, oneTap.y);\n      vec2 offset20 = shadowNDCPos.xy + vec2(twoTap.x, oneTap.y);\n      vec2 offset21 = shadowNDCPos.xy + vec2(-twoTap.x, twoTap.y);\n      vec2 offset22 = shadowNDCPos.xy + vec2(-oneTap.x, twoTap.y);\n      vec2 offset23 = shadowNDCPos.xy + vec2(0.0, twoTap.y);\n      vec2 offset24 = shadowNDCPos.xy + vec2(oneTap.x, twoTap.y);\n      vec2 offset25 = shadowNDCPos.xy + vec2(twoTap.x, twoTap.y);\n      float block1, block2, block3, block4, block5, block6, block7, block8, block9, block10, block11, block12, block13, block14, block15, block16, block17, block18, block19, block20, block21, block22, block23, block24, block25;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block1 = step(shadowNDCPos.z, dot(texture(shadowMap, offset1), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture(shadowMap, offset2), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture(shadowMap, offset3), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block4 = step(shadowNDCPos.z, dot(texture(shadowMap, offset4), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block5 = step(shadowNDCPos.z, dot(texture(shadowMap, offset5), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block6 = step(shadowNDCPos.z, dot(texture(shadowMap, offset6), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block7 = step(shadowNDCPos.z, dot(texture(shadowMap, offset7), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block8 = step(shadowNDCPos.z, dot(texture(shadowMap, offset8), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block9 = step(shadowNDCPos.z, dot(texture(shadowMap, offset9), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block10 = step(shadowNDCPos.z, dot(texture(shadowMap, offset10), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block11 = step(shadowNDCPos.z, dot(texture(shadowMap, offset11), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block12 = step(shadowNDCPos.z, dot(texture(shadowMap, offset12), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block13 = step(shadowNDCPos.z, dot(texture(shadowMap, offset13), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block14 = step(shadowNDCPos.z, dot(texture(shadowMap, offset14), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block15 = step(shadowNDCPos.z, dot(texture(shadowMap, offset15), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block16 = step(shadowNDCPos.z, dot(texture(shadowMap, offset16), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block17 = step(shadowNDCPos.z, dot(texture(shadowMap, offset17), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block18 = step(shadowNDCPos.z, dot(texture(shadowMap, offset18), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block19 = step(shadowNDCPos.z, dot(texture(shadowMap, offset19), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block20 = step(shadowNDCPos.z, dot(texture(shadowMap, offset20), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block21 = step(shadowNDCPos.z, dot(texture(shadowMap, offset21), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block22 = step(shadowNDCPos.z, dot(texture(shadowMap, offset22), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block23 = step(shadowNDCPos.z, dot(texture(shadowMap, offset23), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block24 = step(shadowNDCPos.z, dot(texture(shadowMap, offset24), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block25 = step(shadowNDCPos.z, dot(texture(shadowMap, offset25), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block1 = step(shadowNDCPos.z, texture(shadowMap, offset1).x);\n        block2 = step(shadowNDCPos.z, texture(shadowMap, offset2).x);\n        block3 = step(shadowNDCPos.z, texture(shadowMap, offset3).x);\n        block4 = step(shadowNDCPos.z, texture(shadowMap, offset4).x);\n        block5 = step(shadowNDCPos.z, texture(shadowMap, offset5).x);\n        block6 = step(shadowNDCPos.z, texture(shadowMap, offset6).x);\n        block7 = step(shadowNDCPos.z, texture(shadowMap, offset7).x);\n        block8 = step(shadowNDCPos.z, texture(shadowMap, offset8).x);\n        block9 = step(shadowNDCPos.z, texture(shadowMap, offset9).x);\n        block10 = step(shadowNDCPos.z, texture(shadowMap, offset10).x);\n        block11 = step(shadowNDCPos.z, texture(shadowMap, offset11).x);\n        block12 = step(shadowNDCPos.z, texture(shadowMap, offset12).x);\n        block13 = step(shadowNDCPos.z, texture(shadowMap, offset13).x);\n        block14 = step(shadowNDCPos.z, texture(shadowMap, offset14).x);\n        block15 = step(shadowNDCPos.z, texture(shadowMap, offset15).x);\n        block16 = step(shadowNDCPos.z, texture(shadowMap, offset16).x);\n        block17 = step(shadowNDCPos.z, texture(shadowMap, offset17).x);\n        block18 = step(shadowNDCPos.z, texture(shadowMap, offset18).x);\n        block19 = step(shadowNDCPos.z, texture(shadowMap, offset19).x);\n        block20 = step(shadowNDCPos.z, texture(shadowMap, offset20).x);\n        block21 = step(shadowNDCPos.z, texture(shadowMap, offset21).x);\n        block22 = step(shadowNDCPos.z, texture(shadowMap, offset22).x);\n        block23 = step(shadowNDCPos.z, texture(shadowMap, offset23).x);\n        block24 = step(shadowNDCPos.z, texture(shadowMap, offset24).x);\n        block25 = step(shadowNDCPos.z, texture(shadowMap, offset25).x);\n      #endif\n      vec2 coef = fract(shadowNDCPos.xy * shadowMapResolution);\n      vec2 v1X1 = mix(vec2(block1, block6), vec2(block2, block7), coef.xx);\n      vec2 v1X2 = mix(vec2(block2, block7), vec2(block3, block8), coef.xx);\n      vec2 v1X3 = mix(vec2(block3, block8), vec2(block4, block9), coef.xx);\n      vec2 v1X4 = mix(vec2(block4, block9), vec2(block5, block10), coef.xx);\n      float v1 = mix(v1X1.x, v1X1.y, coef.y) + mix(v1X2.x, v1X2.y, coef.y) + mix(v1X3.x, v1X3.y, coef.y) + mix(v1X4.x, v1X4.y, coef.y);\n      vec2 v2X1 = mix(vec2(block6, block11), vec2(block7, block12), coef.xx);\n      vec2 v2X2 = mix(vec2(block7, block12), vec2(block8, block13), coef.xx);\n      vec2 v2X3 = mix(vec2(block8, block13), vec2(block9, block14), coef.xx);\n      vec2 v2X4 = mix(vec2(block9, block14), vec2(block10, block15), coef.xx);\n      float v2 = mix(v2X1.x, v2X1.y, coef.y) + mix(v2X2.x, v2X2.y, coef.y) + mix(v2X3.x, v2X3.y, coef.y) + mix(v2X4.x, v2X4.y, coef.y);\n      vec2 v3X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\n      vec2 v3X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\n      vec2 v3X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\n      vec2 v3X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\n      float v3 = mix(v3X1.x, v3X1.y, coef.y) + mix(v3X2.x, v3X2.y, coef.y) + mix(v3X3.x, v3X3.y, coef.y) + mix(v3X4.x, v3X4.y, coef.y);\n      vec2 v4X1 = mix(vec2(block16, block21), vec2(block17, block22), coef.xx);\n      vec2 v4X2 = mix(vec2(block17, block22), vec2(block18, block23), coef.xx);\n      vec2 v4X3 = mix(vec2(block18, block23), vec2(block19, block24), coef.xx);\n      vec2 v4X4 = mix(vec2(block19, block24), vec2(block20, block25), coef.xx);\n      float v4 = mix(v4X1.x, v4X1.y, coef.y) + mix(v4X2.x, v4X2.y, coef.y) + mix(v4X3.x, v4X3.y, coef.y) + mix(v4X4.x, v4X4.y, coef.y);\n      float fAvg = (v1 + v2 + v3 + v4) * 0.0625;\n      return fAvg;\n    }\n    bool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)\n    {\n    \tshadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;\n    \tif (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||\n    \t\tshadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||\n    \t\tshadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {\n    \t\treturn false;\n    \t}\n    \tshadowNDCPos.xy = cc_cameraPos.w == 1.0 ? vec2(shadowNDCPos.xy.x, 1.0 - shadowNDCPos.xy.y) : shadowNDCPos.xy;\n    \treturn true;\n    }\n    vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, vec3 matViewDir0, vec3 matViewDir1, vec3 matViewDir2, vec2 projScaleXY)\n    {\n      vec4 newShadowPos = shadowPos;\n      if (normalBias > EPSILON_LOWP)\n      {\n        vec3 viewNormal = vec3(dot(matViewDir0, worldNormal), dot(matViewDir1, worldNormal), dot(matViewDir2, worldNormal));\n        if (viewNormal.z < 0.1)\n          newShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n      }\n      return newShadowPos;\n    }\n    vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)\n    {\n    \tvec4 newShadowPos = shadowPos;\n    \tif (normalBias > EPSILON_LOWP)\n    \t{\n    \t\tvec4 viewNormal = matLightView * vec4(worldNormal, 0.0);\n    \t\tif (viewNormal.z < 0.1)\n    \t\t\tnewShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n    \t}\n    \treturn newShadowPos;\n    }\n    float GetViewSpaceDepthFromNDCDepth_Orthgraphic(float NDCDepth, float projScaleZ, float projBiasZ)\n    {\n    \treturn (NDCDepth - projBiasZ) / projScaleZ;\n    }\n    float GetViewSpaceDepthFromNDCDepth_Perspective(float NDCDepth, float homogenousDividW, float invProjScaleZ, float invProjBiasZ)\n    {\n    \treturn NDCDepth * invProjScaleZ + homogenousDividW * invProjBiasZ;\n    }\n    vec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n    {\n    \tvec3 viewSpacePos;\n    \tviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\n    \tviewSpacePos.z = GetViewSpaceDepthFromNDCDepth_Perspective(shadowPos.z, shadowPos.w, cc_shadowInvProjDepthInfo.x, cc_shadowInvProjDepthInfo.y);\n    \tviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\n    \tvec4 clipSpacePos;\n    \tclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\n    \tclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\n    \t#if CC_SHADOWMAP_USE_LINEAR_DEPTH\n    \t\tclipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n    \t\tclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n    \t#endif\n    \treturn clipSpacePos;\n    }\n    vec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)\n    {\n    \tfloat coeffA = projScaleZ;\n    \tfloat coeffB = projBiasZ;\n    \tfloat viewSpacePos_z = GetViewSpaceDepthFromNDCDepth_Orthgraphic(shadowPos.z, projScaleZ, projBiasZ);\n    \tviewSpacePos_z += viewspaceDepthBias;\n    \tvec4 result = shadowPos;\n    \tresult.z = viewSpacePos_z * coeffA + coeffB;\n    \treturn result;\n    }\n    vec4 ApplyShadowDepthBias_PerspectiveLinearDepth(vec4 shadowPos, float viewspaceDepthBias, vec3 worldPos)\n    {\n      shadowPos.z = CCGetLinearDepth(worldPos, viewspaceDepthBias) * 2.0 - 1.0;\n      shadowPos.z *= shadowPos.w;\n      return shadowPos;\n    }\n    float CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorHard(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCSpotShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n    {\n      float pcf = cc_shadowWHPBInfo.z;\n      vec4 pos = vec4(1.0);\n      #if CC_SHADOWMAP_USE_LINEAR_DEPTH\n        pos = ApplyShadowDepthBias_PerspectiveLinearDepth(shadowPos, shadowBias.x, worldPos);\n      #else\n        pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);\n      #endif\n      float realtimeShadow = 1.0;\n      if (pcf > 2.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft5X(pos, worldPos);\n      }else if (pcf > 1.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft3X(pos, worldPos);\n      }else if (pcf > 0.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft(pos, worldPos);\n      }else {\n        realtimeShadow = CCGetSpotLightShadowFactorHard(pos, worldPos);\n      }\n      shadowNDCPosWithBias = pos;\n      return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n    }\n    float CCShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 N, vec2 shadowBias)\n    {\n      vec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);\n      pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);\n      float realtimeShadow = 1.0;\n      #if CC_DIR_SHADOW_PCF_TYPE == 3\n        realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 2\n        realtimeShadow =  CCGetDirLightShadowFactorSoft3X(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 1\n        realtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 0\n        realtimeShadow = CCGetDirLightShadowFactorHard(pos);\n      #endif\n      shadowNDCPosWithBias = pos;\n      return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n    }\n    #if CC_SUPPORT_CASCADED_SHADOW_MAP\n      bool CCGetCSMLevelWithTransition(out float ratio, vec3 clipPos) {\n        highp float layerThreshold = cc_csmViewDir0[0].w;\n        highp float maxRange = 1.0 - cc_csmSplitsInfo.x - layerThreshold;\n        highp float minRange = cc_csmSplitsInfo.x - layerThreshold;\n        if (clipPos.x <= minRange || clipPos.x >= maxRange ||\n            clipPos.y <= minRange || clipPos.y >= maxRange) {\n          if (clipPos.x >= layerThreshold && clipPos.x <= cc_csmSplitsInfo.x) {\n            ratio = (clipPos.x - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          if (clipPos.x >= maxRange && clipPos.x <= 1.0 - layerThreshold) {\n            ratio = (clipPos.x - maxRange) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          if (clipPos.y >= 0.0 && clipPos.y <= cc_csmSplitsInfo.x) {\n            ratio = min((clipPos.y - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold), 1.0);\n          }\n          if (clipPos.y >= maxRange && clipPos.y <= 1.0 - layerThreshold) {\n            ratio = (clipPos.y - maxRange) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          return true;\n        }\n        return false;\n      }\n      int CCGetCSMLevel(out bool hasNextTransition, out bool transitionArea, out float transitionRatio, out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos, int nextLayer)\n      {\n        int layer = -1;\n        highp float layerThreshold = cc_csmViewDir0[0].w;\n        for (int i = 0; i < 4; i++) {\n          vec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\n          vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;\n          if (clipPos.x >= (0.0 + layerThreshold) && clipPos.x <= (1.0 - layerThreshold) &&\n              clipPos.y >= (0.0 + layerThreshold) && clipPos.y <= (1.0 - layerThreshold) &&\n              clipPos.z >= 0.0 && clipPos.z <= 1.0) {\n            #if CC_CASCADED_LAYERS_TRANSITION\n              if (layer < 0 || (nextLayer >= 0 && i == nextLayer))\n            #else\n              if (layer < 0)\n            #endif\n            {\n              #if CC_CASCADED_LAYERS_TRANSITION\n                if (nextLayer < 0) {\n                  transitionArea = CCGetCSMLevelWithTransition(transitionRatio, clipPos);\n                }\n              #endif\n              csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\n              csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw;\n              shadowProjDepthInfo = cc_csmProjDepthInfo[i];\n              shadowProjInfo = cc_csmProjInfo[i];\n              shadowViewDir0 = cc_csmViewDir0[i].xyz;\n              shadowViewDir1 = cc_csmViewDir1[i].xyz;\n              shadowViewDir2 = cc_csmViewDir2[i].xyz;\n              layer = i;\n              #if CC_CASCADED_LAYERS_TRANSITION\n                hasNextTransition = true;\n              #endif\n            }\n          }\n        }\n        return layer;\n      }\n      int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos)\n      {\n        bool hasNextTransition = false;\n        bool transitionArea = false;\n        float transitionRatio = 0.0;\n        int nextLayer = -1;\n        return CCGetCSMLevel(hasNextTransition, transitionArea, transitionRatio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, nextLayer);\n      }\n      float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias)\n      {\n        bool hasNext = false;\n        bool transitionArea = false;\n        float ratio = 0.0;\n        csmPos = vec4(1.0);\n        vec4 shadowProjDepthInfo, shadowProjInfo;\n        vec3 shadowViewDir0, shadowViewDir1, shadowViewDir2;\n        int level = -1;\n        #if CC_CASCADED_LAYERS_TRANSITION\n          level = CCGetCSMLevel(hasNext, transitionArea, ratio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, -1);\n        #else\n          level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos);\n        #endif\n        if (level < 0) { return 1.0; }\n        vec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, shadowViewDir0, shadowViewDir1, shadowViewDir2, shadowProjInfo.xy);\n        pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);\n        csmNDCPosWithBias = pos;\n        float realtimeShadow = 1.0;\n        #if CC_DIR_SHADOW_PCF_TYPE == 3\n          realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 2\n          realtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 1\n          realtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 0\n          realtimeShadow = CCGetDirLightShadowFactorHard(pos);\n        #endif\n        #if CC_CASCADED_LAYERS_TRANSITION\n          vec4 nextCSMPos = vec4(1.0);\n          vec4 nextShadowProjDepthInfo, nextShadowProjInfo;\n          vec3 nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2;\n          float nextRealtimeShadow = 1.0;\n          CCGetCSMLevel(hasNext, transitionArea, ratio, nextCSMPos, nextShadowProjDepthInfo, nextShadowProjInfo, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, worldPos, level + 1);\n          if (hasNext && transitionArea) {\n            vec4 nexPos = ApplyShadowDepthBias_FaceNormal(nextCSMPos, N, shadowBias.y, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, nextShadowProjInfo.xy);\n            nexPos = ApplyShadowDepthBias_Orthographic(nexPos, shadowBias.x, nextShadowProjDepthInfo.x, nextShadowProjDepthInfo.y);\n            #if CC_DIR_SHADOW_PCF_TYPE == 3\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft5X(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 2\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft3X(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 1\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 0\n              nextRealtimeShadow = CCGetDirLightShadowFactorHard(nexPos);\n            #endif\n            return mix(mix(nextRealtimeShadow, realtimeShadow, ratio), 1.0, cc_shadowNFLSInfo.w);\n          }\n          return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n        #else\n          return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n        #endif\n      }\n    #else\n      int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) {\n        return -1;\n      }\n      float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias) {\n        csmPos = cc_matLightViewProj * vec4(worldPos, 1.0);\n        return CCShadowFactorBase(csmNDCPosWithBias, csmPos, N, shadowBias);\n      }\n    #endif\n    float CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias) {\n      vec4 shadowNDCPosWithBias;\n      return CCShadowFactorBase(shadowNDCPosWithBias, shadowPos, N, shadowBias);\n    }\n    float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) {\n      vec4 csmPos, csmNDCPosWithBias;\n      return CCCSMFactorBase(csmPos, csmNDCPosWithBias, worldPos, N, shadowBias);\n    }\n    float CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n    {\n      vec4 shadowNDCPosWithBias;\n      return CCSpotShadowFactorBase(shadowNDCPosWithBias, shadowPos, worldPos, shadowBias);\n    }\n  #endif\n  vec3 unpackRGBE (vec4 rgbe) {\n    return rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n  }\n  vec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n      return textureLod(tex, coord, lod);\n  }\n  vec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n      return textureLod(tex, coord, lod);\n  }\n  #if CC_USE_IBL\n    layout(set = 0, binding = 5) uniform samplerCube cc_environment;\n    #if CC_USE_DIFFUSEMAP\n      layout(set = 0, binding = 7) uniform samplerCube cc_diffuseMap;\n    #endif\n  #endif\n  #if CC_USE_REFLECTION_PROBE\n    layout(set = 2, binding = 15) uniform samplerCube cc_reflectionProbeCubemap;\n    layout(set = 2, binding = 16) uniform sampler2D cc_reflectionProbePlanarMap;\n  #endif\n  #if CC_USE_LIGHT_PROBE\n  #if CC_USE_LIGHT_PROBE\n    #if USE_INSTANCING\n      layout(location = 1) in mediump vec4 v_sh_linear_const_r;\n      layout(location = 2) in mediump vec4 v_sh_linear_const_g;\n      layout(location = 3) in mediump vec4 v_sh_linear_const_b;\n    #else\n      layout(set = 2, binding = 6) uniform CCSH {\n        vec4 cc_sh_linear_const_r;\n        vec4 cc_sh_linear_const_g;\n        vec4 cc_sh_linear_const_b;\n        vec4 cc_sh_quadratic_r;\n        vec4 cc_sh_quadratic_g;\n        vec4 cc_sh_quadratic_b;\n        vec4 cc_sh_quadratic_a;\n      };\n    #endif\n    #if CC_USE_LIGHT_PROBE\n    vec3 SHEvaluate(vec3 normal)\n    {\n    #if USE_INSTANCING\n        vec3 result;\n        vec4 normal4 = vec4(normal, 1.0);\n        result.r = dot(v_sh_linear_const_r, normal4);\n        result.g = dot(v_sh_linear_const_g, normal4);\n        result.b = dot(v_sh_linear_const_b, normal4);\n        return result;\n    #else\n        vec3 result;\n        vec4 normal4 = vec4(normal, 1.0);\n        result.r = dot(cc_sh_linear_const_r, normal4);\n        result.g = dot(cc_sh_linear_const_g, normal4);\n        result.b = dot(cc_sh_linear_const_b, normal4);\n        vec4 n14 = normal.xyzz * normal.yzzx;\n        float n5 = normal.x * normal.x - normal.y * normal.y;\n        result.r += dot(cc_sh_quadratic_r, n14);\n        result.g += dot(cc_sh_quadratic_g, n14);\n        result.b += dot(cc_sh_quadratic_b, n14);\n        result += (cc_sh_quadratic_a.rgb * n5);\n        return result;\n    #endif\n    }\n    #endif\n  #endif\n  #endif\n  float GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\n    vec3 NxH = cross(N, H);\n    float OneMinusNoHSqr = dot(NxH, NxH);\n    float a = roughness * roughness;\n    float n = NoH * a;\n    float p = a / (OneMinusNoHSqr + n * n);\n    return p * p;\n  }\n  float CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\n    return (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n  }\n  vec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\n    const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\n    const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\n    vec4 r = roughness * c0 + c1;\n    float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\n    vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\n    AB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\n    return specular * AB.x + AB.y;\n  }\n  #if USE_REFLECTION_DENOISE\n    vec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity, vec2 screenUV) {\n      #if CC_USE_IBL\n      \tfloat mip = roughness * (mipCount - 1.0);\n      \tfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\n      \tfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\n        #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE\n          vec4 biased = fragTextureLod(cc_reflectionProbeCubemap, R, mip + mipBias);\n       \t  vec4 filtered = texture(cc_reflectionProbeCubemap, R);\n        #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR\n          vec4 biased = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mip + mipBias);\n          vec4 filtered = texture(cc_reflectionProbePlanarMap, screenUV);\n        #else\n          vec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\n       \t  vec4 filtered = texture(cc_environment, R);\n        #endif\n        #if CC_USE_IBL == 2 || CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_NONE\n          biased.rgb = unpackRGBE(biased);\n        \tfiltered.rgb = unpackRGBE(filtered);\n        #else\n        \tbiased.rgb = SRGBToLinear(biased.rgb);\n        \tfiltered.rgb = SRGBToLinear(filtered.rgb);\n        #endif\n        return mix(biased.rgb, filtered.rgb, denoiseIntensity);\n      #else\n        return vec3(0.0, 0.0, 0.0);\n      #endif\n    }\n  #endif\n  struct StandardSurface {\n    vec4 albedo;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        vec3 position, position_fract_part;\n        #else\n        vec3 position;\n        #endif\n    vec3 normal;\n    vec3 emissive;\n    vec4 lightmap;\n    float lightmap_test;\n    float roughness;\n    float metallic;\n    float occlusion;\n    float specularIntensity;\n    #if CC_RECEIVE_SHADOW\n      vec2 shadowBias;\n    #endif\n  };\n  vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    vec3 L = normalize(-cc_mainLitDir.xyz);\n    float NL = max(dot(N, L), 0.0);\n    float shadow = 1.0;\n    #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == 2\n      if (NL > 0.0 && cc_mainLitDir.w > 0.0) {\n        if (cc_shadowLPNNInfo.w > 0.0) {\n          #if CC_DIR_LIGHT_SHADOW_TYPE == 2\n            shadow = CCCSMFactorBase(position, N, s.shadowBias);\n          #endif\n        } else {\n          #if CC_DIR_LIGHT_SHADOW_TYPE == 1\n            shadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n          #endif\n        }\n      }\n    #endif\n    vec3 finalColor = vec3(0.0);\n    #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD\n      vec3 lightmap = s.lightmap.rgb;\n      #if CC_USE_HDR\n          lightmap.rgb *= cc_exposure.w * cc_exposure.x;\n      #endif\n      #if CC_USE_LIGHTMAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION\n        shadow *= s.lightmap.a;\n        s.occlusion *= s.lightmap_test;\n        finalColor += diffuse * lightmap.rgb;\n      #else\n        finalColor += diffuse * lightmap.rgb * shadow;\n      #endif\n    #endif\n    #if CC_USE_LIGHTMAP != LIGHT_MAP_TYPE_ALL_IN_ONE\n      float NV = max(abs(dot(N, V)), 0.0);\n      specular = BRDFApprox(specular, s.roughness, NV);\n      vec3 H = normalize(L + V);\n      float NH = max(dot(N, H), 0.0);\n      vec3 lightingColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\n      vec3 diffuseContrib = diffuse / PI;\n      vec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\n      vec3 dirlightContrib = (diffuseContrib + specularContrib);\n      dirlightContrib *= shadow;\n      finalColor += lightingColor * dirlightContrib;\n    #endif\n    float fAmb = 0.5 - N.y * 0.5;\n    vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n    vec3 env = vec3(0.0);\n    #if CC_USE_IBL\n      #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE\n        vec4 diffuseMap = texture(cc_diffuseMap, N);\n        #if CC_USE_DIFFUSEMAP == 2\n          ambDiff = unpackRGBE(diffuseMap);\n        #else\n          ambDiff = SRGBToLinear(diffuseMap.rgb);\n        #endif\n      #endif\n      #if !CC_USE_REFLECTION_PROBE\n        vec3 R = normalize(reflect(-V, N));\n        vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w);\n        #if USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED\n          env = GetEnvReflectionWithMipFiltering(rotationDir, s.roughness, cc_ambientGround.w, 0.6, vec2(0.0));\n        #else\n          vec4 envmap = fragTextureLod(cc_environment, rotationDir, s.roughness * (cc_ambientGround.w - 1.0));\n          #if CC_USE_IBL == 2\n            env = unpackRGBE(envmap);\n          #else\n            env = SRGBToLinear(envmap.rgb);\n            #endif\n        #endif\n      #endif\n    #endif\n    #if CC_USE_REFLECTION_PROBE\n      vec4 probe = vec4(0.0);\n      vec3 R = normalize(reflect(-V, N));\n      #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE\n        probe = fragTextureLod(cc_reflectionProbeCubemap, R, s.roughness * (cc_ambientGround.w - 1.0));\n      #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR\n        vec2 screenUV = GetPlanarReflectScreenUV(s.position, cc_matViewProj, cc_cameraPos.w, V, R);\n        probe = texture(cc_reflectionProbePlanarMap, screenUV);\n      #endif\n      env = unpackRGBE(probe);\n    #endif\n    finalColor += env * cc_ambientSky.w * specular * s.occlusion;\n  #if CC_USE_LIGHT_PROBE\n    finalColor += SHEvaluate(N) * diffuse * s.occlusion;\n  #endif\n    finalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\n    finalColor += s.emissive;\n    return vec4(finalColor, s.albedo.a);\n  }\n  #if CC_PIPELINE_TYPE == 0\n    #define LIGHTS_PER_PASS 1\n  #else\n    #define LIGHTS_PER_PASS 10\n  #endif\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\n  layout(set = 2, binding = 1) uniform CCForwardLight {\n    highp vec4 cc_lightPos[LIGHTS_PER_PASS];\n    vec4 cc_lightColor[LIGHTS_PER_PASS];\n    vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\n    vec4 cc_lightDir[LIGHTS_PER_PASS];\n  };\n  #endif\n  float SmoothDistAtt (float distSqr, float invSqrAttRadius) {\n    float factor = distSqr * invSqrAttRadius;\n    float smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\n    return smoothFactor * smoothFactor;\n  }\n  float GetDistAtt (float distSqr, float invSqrAttRadius) {\n    float attenuation = 1.0 / max(distSqr, 0.01*0.01);\n    attenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\n    return attenuation;\n  }\n  float GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\n    float cd = dot(litDir, L);\n    float attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\n    return (attenuation * attenuation);\n  }\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\n  vec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\n    vec3 diffuseContrib = diffuse / PI;\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    float NV = max(abs(dot(N, V)), 0.0);\n    specular = BRDFApprox(specular, s.roughness, NV);\n    vec3 finalColor = vec3(0.0);\n    int numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\n    for (int i = 0; i < LIGHTS_PER_PASS; i++) {\n      if (i >= numLights) break;\n      vec3 SLU = cc_lightPos[i].xyz - position;\n      vec3 SL = normalize(SLU);\n      vec3 SH = normalize(SL + V);\n      float SNL = max(dot(N, SL), 0.0);\n      float SNH = max(dot(N, SH), 0.0);\n      float distSqr = dot(SLU, SLU);\n      float litRadius = cc_lightSizeRangeAngle[i].x;\n      float litRadiusSqr = litRadius * litRadius;\n      float illum = litRadiusSqr / max(litRadiusSqr, distSqr);\n      float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\n      attRadiusSqrInv *= attRadiusSqrInv;\n      float att = GetDistAtt(distSqr, attRadiusSqrInv);\n      vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\n      if (cc_lightPos[i].w > 0.0) {\n        float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\n        float cosOuter = cc_lightSizeRangeAngle[i].z;\n        float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\n        float litAngleOffset = -cosOuter * litAngleScale;\n        att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n      }\n      vec3 lightColor = cc_lightColor[i].rgb;\n      float shadow = 1.0;\n      #if CC_RECEIVE_SHADOW  && CC_SHADOW_TYPE == 2\n        if (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\n          shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n        }\n      #endif\n      lightColor *= shadow;\n      finalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n    }\n    return vec4(finalColor, 0.0);\n  }\n  #endif\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\n  layout(set = 1, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\n  layout(set = 1, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\n  layout(set = 1, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\n  struct CCLight\n  {\n    vec4 cc_lightPos;\n    vec4 cc_lightColor;\n    vec4 cc_lightSizeRangeAngle;\n    vec4 cc_lightDir;\n  };\n  struct Cluster\n  {\n    vec3 minBounds;\n    vec3 maxBounds;\n  };\n  struct LightGrid\n  {\n    uint offset;\n    uint ccLights;\n  };\n  CCLight getCCLight(uint i)\n  {\n    CCLight light;\n    light.cc_lightPos = b_ccLights[4u * i + 0u];\n    light.cc_lightColor = b_ccLights[4u * i + 1u];\n    light.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\n    light.cc_lightDir = b_ccLights[4u * i + 3u];\n    return light;\n  }\n  LightGrid getLightGrid(uint cluster)\n  {\n    uvec4 gridvec = b_clusterLightGrid[cluster];\n    LightGrid grid;\n    grid.offset = gridvec.x;\n    grid.ccLights = gridvec.y;\n    return grid;\n  }\n  uint getGridLightIndex(uint start, uint offset)\n  {\n    return b_clusterLightIndices[start + offset];\n  }\n  uint getClusterZIndex(vec4 worldPos)\n  {\n    float scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\n    float bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\n    float eyeDepth = -(cc_matView * worldPos).z;\n    uint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\n    return zIndex;\n  }\n  uint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n  {\n    uint zIndex = getClusterZIndex(worldPos);\n    float clusterSizeX = ceil(cc_viewPort.z / float(16));\n    float clusterSizeY = ceil(cc_viewPort.w / float(8));\n    uvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\n    uint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\n    return cluster;\n  }\n  vec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\n    vec3 diffuseContrib = diffuse / PI;\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    float NV = max(abs(dot(N, V)), 0.001);\n    specular = BRDFApprox(specular, s.roughness, NV);\n    vec3 finalColor = vec3(0.0);\n    uint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\n    LightGrid grid = getLightGrid(cluster);\n    uint numLights = grid.ccLights;\n    for (uint i = 0u; i < 100u; i++) {\n      if (i >= numLights) break;\n      uint lightIndex = getGridLightIndex(grid.offset, i);\n      CCLight light = getCCLight(lightIndex);\n      vec3 SLU = light.cc_lightPos.xyz - position;\n      vec3 SL = normalize(SLU);\n      vec3 SH = normalize(SL + V);\n      float SNL = max(dot(N, SL), 0.001);\n      float SNH = max(dot(N, SH), 0.0);\n      float distSqr = dot(SLU, SLU);\n      float litRadius = light.cc_lightSizeRangeAngle.x;\n      float litRadiusSqr = litRadius * litRadius;\n      float illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\n      float attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\n      attRadiusSqrInv *= attRadiusSqrInv;\n      float att = GetDistAtt(distSqr, attRadiusSqrInv);\n      vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\n      if (light.cc_lightPos.w > 0.0) {\n        float cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\n        float cosOuter = light.cc_lightSizeRangeAngle.z;\n        float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\n        float litAngleOffset = -cosOuter * litAngleScale;\n        att *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n      }\n      vec3 lightColor = light.cc_lightColor.rgb;\n      float shadow = 1.0;\n      #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == 2\n        if (light.cc_lightPos.w > 0.0) {\n          shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n        }\n      #endif\n      lightColor *= shadow;\n      finalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n    }\n    return vec4(finalColor, 0.0);\n  }\n  #endif\n  vec3 ACESToneMap (vec3 color) {\n    color = min(color, vec3(8.0));\n    const float A = 2.51;\n    const float B = 0.03;\n    const float C = 2.43;\n    const float D = 0.59;\n    const float E = 0.14;\n    return (color * (A * color + B)) / (color * (C * color + D) + E);\n  }\n  vec4 CCFragOutput (vec4 color) {\n    #if !CC_USE_RGBE_OUTPUT\n      #if CC_USE_HDR\n        color.rgb = ACESToneMap(color.rgb);\n      #endif\n      color.rgb = LinearToSRGB(color.rgb);\n    #endif\n    return color;\n  }\n  #if CC_USE_FOG != 4\n    float LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\n        vec4 wPos = pos;\n        float cam_dis = distance(cameraPos, wPos.xyz);\n        return clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n    }\n    float ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\n        vec4 wPos = pos;\n        float cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\n        float f = exp(-cam_dis * fogDensity);\n        return f;\n    }\n    float ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\n        vec4 wPos = pos;\n        float cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\n        float f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\n        return f;\n    }\n    float LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\n        vec4 wPos = pos;\n        vec3 camWorldProj = cameraPos.xyz;\n        camWorldProj.y = 0.;\n        vec3 worldPosProj = wPos.xyz;\n        worldPosProj.y = 0.;\n        float fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\n        float fDeltaY, fDensityIntegral;\n        if (cameraPos.y > fogTop) {\n            if (wPos.y < fogTop) {\n                fDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\n                fDensityIntegral = fDeltaY * fDeltaY * 0.5;\n            }\n            else {\n                fDeltaY = 0.;\n                fDensityIntegral = 0.;\n            }\n        }\n        else {\n            if (wPos.y < fogTop) {\n                float fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\n                float fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\n                fDeltaY = abs(fDeltaA - fDeltaB);\n                fDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n            }\n            else {\n                fDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\n                fDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n            }\n        }\n        float fDensity;\n        if (fDeltaY != 0.) {\n            fDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n        }\n        else {\n            fDensity = 0.;\n        }\n        float f = exp(-fDensity);\n        return f;\n    }\n  #endif\n  void CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n  {\n  #if CC_USE_FOG == 0\n  \tfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n  #elif CC_USE_FOG == 1\n  \tfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n  #elif CC_USE_FOG == 2\n  \tfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n  #elif CC_USE_FOG == 3\n  \tfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n  #else\n  \tfactor = 1.0;\n  #endif\n  }\n  void CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\n  \tcolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n  }\n  vec2 signNotZero(vec2 v) {\n    return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n  }\n  vec3 oct_to_float32x3(vec2 e) {\n    vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\n    if (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\n    return normalize(v);\n  }\n  layout(location = 0) in vec2 v_uv;\n  layout(set = 1, binding = 0) uniform sampler2D gbuffer_albedoMap;\n  layout(set = 1, binding = 1) uniform sampler2D gbuffer_normalMap;\n  layout(set = 1, binding = 2) uniform sampler2D gbuffer_emissiveMap;\n  layout(set = 1, binding = 3) uniform sampler2D depth_stencil;\n  layout(location = 0) out vec4 fragColor;\n  vec4 screen2WS(vec3 coord) {\n    vec3 ndc = vec3(\n      2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n      2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n      coord.z);\n    return GetWorldPosFromNDCPosRH(ndc, cc_matProj, cc_matViewProjInv);\n  }\n  void main () {\n    StandardSurface s;\n    vec4 albedoMap = texture(gbuffer_albedoMap,v_uv);\n    vec4 normalMap = texture(gbuffer_normalMap,v_uv);\n    vec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv);\n    float depth = texture(depth_stencil, v_uv).x;\n    s.albedo = albedoMap;\n    vec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\n    s.position = position;\n    s.roughness = normalMap.z;\n    s.normal = oct_to_float32x3(normalMap.xy);\n    s.specularIntensity = 0.5;\n    s.metallic = normalMap.w;\n    s.emissive = emissiveMap.xyz;\n    s.occlusion = emissiveMap.w;\n    float fogFactor;\n    CC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\n    vec4 shadowPos;\n    shadowPos = cc_matLightViewProj * vec4(position, 1);\n    vec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\n                 CCClusterShadingAdditive(s, shadowPos);\n#else\n                 CCStandardShadingAdditive(s, shadowPos);\n#endif\n    CC_APPLY_FOG_BASE(color, fogFactor);\n    color = CCFragOutput(color);\n    fragColor = color;\n  }"
      },
      "glsl3": {
        "vert": "\nprecision highp float;\n#define QUATER_PI         0.78539816340\n#define HALF_PI           1.57079632679\n#define PI                3.14159265359\n#define PI2               6.28318530718\n#define PI4               12.5663706144\n#define INV_QUATER_PI     1.27323954474\n#define INV_HALF_PI       0.63661977237\n#define INV_PI            0.31830988618\n#define INV_PI2           0.15915494309\n#define INV_PI4           0.07957747155\n#define EPSILON           1e-6\n#define EPSILON_LOWP      1e-4\n#define LOG2              1.442695\n#define EXP_VALUE         2.71828183f\n#define FP_MAX            65504.0\n#define FP_SCALE          0.0009765625\n#define FP_SCALE_INV      1024.0\n#define GRAY_VECTOR       vec3(0.299, 0.587, 0.114)\n#define LIGHT_MAP_TYPE_DISABLED 0\n#define LIGHT_MAP_TYPE_ALL_IN_ONE 1\n#define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2\n#define REFLECTION_PROBE_TYPE_NONE 0\n#define REFLECTION_PROBE_TYPE_CUBE 1\n#define REFLECTION_PROBE_TYPE_PLANAR 2\n#define LIGHT_TYPE_DIRECTIONAL 0.0\n#define LIGHT_TYPE_SPHERE 1.0\n#define LIGHT_TYPE_SPOT 2.0\n#define IS_DIRECTIONAL_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_DIRECTIONAL)) < EPSILON)\n#define IS_SPHERE_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPHERE)) < EPSILON)\n#define IS_SPOT_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPOT)) < EPSILON)\nstruct StandardVertInput {\n  highp vec4 position;\n  vec3 normal;\n  vec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\n    in vec4 a_joints;\n  in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n  #if CC_USE_BAKED_ANIMATION\n    in highp vec4 a_jointAnimInfo;\n  #endif\n  in vec4 a_matWorld0;\n  in vec4 a_matWorld1;\n  in vec4 a_matWorld2;\n  #if CC_USE_LIGHTMAP\n    in vec4 a_lightingMapUVParam;\n  #endif\n  #if CC_RECEIVE_SHADOW\n    in vec2 a_localShadowBias;\n  #endif\n  #if CC_USE_LIGHT_PROBE\n    in vec4 a_sh_linear_const_r;\n    in vec4 a_sh_linear_const_g;\n    in vec4 a_sh_linear_const_b;\n  #endif\n#endif\n#if CC_USE_MORPH\n    in float a_vertexId;\n#endif\nlayout(std140) uniform CCGlobal {\n  highp   vec4 cc_time;\n  mediump vec4 cc_screenSize;\n  mediump vec4 cc_nativeSize;\n  mediump vec4 cc_debug_view_mode;\n  mediump vec4 cc_debug_view_composite_pack_1;\n  mediump vec4 cc_debug_view_composite_pack_2;\n  mediump vec4 cc_debug_view_composite_pack_3;\n};\nlayout(std140) uniform CCCamera {\n  highp   mat4 cc_matView;\n  highp   mat4 cc_matViewInv;\n  highp   mat4 cc_matProj;\n  highp   mat4 cc_matProjInv;\n  highp   mat4 cc_matViewProj;\n  highp   mat4 cc_matViewProjInv;\n  highp   vec4 cc_cameraPos;\n  mediump vec4 cc_surfaceTransform;\n  mediump vec4 cc_screenScale;\n  mediump vec4 cc_exposure;\n  mediump vec4 cc_mainLitDir;\n  mediump vec4 cc_mainLitColor;\n  mediump vec4 cc_ambientSky;\n  mediump vec4 cc_ambientGround;\n  mediump vec4 cc_fogColor;\n  mediump vec4 cc_fogBase;\n  mediump vec4 cc_fogAdd;\n  mediump vec4 cc_nearFar;\n  mediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\n  vec4 position;\n    position = vec4(a_position, 1.0);\n  position.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\n  gl_Position = vec4(position.x, position.y, 1.0, 1.0);\n  v_uv = a_texCoord;\n}",
        "frag": "\n  precision highp float;\n  layout(std140) uniform CCGlobal {\n    highp   vec4 cc_time;\n    mediump vec4 cc_screenSize;\n    mediump vec4 cc_nativeSize;\n    mediump vec4 cc_debug_view_mode;\n    mediump vec4 cc_debug_view_composite_pack_1;\n    mediump vec4 cc_debug_view_composite_pack_2;\n    mediump vec4 cc_debug_view_composite_pack_3;\n  };\n  layout(std140) uniform CCCamera {\n    highp   mat4 cc_matView;\n    highp   mat4 cc_matViewInv;\n    highp   mat4 cc_matProj;\n    highp   mat4 cc_matProjInv;\n    highp   mat4 cc_matViewProj;\n    highp   mat4 cc_matViewProjInv;\n    highp   vec4 cc_cameraPos;\n    mediump vec4 cc_surfaceTransform;\n    mediump vec4 cc_screenScale;\n    mediump vec4 cc_exposure;\n    mediump vec4 cc_mainLitDir;\n    mediump vec4 cc_mainLitColor;\n    mediump vec4 cc_ambientSky;\n    mediump vec4 cc_ambientGround;\n    mediump vec4 cc_fogColor;\n    mediump vec4 cc_fogBase;\n    mediump vec4 cc_fogAdd;\n    mediump vec4 cc_nearFar;\n    mediump vec4 cc_viewPort;\n  };\n  #define QUATER_PI         0.78539816340\n  #define HALF_PI           1.57079632679\n  #define PI                3.14159265359\n  #define PI2               6.28318530718\n  #define PI4               12.5663706144\n  #define INV_QUATER_PI     1.27323954474\n  #define INV_HALF_PI       0.63661977237\n  #define INV_PI            0.31830988618\n  #define INV_PI2           0.15915494309\n  #define INV_PI4           0.07957747155\n  #define EPSILON           1e-6\n  #define EPSILON_LOWP      1e-4\n  #define LOG2              1.442695\n  #define EXP_VALUE         2.71828183f\n  #define FP_MAX            65504.0\n  #define FP_SCALE          0.0009765625\n  #define FP_SCALE_INV      1024.0\n  #define GRAY_VECTOR       vec3(0.299, 0.587, 0.114)\n      #define LIGHT_MAP_TYPE_DISABLED 0\n  #define LIGHT_MAP_TYPE_ALL_IN_ONE 1\n  #define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2\n  #define REFLECTION_PROBE_TYPE_NONE 0\n  #define REFLECTION_PROBE_TYPE_CUBE 1\n  #define REFLECTION_PROBE_TYPE_PLANAR 2\n  #define LIGHT_TYPE_DIRECTIONAL 0.0\n  #define LIGHT_TYPE_SPHERE 1.0\n  #define LIGHT_TYPE_SPOT 2.0\n  #define IS_DIRECTIONAL_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_DIRECTIONAL)) < EPSILON)\n  #define IS_SPHERE_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPHERE)) < EPSILON)\n  #define IS_SPOT_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPOT)) < EPSILON)\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_COLOR 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_NORMAL CC_SURFACES_DEBUG_VIEW_VERTEX_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_TANGENT CC_SURFACES_DEBUG_VIEW_VERTEX_NORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_WORLD_POS CC_SURFACES_DEBUG_VIEW_VERTEX_TANGENT + 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_MIRROR CC_SURFACES_DEBUG_VIEW_WORLD_POS + 1\n  #define CC_SURFACES_DEBUG_VIEW_FACE_SIDE CC_SURFACES_DEBUG_VIEW_VERTEX_MIRROR + 1\n  #define CC_SURFACES_DEBUG_VIEW_UV0 CC_SURFACES_DEBUG_VIEW_FACE_SIDE + 1\n  #define CC_SURFACES_DEBUG_VIEW_UV1 CC_SURFACES_DEBUG_VIEW_UV0 + 1\n  #define CC_SURFACES_DEBUG_VIEW_UVLIGHTMAP CC_SURFACES_DEBUG_VIEW_UV1 + 1\n  #define CC_SURFACES_DEBUG_VIEW_PROJ_DEPTH CC_SURFACES_DEBUG_VIEW_UVLIGHTMAP + 1\n  #define CC_SURFACES_DEBUG_VIEW_LINEAR_DEPTH CC_SURFACES_DEBUG_VIEW_PROJ_DEPTH + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_NORMAL CC_SURFACES_DEBUG_VIEW_LINEAR_DEPTH + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_TANGENT CC_SURFACES_DEBUG_VIEW_FRAGMENT_NORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_BINORMAL CC_SURFACES_DEBUG_VIEW_FRAGMENT_TANGENT + 1\n  #define CC_SURFACES_DEBUG_VIEW_BASE_COLOR CC_SURFACES_DEBUG_VIEW_FRAGMENT_BINORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIFFUSE_COLOR CC_SURFACES_DEBUG_VIEW_BASE_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_SPECULAR_COLOR CC_SURFACES_DEBUG_VIEW_DIFFUSE_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_TRANSPARENCY CC_SURFACES_DEBUG_VIEW_SPECULAR_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_METALLIC CC_SURFACES_DEBUG_VIEW_TRANSPARENCY + 1\n  #define CC_SURFACES_DEBUG_VIEW_ROUGHNESS CC_SURFACES_DEBUG_VIEW_METALLIC + 1\n  #define CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY CC_SURFACES_DEBUG_VIEW_ROUGHNESS + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_ALL CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE CC_SURFACES_DEBUG_VIEW_DIRECT_ALL + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_ALL CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR + 1\n  #define CC_SURFACES_DEBUG_VIEW_EMISSIVE CC_SURFACES_DEBUG_VIEW_ENV_ALL + 1\n  #define CC_SURFACES_DEBUG_VIEW_LIGHT_MAP CC_SURFACES_DEBUG_VIEW_EMISSIVE + 1\n  #define CC_SURFACES_DEBUG_VIEW_SHADOW CC_SURFACES_DEBUG_VIEW_LIGHT_MAP + 1\n  #define CC_SURFACES_DEBUG_VIEW_AO CC_SURFACES_DEBUG_VIEW_SHADOW + 1\n  #define CC_SURFACES_DEBUG_VIEW_FOG CC_SURFACES_DEBUG_VIEW_AO + 1\n  #define CC_SURFACES_DEBUG_VIEW_SINGLE 1\n  #define CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC 2\n  #define IS_DEBUG_VIEW_ENABLE_WITH_CAMERA (cc_surfaceTransform.y != 3.0)\n    #define IS_DEBUG_VIEW_LIGHTING_ENABLE_WITH_ALBEDO ((cc_debug_view_mode.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_MISC_ENABLE_CSM_LAYER_COLORATION ((cc_debug_view_mode.z > 0.0) && IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_DIFFUSE ((cc_debug_view_composite_pack_1.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_SPECULAR ((cc_debug_view_composite_pack_1.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_DIFFUSE ((cc_debug_view_composite_pack_1.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_SPECULAR ((cc_debug_view_composite_pack_1.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_EMISSIVE ((cc_debug_view_composite_pack_2.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_LIGHT_MAP ((cc_debug_view_composite_pack_2.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_SHADOW ((cc_debug_view_composite_pack_2.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_AO ((cc_debug_view_composite_pack_2.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_NORMAL_MAP ((cc_debug_view_composite_pack_3.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_FOG ((cc_debug_view_composite_pack_3.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING ((cc_debug_view_composite_pack_3.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION ((cc_debug_view_composite_pack_3.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  vec3 SRGBToLinear (vec3 gamma) {\n  #ifdef CC_USE_SURFACE_SHADER\n    #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC\n      if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION) {\n        return gamma;\n      }\n    #endif\n  #endif\n    return gamma * gamma;\n  }\n  vec3 LinearToSRGB(vec3 linear) {\n  #ifdef CC_USE_SURFACE_SHADER\n    #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC\n      if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION) {\n        return linear;\n      }\n    #endif\n  #endif\n    return sqrt(linear);\n  }\n  layout(std140) uniform CCShadow {\n    highp mat4 cc_matLightView;\n    highp mat4 cc_matLightViewProj;\n    highp vec4 cc_shadowInvProjDepthInfo;\n    highp vec4 cc_shadowProjDepthInfo;\n    highp vec4 cc_shadowProjInfo;\n    mediump vec4 cc_shadowNFLSInfo;\n    mediump vec4 cc_shadowWHPBInfo;\n    mediump vec4 cc_shadowLPNNInfo;\n    lowp vec4 cc_shadowColor;\n    mediump vec4 cc_planarNDInfo;\n  };\n  #if CC_SUPPORT_CASCADED_SHADOW_MAP\n    layout(std140) uniform CCCSM {\n      highp vec4 cc_csmViewDir0[4];\n      highp vec4 cc_csmViewDir1[4];\n      highp vec4 cc_csmViewDir2[4];\n      highp vec4 cc_csmAtlas[4];\n      highp mat4 cc_matCSMViewProj[4];\n      highp vec4 cc_csmProjDepthInfo[4];\n      highp vec4 cc_csmProjInfo[4];\n      highp vec4 cc_csmSplitsInfo;\n    };\n  #endif\n  vec2 GetPlanarReflectScreenUV(vec3 worldPos, mat4 matVirtualCameraViewProj, float flipNDCSign, vec3 viewDir, vec3 reflectDir)\n  {\n    vec4 clipPos = matVirtualCameraViewProj * vec4(worldPos, 1.0);\n    vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5;\n    screenUV = vec2(1.0 - screenUV.x, screenUV.y);\n    screenUV = flipNDCSign == 1.0 ? vec2(screenUV.x, 1.0 - screenUV.y) : screenUV;\n    return screenUV;\n  }\n  float GetCameraDepthRH(float depthHS, mat4 matProj)\n  {\n      return -matProj[3][2] / (depthHS + matProj[2][2]);\n  }\n  float GetCameraDepthRH(float depthHS, float matProj32, float matProj22)\n  {\n      return -matProj32 / (depthHS + matProj22);\n  }\n  vec4 GetWorldPosFromNDCPosRH(vec3 posHS, mat4 matProj, mat4 matViewProjInv)\n  {\n      float w = -GetCameraDepthRH(posHS.z, matProj);\n      return matViewProjInv * vec4(posHS * w, w);\n  }\n  float GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\n    float dist = length(viewPos);\n    return (dist - near) / (far - near);\n  }\n  vec3 RotationVecFromAxisY(vec3 v, float cosTheta, float sinTheta)\n  {\n      vec3 result;\n      result.x = dot(v, vec3(cosTheta, 0.0, -sinTheta));\n      result.y = v.y;\n      result.z = dot(v, vec3(sinTheta, 0.0,  cosTheta));\n      return result;\n  }\n  float CCGetLinearDepth(vec3 worldPos, float viewSpaceBias) {\n  \tvec4 viewPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\n    viewPos.z += viewSpaceBias;\n  \treturn GetLinearDepthFromViewSpace(viewPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n  }\n  float CCGetLinearDepth(vec3 worldPos) {\n  \treturn CCGetLinearDepth(worldPos, 0.0);\n  }\n  #if CC_RECEIVE_SHADOW\n    uniform highp sampler2D cc_shadowMap;\n    uniform highp sampler2D cc_spotShadowMap;\n        highp float unpackHighpData (float mainPart, float modPart) {\n          highp float data = mainPart;\n          return data + modPart;\n        }\n        highp float unpackHighpData (float mainPart, float modPart, const float modValue) {\n          highp float data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\n          highp vec2 data = mainPart;\n          return data + modPart;\n        }\n        highp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\n          highp vec2 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\n          highp vec3 data = mainPart;\n          return data + modPart;\n        }\n        highp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\n          highp vec3 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\n          highp vec4 data = mainPart;\n          return data + modPart;\n        }\n        highp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\n          highp vec4 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n    float NativePCFShadowFactorHard (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      #if CC_SHADOWMAP_FORMAT == 1\n        return step(shadowNDCPos.z, dot(texture(shadowMap, shadowNDCPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        return step(shadowNDCPos.z, texture(shadowMap, shadowNDCPos.xy).x);\n      #endif\n    }\n    float NativePCFShadowFactorSoft (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      vec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap;\n      float block0, block1, block2, block3;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\n        block1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)).x);\n        block2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)).x);\n        block3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)).x);\n      #endif\n      float coefX   = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\n      float resultX = mix(block0, block1, coefX);\n      float resultY = mix(block2, block3, coefX);\n      float coefY   = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\n      return mix(resultX, resultY, coefY);\n    }\n    float NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      float shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x;\n      float shadowNDCPos_offset_R = shadowNDCPos.x + oneTap.x;\n      float shadowNDCPos_offset_U = shadowNDCPos.y - oneTap.y;\n      float shadowNDCPos_offset_D = shadowNDCPos.y + oneTap.y;\n      float block0, block1, block2, block3, block4, block5, block6, block7, block8;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block4 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block5 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block6 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block7 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block8 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)).x);\n        block1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)).x);\n        block2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)).x);\n        block3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)).x);\n        block4 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\n        block5 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)).x);\n        block6 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)).x);\n        block7 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)).x);\n        block8 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)).x);\n      #endif\n      float coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\n      float coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\n      float shadow = 0.0;\n      float resultX = mix(block0, block1, coefX);\n      float resultY = mix(block3, block4, coefX);\n      shadow += mix(resultX , resultY, coefY);\n      resultX = mix(block1, block2, coefX);\n      resultY = mix(block4, block5, coefX);\n      shadow += mix(resultX , resultY, coefY);\n      resultX = mix(block3, block4, coefX);\n      resultY = mix(block6, block7, coefX);\n      shadow += mix(resultX, resultY, coefY);\n      resultX = mix(block4, block5, coefX);\n      resultY = mix(block7, block8, coefX);\n      shadow += mix(resultX, resultY, coefY);\n      return shadow * 0.25;\n    }\n    float NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      vec2 twoTap = oneTap * 2.0;\n      vec2 offset1 = shadowNDCPos.xy + vec2(-twoTap.x, -twoTap.y);\n      vec2 offset2 = shadowNDCPos.xy + vec2(-oneTap.x, -twoTap.y);\n      vec2 offset3 = shadowNDCPos.xy + vec2(0.0, -twoTap.y);\n      vec2 offset4 = shadowNDCPos.xy + vec2(oneTap.x, -twoTap.y);\n      vec2 offset5 = shadowNDCPos.xy + vec2(twoTap.x, -twoTap.y);\n      vec2 offset6 = shadowNDCPos.xy + vec2(-twoTap.x, -oneTap.y);\n      vec2 offset7 = shadowNDCPos.xy + vec2(-oneTap.x, -oneTap.y);\n      vec2 offset8 = shadowNDCPos.xy + vec2(0.0, -oneTap.y);\n      vec2 offset9 = shadowNDCPos.xy + vec2(oneTap.x, -oneTap.y);\n      vec2 offset10 = shadowNDCPos.xy + vec2(twoTap.x, -oneTap.y);\n      vec2 offset11 = shadowNDCPos.xy + vec2(-twoTap.x, 0.0);\n      vec2 offset12 = shadowNDCPos.xy + vec2(-oneTap.x, 0.0);\n      vec2 offset13 = shadowNDCPos.xy + vec2(0.0, 0.0);\n      vec2 offset14 = shadowNDCPos.xy + vec2(oneTap.x, 0.0);\n      vec2 offset15 = shadowNDCPos.xy + vec2(twoTap.x, 0.0);\n      vec2 offset16 = shadowNDCPos.xy + vec2(-twoTap.x, oneTap.y);\n      vec2 offset17 = shadowNDCPos.xy + vec2(-oneTap.x, oneTap.y);\n      vec2 offset18 = shadowNDCPos.xy + vec2(0.0, oneTap.y);\n      vec2 offset19 = shadowNDCPos.xy + vec2(oneTap.x, oneTap.y);\n      vec2 offset20 = shadowNDCPos.xy + vec2(twoTap.x, oneTap.y);\n      vec2 offset21 = shadowNDCPos.xy + vec2(-twoTap.x, twoTap.y);\n      vec2 offset22 = shadowNDCPos.xy + vec2(-oneTap.x, twoTap.y);\n      vec2 offset23 = shadowNDCPos.xy + vec2(0.0, twoTap.y);\n      vec2 offset24 = shadowNDCPos.xy + vec2(oneTap.x, twoTap.y);\n      vec2 offset25 = shadowNDCPos.xy + vec2(twoTap.x, twoTap.y);\n      float block1, block2, block3, block4, block5, block6, block7, block8, block9, block10, block11, block12, block13, block14, block15, block16, block17, block18, block19, block20, block21, block22, block23, block24, block25;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block1 = step(shadowNDCPos.z, dot(texture(shadowMap, offset1), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture(shadowMap, offset2), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture(shadowMap, offset3), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block4 = step(shadowNDCPos.z, dot(texture(shadowMap, offset4), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block5 = step(shadowNDCPos.z, dot(texture(shadowMap, offset5), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block6 = step(shadowNDCPos.z, dot(texture(shadowMap, offset6), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block7 = step(shadowNDCPos.z, dot(texture(shadowMap, offset7), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block8 = step(shadowNDCPos.z, dot(texture(shadowMap, offset8), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block9 = step(shadowNDCPos.z, dot(texture(shadowMap, offset9), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block10 = step(shadowNDCPos.z, dot(texture(shadowMap, offset10), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block11 = step(shadowNDCPos.z, dot(texture(shadowMap, offset11), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block12 = step(shadowNDCPos.z, dot(texture(shadowMap, offset12), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block13 = step(shadowNDCPos.z, dot(texture(shadowMap, offset13), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block14 = step(shadowNDCPos.z, dot(texture(shadowMap, offset14), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block15 = step(shadowNDCPos.z, dot(texture(shadowMap, offset15), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block16 = step(shadowNDCPos.z, dot(texture(shadowMap, offset16), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block17 = step(shadowNDCPos.z, dot(texture(shadowMap, offset17), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block18 = step(shadowNDCPos.z, dot(texture(shadowMap, offset18), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block19 = step(shadowNDCPos.z, dot(texture(shadowMap, offset19), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block20 = step(shadowNDCPos.z, dot(texture(shadowMap, offset20), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block21 = step(shadowNDCPos.z, dot(texture(shadowMap, offset21), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block22 = step(shadowNDCPos.z, dot(texture(shadowMap, offset22), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block23 = step(shadowNDCPos.z, dot(texture(shadowMap, offset23), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block24 = step(shadowNDCPos.z, dot(texture(shadowMap, offset24), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block25 = step(shadowNDCPos.z, dot(texture(shadowMap, offset25), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block1 = step(shadowNDCPos.z, texture(shadowMap, offset1).x);\n        block2 = step(shadowNDCPos.z, texture(shadowMap, offset2).x);\n        block3 = step(shadowNDCPos.z, texture(shadowMap, offset3).x);\n        block4 = step(shadowNDCPos.z, texture(shadowMap, offset4).x);\n        block5 = step(shadowNDCPos.z, texture(shadowMap, offset5).x);\n        block6 = step(shadowNDCPos.z, texture(shadowMap, offset6).x);\n        block7 = step(shadowNDCPos.z, texture(shadowMap, offset7).x);\n        block8 = step(shadowNDCPos.z, texture(shadowMap, offset8).x);\n        block9 = step(shadowNDCPos.z, texture(shadowMap, offset9).x);\n        block10 = step(shadowNDCPos.z, texture(shadowMap, offset10).x);\n        block11 = step(shadowNDCPos.z, texture(shadowMap, offset11).x);\n        block12 = step(shadowNDCPos.z, texture(shadowMap, offset12).x);\n        block13 = step(shadowNDCPos.z, texture(shadowMap, offset13).x);\n        block14 = step(shadowNDCPos.z, texture(shadowMap, offset14).x);\n        block15 = step(shadowNDCPos.z, texture(shadowMap, offset15).x);\n        block16 = step(shadowNDCPos.z, texture(shadowMap, offset16).x);\n        block17 = step(shadowNDCPos.z, texture(shadowMap, offset17).x);\n        block18 = step(shadowNDCPos.z, texture(shadowMap, offset18).x);\n        block19 = step(shadowNDCPos.z, texture(shadowMap, offset19).x);\n        block20 = step(shadowNDCPos.z, texture(shadowMap, offset20).x);\n        block21 = step(shadowNDCPos.z, texture(shadowMap, offset21).x);\n        block22 = step(shadowNDCPos.z, texture(shadowMap, offset22).x);\n        block23 = step(shadowNDCPos.z, texture(shadowMap, offset23).x);\n        block24 = step(shadowNDCPos.z, texture(shadowMap, offset24).x);\n        block25 = step(shadowNDCPos.z, texture(shadowMap, offset25).x);\n      #endif\n      vec2 coef = fract(shadowNDCPos.xy * shadowMapResolution);\n      vec2 v1X1 = mix(vec2(block1, block6), vec2(block2, block7), coef.xx);\n      vec2 v1X2 = mix(vec2(block2, block7), vec2(block3, block8), coef.xx);\n      vec2 v1X3 = mix(vec2(block3, block8), vec2(block4, block9), coef.xx);\n      vec2 v1X4 = mix(vec2(block4, block9), vec2(block5, block10), coef.xx);\n      float v1 = mix(v1X1.x, v1X1.y, coef.y) + mix(v1X2.x, v1X2.y, coef.y) + mix(v1X3.x, v1X3.y, coef.y) + mix(v1X4.x, v1X4.y, coef.y);\n      vec2 v2X1 = mix(vec2(block6, block11), vec2(block7, block12), coef.xx);\n      vec2 v2X2 = mix(vec2(block7, block12), vec2(block8, block13), coef.xx);\n      vec2 v2X3 = mix(vec2(block8, block13), vec2(block9, block14), coef.xx);\n      vec2 v2X4 = mix(vec2(block9, block14), vec2(block10, block15), coef.xx);\n      float v2 = mix(v2X1.x, v2X1.y, coef.y) + mix(v2X2.x, v2X2.y, coef.y) + mix(v2X3.x, v2X3.y, coef.y) + mix(v2X4.x, v2X4.y, coef.y);\n      vec2 v3X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\n      vec2 v3X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\n      vec2 v3X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\n      vec2 v3X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\n      float v3 = mix(v3X1.x, v3X1.y, coef.y) + mix(v3X2.x, v3X2.y, coef.y) + mix(v3X3.x, v3X3.y, coef.y) + mix(v3X4.x, v3X4.y, coef.y);\n      vec2 v4X1 = mix(vec2(block16, block21), vec2(block17, block22), coef.xx);\n      vec2 v4X2 = mix(vec2(block17, block22), vec2(block18, block23), coef.xx);\n      vec2 v4X3 = mix(vec2(block18, block23), vec2(block19, block24), coef.xx);\n      vec2 v4X4 = mix(vec2(block19, block24), vec2(block20, block25), coef.xx);\n      float v4 = mix(v4X1.x, v4X1.y, coef.y) + mix(v4X2.x, v4X2.y, coef.y) + mix(v4X3.x, v4X3.y, coef.y) + mix(v4X4.x, v4X4.y, coef.y);\n      float fAvg = (v1 + v2 + v3 + v4) * 0.0625;\n      return fAvg;\n    }\n    bool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)\n    {\n    \tshadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;\n    \tif (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||\n    \t\tshadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||\n    \t\tshadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {\n    \t\treturn false;\n    \t}\n    \tshadowNDCPos.xy = cc_cameraPos.w == 1.0 ? vec2(shadowNDCPos.xy.x, 1.0 - shadowNDCPos.xy.y) : shadowNDCPos.xy;\n    \treturn true;\n    }\n    vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, vec3 matViewDir0, vec3 matViewDir1, vec3 matViewDir2, vec2 projScaleXY)\n    {\n      vec4 newShadowPos = shadowPos;\n      if (normalBias > EPSILON_LOWP)\n      {\n        vec3 viewNormal = vec3(dot(matViewDir0, worldNormal), dot(matViewDir1, worldNormal), dot(matViewDir2, worldNormal));\n        if (viewNormal.z < 0.1)\n          newShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n      }\n      return newShadowPos;\n    }\n    vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)\n    {\n    \tvec4 newShadowPos = shadowPos;\n    \tif (normalBias > EPSILON_LOWP)\n    \t{\n    \t\tvec4 viewNormal = matLightView * vec4(worldNormal, 0.0);\n    \t\tif (viewNormal.z < 0.1)\n    \t\t\tnewShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n    \t}\n    \treturn newShadowPos;\n    }\n    float GetViewSpaceDepthFromNDCDepth_Orthgraphic(float NDCDepth, float projScaleZ, float projBiasZ)\n    {\n    \treturn (NDCDepth - projBiasZ) / projScaleZ;\n    }\n    float GetViewSpaceDepthFromNDCDepth_Perspective(float NDCDepth, float homogenousDividW, float invProjScaleZ, float invProjBiasZ)\n    {\n    \treturn NDCDepth * invProjScaleZ + homogenousDividW * invProjBiasZ;\n    }\n    vec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n    {\n    \tvec3 viewSpacePos;\n    \tviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\n    \tviewSpacePos.z = GetViewSpaceDepthFromNDCDepth_Perspective(shadowPos.z, shadowPos.w, cc_shadowInvProjDepthInfo.x, cc_shadowInvProjDepthInfo.y);\n    \tviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\n    \tvec4 clipSpacePos;\n    \tclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\n    \tclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\n    \t#if CC_SHADOWMAP_USE_LINEAR_DEPTH\n    \t\tclipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n    \t\tclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n    \t#endif\n    \treturn clipSpacePos;\n    }\n    vec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)\n    {\n    \tfloat coeffA = projScaleZ;\n    \tfloat coeffB = projBiasZ;\n    \tfloat viewSpacePos_z = GetViewSpaceDepthFromNDCDepth_Orthgraphic(shadowPos.z, projScaleZ, projBiasZ);\n    \tviewSpacePos_z += viewspaceDepthBias;\n    \tvec4 result = shadowPos;\n    \tresult.z = viewSpacePos_z * coeffA + coeffB;\n    \treturn result;\n    }\n    vec4 ApplyShadowDepthBias_PerspectiveLinearDepth(vec4 shadowPos, float viewspaceDepthBias, vec3 worldPos)\n    {\n      shadowPos.z = CCGetLinearDepth(worldPos, viewspaceDepthBias) * 2.0 - 1.0;\n      shadowPos.z *= shadowPos.w;\n      return shadowPos;\n    }\n    float CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorHard(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCSpotShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n    {\n      float pcf = cc_shadowWHPBInfo.z;\n      vec4 pos = vec4(1.0);\n      #if CC_SHADOWMAP_USE_LINEAR_DEPTH\n        pos = ApplyShadowDepthBias_PerspectiveLinearDepth(shadowPos, shadowBias.x, worldPos);\n      #else\n        pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);\n      #endif\n      float realtimeShadow = 1.0;\n      if (pcf > 2.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft5X(pos, worldPos);\n      }else if (pcf > 1.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft3X(pos, worldPos);\n      }else if (pcf > 0.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft(pos, worldPos);\n      }else {\n        realtimeShadow = CCGetSpotLightShadowFactorHard(pos, worldPos);\n      }\n      shadowNDCPosWithBias = pos;\n      return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n    }\n    float CCShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 N, vec2 shadowBias)\n    {\n      vec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);\n      pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);\n      float realtimeShadow = 1.0;\n      #if CC_DIR_SHADOW_PCF_TYPE == 3\n        realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 2\n        realtimeShadow =  CCGetDirLightShadowFactorSoft3X(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 1\n        realtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 0\n        realtimeShadow = CCGetDirLightShadowFactorHard(pos);\n      #endif\n      shadowNDCPosWithBias = pos;\n      return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n    }\n    #if CC_SUPPORT_CASCADED_SHADOW_MAP\n      bool CCGetCSMLevelWithTransition(out float ratio, vec3 clipPos) {\n        highp float layerThreshold = cc_csmViewDir0[0].w;\n        highp float maxRange = 1.0 - cc_csmSplitsInfo.x - layerThreshold;\n        highp float minRange = cc_csmSplitsInfo.x - layerThreshold;\n        if (clipPos.x <= minRange || clipPos.x >= maxRange ||\n            clipPos.y <= minRange || clipPos.y >= maxRange) {\n          if (clipPos.x >= layerThreshold && clipPos.x <= cc_csmSplitsInfo.x) {\n            ratio = (clipPos.x - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          if (clipPos.x >= maxRange && clipPos.x <= 1.0 - layerThreshold) {\n            ratio = (clipPos.x - maxRange) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          if (clipPos.y >= 0.0 && clipPos.y <= cc_csmSplitsInfo.x) {\n            ratio = min((clipPos.y - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold), 1.0);\n          }\n          if (clipPos.y >= maxRange && clipPos.y <= 1.0 - layerThreshold) {\n            ratio = (clipPos.y - maxRange) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          return true;\n        }\n        return false;\n      }\n      int CCGetCSMLevel(out bool hasNextTransition, out bool transitionArea, out float transitionRatio, out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos, int nextLayer)\n      {\n        int layer = -1;\n        highp float layerThreshold = cc_csmViewDir0[0].w;\n        for (int i = 0; i < 4; i++) {\n          vec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\n          vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;\n          if (clipPos.x >= (0.0 + layerThreshold) && clipPos.x <= (1.0 - layerThreshold) &&\n              clipPos.y >= (0.0 + layerThreshold) && clipPos.y <= (1.0 - layerThreshold) &&\n              clipPos.z >= 0.0 && clipPos.z <= 1.0) {\n            #if CC_CASCADED_LAYERS_TRANSITION\n              if (layer < 0 || (nextLayer >= 0 && i == nextLayer))\n            #else\n              if (layer < 0)\n            #endif\n            {\n              #if CC_CASCADED_LAYERS_TRANSITION\n                if (nextLayer < 0) {\n                  transitionArea = CCGetCSMLevelWithTransition(transitionRatio, clipPos);\n                }\n              #endif\n              csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\n              csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw;\n              shadowProjDepthInfo = cc_csmProjDepthInfo[i];\n              shadowProjInfo = cc_csmProjInfo[i];\n              shadowViewDir0 = cc_csmViewDir0[i].xyz;\n              shadowViewDir1 = cc_csmViewDir1[i].xyz;\n              shadowViewDir2 = cc_csmViewDir2[i].xyz;\n              layer = i;\n              #if CC_CASCADED_LAYERS_TRANSITION\n                hasNextTransition = true;\n              #endif\n            }\n          }\n        }\n        return layer;\n      }\n      int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos)\n      {\n        bool hasNextTransition = false;\n        bool transitionArea = false;\n        float transitionRatio = 0.0;\n        int nextLayer = -1;\n        return CCGetCSMLevel(hasNextTransition, transitionArea, transitionRatio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, nextLayer);\n      }\n      float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias)\n      {\n        bool hasNext = false;\n        bool transitionArea = false;\n        float ratio = 0.0;\n        csmPos = vec4(1.0);\n        vec4 shadowProjDepthInfo, shadowProjInfo;\n        vec3 shadowViewDir0, shadowViewDir1, shadowViewDir2;\n        int level = -1;\n        #if CC_CASCADED_LAYERS_TRANSITION\n          level = CCGetCSMLevel(hasNext, transitionArea, ratio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, -1);\n        #else\n          level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos);\n        #endif\n        if (level < 0) { return 1.0; }\n        vec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, shadowViewDir0, shadowViewDir1, shadowViewDir2, shadowProjInfo.xy);\n        pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);\n        csmNDCPosWithBias = pos;\n        float realtimeShadow = 1.0;\n        #if CC_DIR_SHADOW_PCF_TYPE == 3\n          realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 2\n          realtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 1\n          realtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 0\n          realtimeShadow = CCGetDirLightShadowFactorHard(pos);\n        #endif\n        #if CC_CASCADED_LAYERS_TRANSITION\n          vec4 nextCSMPos = vec4(1.0);\n          vec4 nextShadowProjDepthInfo, nextShadowProjInfo;\n          vec3 nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2;\n          float nextRealtimeShadow = 1.0;\n          CCGetCSMLevel(hasNext, transitionArea, ratio, nextCSMPos, nextShadowProjDepthInfo, nextShadowProjInfo, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, worldPos, level + 1);\n          if (hasNext && transitionArea) {\n            vec4 nexPos = ApplyShadowDepthBias_FaceNormal(nextCSMPos, N, shadowBias.y, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, nextShadowProjInfo.xy);\n            nexPos = ApplyShadowDepthBias_Orthographic(nexPos, shadowBias.x, nextShadowProjDepthInfo.x, nextShadowProjDepthInfo.y);\n            #if CC_DIR_SHADOW_PCF_TYPE == 3\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft5X(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 2\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft3X(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 1\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 0\n              nextRealtimeShadow = CCGetDirLightShadowFactorHard(nexPos);\n            #endif\n            return mix(mix(nextRealtimeShadow, realtimeShadow, ratio), 1.0, cc_shadowNFLSInfo.w);\n          }\n          return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n        #else\n          return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n        #endif\n      }\n    #else\n      int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) {\n        return -1;\n      }\n      float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias) {\n        csmPos = cc_matLightViewProj * vec4(worldPos, 1.0);\n        return CCShadowFactorBase(csmNDCPosWithBias, csmPos, N, shadowBias);\n      }\n    #endif\n    float CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias) {\n      vec4 shadowNDCPosWithBias;\n      return CCShadowFactorBase(shadowNDCPosWithBias, shadowPos, N, shadowBias);\n    }\n    float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) {\n      vec4 csmPos, csmNDCPosWithBias;\n      return CCCSMFactorBase(csmPos, csmNDCPosWithBias, worldPos, N, shadowBias);\n    }\n    float CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n    {\n      vec4 shadowNDCPosWithBias;\n      return CCSpotShadowFactorBase(shadowNDCPosWithBias, shadowPos, worldPos, shadowBias);\n    }\n  #endif\n  vec3 unpackRGBE (vec4 rgbe) {\n    return rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n  }\n  vec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n      return textureLod(tex, coord, lod);\n  }\n  vec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n      return textureLod(tex, coord, lod);\n  }\n  #if CC_USE_IBL\n    uniform samplerCube cc_environment;\n    #if CC_USE_DIFFUSEMAP\n      uniform samplerCube cc_diffuseMap;\n    #endif\n  #endif\n  #if CC_USE_REFLECTION_PROBE\n    uniform samplerCube cc_reflectionProbeCubemap;\n    uniform sampler2D cc_reflectionProbePlanarMap;\n  #endif\n  #if CC_USE_LIGHT_PROBE\n  #if CC_USE_LIGHT_PROBE\n    #if USE_INSTANCING\n      in mediump vec4 v_sh_linear_const_r;\n      in mediump vec4 v_sh_linear_const_g;\n      in mediump vec4 v_sh_linear_const_b;\n    #else\n      layout(std140) uniform CCSH {\n        vec4 cc_sh_linear_const_r;\n        vec4 cc_sh_linear_const_g;\n        vec4 cc_sh_linear_const_b;\n        vec4 cc_sh_quadratic_r;\n        vec4 cc_sh_quadratic_g;\n        vec4 cc_sh_quadratic_b;\n        vec4 cc_sh_quadratic_a;\n      };\n    #endif\n    #if CC_USE_LIGHT_PROBE\n    vec3 SHEvaluate(vec3 normal)\n    {\n    #if USE_INSTANCING\n        vec3 result;\n        vec4 normal4 = vec4(normal, 1.0);\n        result.r = dot(v_sh_linear_const_r, normal4);\n        result.g = dot(v_sh_linear_const_g, normal4);\n        result.b = dot(v_sh_linear_const_b, normal4);\n        return result;\n    #else\n        vec3 result;\n        vec4 normal4 = vec4(normal, 1.0);\n        result.r = dot(cc_sh_linear_const_r, normal4);\n        result.g = dot(cc_sh_linear_const_g, normal4);\n        result.b = dot(cc_sh_linear_const_b, normal4);\n        vec4 n14 = normal.xyzz * normal.yzzx;\n        float n5 = normal.x * normal.x - normal.y * normal.y;\n        result.r += dot(cc_sh_quadratic_r, n14);\n        result.g += dot(cc_sh_quadratic_g, n14);\n        result.b += dot(cc_sh_quadratic_b, n14);\n        result += (cc_sh_quadratic_a.rgb * n5);\n        return result;\n    #endif\n    }\n    #endif\n  #endif\n  #endif\n  float GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\n    vec3 NxH = cross(N, H);\n    float OneMinusNoHSqr = dot(NxH, NxH);\n    float a = roughness * roughness;\n    float n = NoH * a;\n    float p = a / (OneMinusNoHSqr + n * n);\n    return p * p;\n  }\n  float CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\n    return (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n  }\n  vec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\n    const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\n    const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\n    vec4 r = roughness * c0 + c1;\n    float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\n    vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\n    AB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\n    return specular * AB.x + AB.y;\n  }\n  #if USE_REFLECTION_DENOISE\n    vec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity, vec2 screenUV) {\n      #if CC_USE_IBL\n      \tfloat mip = roughness * (mipCount - 1.0);\n      \tfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\n      \tfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\n        #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE\n          vec4 biased = fragTextureLod(cc_reflectionProbeCubemap, R, mip + mipBias);\n       \t  vec4 filtered = texture(cc_reflectionProbeCubemap, R);\n        #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR\n          vec4 biased = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mip + mipBias);\n          vec4 filtered = texture(cc_reflectionProbePlanarMap, screenUV);\n        #else\n          vec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\n       \t  vec4 filtered = texture(cc_environment, R);\n        #endif\n        #if CC_USE_IBL == 2 || CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_NONE\n          biased.rgb = unpackRGBE(biased);\n        \tfiltered.rgb = unpackRGBE(filtered);\n        #else\n        \tbiased.rgb = SRGBToLinear(biased.rgb);\n        \tfiltered.rgb = SRGBToLinear(filtered.rgb);\n        #endif\n        return mix(biased.rgb, filtered.rgb, denoiseIntensity);\n      #else\n        return vec3(0.0, 0.0, 0.0);\n      #endif\n    }\n  #endif\n  struct StandardSurface {\n    vec4 albedo;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        vec3 position, position_fract_part;\n        #else\n        vec3 position;\n        #endif\n    vec3 normal;\n    vec3 emissive;\n    vec4 lightmap;\n    float lightmap_test;\n    float roughness;\n    float metallic;\n    float occlusion;\n    float specularIntensity;\n    #if CC_RECEIVE_SHADOW\n      vec2 shadowBias;\n    #endif\n  };\n  vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    vec3 L = normalize(-cc_mainLitDir.xyz);\n    float NL = max(dot(N, L), 0.0);\n    float shadow = 1.0;\n    #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == 2\n      if (NL > 0.0 && cc_mainLitDir.w > 0.0) {\n        if (cc_shadowLPNNInfo.w > 0.0) {\n          #if CC_DIR_LIGHT_SHADOW_TYPE == 2\n            shadow = CCCSMFactorBase(position, N, s.shadowBias);\n          #endif\n        } else {\n          #if CC_DIR_LIGHT_SHADOW_TYPE == 1\n            shadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n          #endif\n        }\n      }\n    #endif\n    vec3 finalColor = vec3(0.0);\n    #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD\n      vec3 lightmap = s.lightmap.rgb;\n      #if CC_USE_HDR\n          lightmap.rgb *= cc_exposure.w * cc_exposure.x;\n      #endif\n      #if CC_USE_LIGHTMAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION\n        shadow *= s.lightmap.a;\n        s.occlusion *= s.lightmap_test;\n        finalColor += diffuse * lightmap.rgb;\n      #else\n        finalColor += diffuse * lightmap.rgb * shadow;\n      #endif\n    #endif\n    #if CC_USE_LIGHTMAP != LIGHT_MAP_TYPE_ALL_IN_ONE\n      float NV = max(abs(dot(N, V)), 0.0);\n      specular = BRDFApprox(specular, s.roughness, NV);\n      vec3 H = normalize(L + V);\n      float NH = max(dot(N, H), 0.0);\n      vec3 lightingColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\n      vec3 diffuseContrib = diffuse / PI;\n      vec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\n      vec3 dirlightContrib = (diffuseContrib + specularContrib);\n      dirlightContrib *= shadow;\n      finalColor += lightingColor * dirlightContrib;\n    #endif\n    float fAmb = 0.5 - N.y * 0.5;\n    vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n    vec3 env = vec3(0.0);\n    #if CC_USE_IBL\n      #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE\n        vec4 diffuseMap = texture(cc_diffuseMap, N);\n        #if CC_USE_DIFFUSEMAP == 2\n          ambDiff = unpackRGBE(diffuseMap);\n        #else\n          ambDiff = SRGBToLinear(diffuseMap.rgb);\n        #endif\n      #endif\n      #if !CC_USE_REFLECTION_PROBE\n        vec3 R = normalize(reflect(-V, N));\n        vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w);\n        #if USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED\n          env = GetEnvReflectionWithMipFiltering(rotationDir, s.roughness, cc_ambientGround.w, 0.6, vec2(0.0));\n        #else\n          vec4 envmap = fragTextureLod(cc_environment, rotationDir, s.roughness * (cc_ambientGround.w - 1.0));\n          #if CC_USE_IBL == 2\n            env = unpackRGBE(envmap);\n          #else\n            env = SRGBToLinear(envmap.rgb);\n            #endif\n        #endif\n      #endif\n    #endif\n    #if CC_USE_REFLECTION_PROBE\n      vec4 probe = vec4(0.0);\n      vec3 R = normalize(reflect(-V, N));\n      #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE\n        probe = fragTextureLod(cc_reflectionProbeCubemap, R, s.roughness * (cc_ambientGround.w - 1.0));\n      #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR\n        vec2 screenUV = GetPlanarReflectScreenUV(s.position, cc_matViewProj, cc_cameraPos.w, V, R);\n        probe = texture(cc_reflectionProbePlanarMap, screenUV);\n      #endif\n      env = unpackRGBE(probe);\n    #endif\n    finalColor += env * cc_ambientSky.w * specular * s.occlusion;\n  #if CC_USE_LIGHT_PROBE\n    finalColor += SHEvaluate(N) * diffuse * s.occlusion;\n  #endif\n    finalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\n    finalColor += s.emissive;\n    return vec4(finalColor, s.albedo.a);\n  }\n  #if CC_PIPELINE_TYPE == 0\n    #define LIGHTS_PER_PASS 1\n  #else\n    #define LIGHTS_PER_PASS 10\n  #endif\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\n  layout(std140) uniform CCForwardLight {\n    highp vec4 cc_lightPos[LIGHTS_PER_PASS];\n    vec4 cc_lightColor[LIGHTS_PER_PASS];\n    vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\n    vec4 cc_lightDir[LIGHTS_PER_PASS];\n  };\n  #endif\n  float SmoothDistAtt (float distSqr, float invSqrAttRadius) {\n    float factor = distSqr * invSqrAttRadius;\n    float smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\n    return smoothFactor * smoothFactor;\n  }\n  float GetDistAtt (float distSqr, float invSqrAttRadius) {\n    float attenuation = 1.0 / max(distSqr, 0.01*0.01);\n    attenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\n    return attenuation;\n  }\n  float GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\n    float cd = dot(litDir, L);\n    float attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\n    return (attenuation * attenuation);\n  }\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\n  vec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\n    vec3 diffuseContrib = diffuse / PI;\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    float NV = max(abs(dot(N, V)), 0.0);\n    specular = BRDFApprox(specular, s.roughness, NV);\n    vec3 finalColor = vec3(0.0);\n    int numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\n    for (int i = 0; i < LIGHTS_PER_PASS; i++) {\n      if (i >= numLights) break;\n      vec3 SLU = cc_lightPos[i].xyz - position;\n      vec3 SL = normalize(SLU);\n      vec3 SH = normalize(SL + V);\n      float SNL = max(dot(N, SL), 0.0);\n      float SNH = max(dot(N, SH), 0.0);\n      float distSqr = dot(SLU, SLU);\n      float litRadius = cc_lightSizeRangeAngle[i].x;\n      float litRadiusSqr = litRadius * litRadius;\n      float illum = litRadiusSqr / max(litRadiusSqr, distSqr);\n      float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\n      attRadiusSqrInv *= attRadiusSqrInv;\n      float att = GetDistAtt(distSqr, attRadiusSqrInv);\n      vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\n      if (cc_lightPos[i].w > 0.0) {\n        float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\n        float cosOuter = cc_lightSizeRangeAngle[i].z;\n        float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\n        float litAngleOffset = -cosOuter * litAngleScale;\n        att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n      }\n      vec3 lightColor = cc_lightColor[i].rgb;\n      float shadow = 1.0;\n      #if CC_RECEIVE_SHADOW  && CC_SHADOW_TYPE == 2\n        if (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\n          shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n        }\n      #endif\n      lightColor *= shadow;\n      finalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n    }\n    return vec4(finalColor, 0.0);\n  }\n  #endif\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\n  layout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\n  layout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\n  layout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\n  struct CCLight\n  {\n    vec4 cc_lightPos;\n    vec4 cc_lightColor;\n    vec4 cc_lightSizeRangeAngle;\n    vec4 cc_lightDir;\n  };\n  struct Cluster\n  {\n    vec3 minBounds;\n    vec3 maxBounds;\n  };\n  struct LightGrid\n  {\n    uint offset;\n    uint ccLights;\n  };\n  CCLight getCCLight(uint i)\n  {\n    CCLight light;\n    light.cc_lightPos = b_ccLights[4u * i + 0u];\n    light.cc_lightColor = b_ccLights[4u * i + 1u];\n    light.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\n    light.cc_lightDir = b_ccLights[4u * i + 3u];\n    return light;\n  }\n  LightGrid getLightGrid(uint cluster)\n  {\n    uvec4 gridvec = b_clusterLightGrid[cluster];\n    LightGrid grid;\n    grid.offset = gridvec.x;\n    grid.ccLights = gridvec.y;\n    return grid;\n  }\n  uint getGridLightIndex(uint start, uint offset)\n  {\n    return b_clusterLightIndices[start + offset];\n  }\n  uint getClusterZIndex(vec4 worldPos)\n  {\n    float scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\n    float bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\n    float eyeDepth = -(cc_matView * worldPos).z;\n    uint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\n    return zIndex;\n  }\n  uint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n  {\n    uint zIndex = getClusterZIndex(worldPos);\n    float clusterSizeX = ceil(cc_viewPort.z / float(16));\n    float clusterSizeY = ceil(cc_viewPort.w / float(8));\n    uvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\n    uint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\n    return cluster;\n  }\n  vec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\n    vec3 diffuseContrib = diffuse / PI;\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    float NV = max(abs(dot(N, V)), 0.001);\n    specular = BRDFApprox(specular, s.roughness, NV);\n    vec3 finalColor = vec3(0.0);\n    uint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\n    LightGrid grid = getLightGrid(cluster);\n    uint numLights = grid.ccLights;\n    for (uint i = 0u; i < 100u; i++) {\n      if (i >= numLights) break;\n      uint lightIndex = getGridLightIndex(grid.offset, i);\n      CCLight light = getCCLight(lightIndex);\n      vec3 SLU = light.cc_lightPos.xyz - position;\n      vec3 SL = normalize(SLU);\n      vec3 SH = normalize(SL + V);\n      float SNL = max(dot(N, SL), 0.001);\n      float SNH = max(dot(N, SH), 0.0);\n      float distSqr = dot(SLU, SLU);\n      float litRadius = light.cc_lightSizeRangeAngle.x;\n      float litRadiusSqr = litRadius * litRadius;\n      float illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\n      float attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\n      attRadiusSqrInv *= attRadiusSqrInv;\n      float att = GetDistAtt(distSqr, attRadiusSqrInv);\n      vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\n      if (light.cc_lightPos.w > 0.0) {\n        float cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\n        float cosOuter = light.cc_lightSizeRangeAngle.z;\n        float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\n        float litAngleOffset = -cosOuter * litAngleScale;\n        att *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n      }\n      vec3 lightColor = light.cc_lightColor.rgb;\n      float shadow = 1.0;\n      #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == 2\n        if (light.cc_lightPos.w > 0.0) {\n          shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n        }\n      #endif\n      lightColor *= shadow;\n      finalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n    }\n    return vec4(finalColor, 0.0);\n  }\n  #endif\n  vec3 ACESToneMap (vec3 color) {\n    color = min(color, vec3(8.0));\n    const float A = 2.51;\n    const float B = 0.03;\n    const float C = 2.43;\n    const float D = 0.59;\n    const float E = 0.14;\n    return (color * (A * color + B)) / (color * (C * color + D) + E);\n  }\n  vec4 CCFragOutput (vec4 color) {\n    #if !CC_USE_RGBE_OUTPUT\n      #if CC_USE_HDR\n        color.rgb = ACESToneMap(color.rgb);\n      #endif\n      color.rgb = LinearToSRGB(color.rgb);\n    #endif\n    return color;\n  }\n  #if CC_USE_FOG != 4\n    float LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\n        vec4 wPos = pos;\n        float cam_dis = distance(cameraPos, wPos.xyz);\n        return clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n    }\n    float ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\n        vec4 wPos = pos;\n        float cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\n        float f = exp(-cam_dis * fogDensity);\n        return f;\n    }\n    float ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\n        vec4 wPos = pos;\n        float cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\n        float f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\n        return f;\n    }\n    float LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\n        vec4 wPos = pos;\n        vec3 camWorldProj = cameraPos.xyz;\n        camWorldProj.y = 0.;\n        vec3 worldPosProj = wPos.xyz;\n        worldPosProj.y = 0.;\n        float fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\n        float fDeltaY, fDensityIntegral;\n        if (cameraPos.y > fogTop) {\n            if (wPos.y < fogTop) {\n                fDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\n                fDensityIntegral = fDeltaY * fDeltaY * 0.5;\n            }\n            else {\n                fDeltaY = 0.;\n                fDensityIntegral = 0.;\n            }\n        }\n        else {\n            if (wPos.y < fogTop) {\n                float fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\n                float fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\n                fDeltaY = abs(fDeltaA - fDeltaB);\n                fDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n            }\n            else {\n                fDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\n                fDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n            }\n        }\n        float fDensity;\n        if (fDeltaY != 0.) {\n            fDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n        }\n        else {\n            fDensity = 0.;\n        }\n        float f = exp(-fDensity);\n        return f;\n    }\n  #endif\n  void CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n  {\n  #if CC_USE_FOG == 0\n  \tfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n  #elif CC_USE_FOG == 1\n  \tfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n  #elif CC_USE_FOG == 2\n  \tfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n  #elif CC_USE_FOG == 3\n  \tfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n  #else\n  \tfactor = 1.0;\n  #endif\n  }\n  void CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\n  \tcolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n  }\n  vec2 signNotZero(vec2 v) {\n    return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n  }\n  vec3 oct_to_float32x3(vec2 e) {\n    vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\n    if (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\n    return normalize(v);\n  }\n  in vec2 v_uv;\n  uniform sampler2D gbuffer_albedoMap;\n  uniform sampler2D gbuffer_normalMap;\n  uniform sampler2D gbuffer_emissiveMap;\n  uniform sampler2D depth_stencil;\n  layout(location = 0) out vec4 fragColor;\n  vec4 screen2WS(vec3 coord) {\n    vec3 ndc = vec3(\n      2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n      2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n      2.0 * coord.z - 1.0);\n    return GetWorldPosFromNDCPosRH(ndc, cc_matProj, cc_matViewProjInv);\n  }\n  void main () {\n    StandardSurface s;\n    vec4 albedoMap = texture(gbuffer_albedoMap,v_uv);\n    vec4 normalMap = texture(gbuffer_normalMap,v_uv);\n    vec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv);\n    float depth = texture(depth_stencil, v_uv).x;\n    s.albedo = albedoMap;\n    vec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\n    s.position = position;\n    s.roughness = normalMap.z;\n    s.normal = oct_to_float32x3(normalMap.xy);\n    s.specularIntensity = 0.5;\n    s.metallic = normalMap.w;\n    s.emissive = emissiveMap.xyz;\n    s.occlusion = emissiveMap.w;\n    float fogFactor;\n    CC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\n    vec4 shadowPos;\n    shadowPos = cc_matLightViewProj * vec4(position, 1);\n    vec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\n                 CCClusterShadingAdditive(s, shadowPos);\n#else\n                 CCStandardShadingAdditive(s, shadowPos);\n#endif\n    CC_APPLY_FOG_BASE(color, fogFactor);\n    color = CCFragOutput(color);\n    fragColor = color;\n  }"
      },
      "glsl1": {
        "vert": "\nprecision highp float;\n#define QUATER_PI         0.78539816340\n#define HALF_PI           1.57079632679\n#define PI                3.14159265359\n#define PI2               6.28318530718\n#define PI4               12.5663706144\n#define INV_QUATER_PI     1.27323954474\n#define INV_HALF_PI       0.63661977237\n#define INV_PI            0.31830988618\n#define INV_PI2           0.15915494309\n#define INV_PI4           0.07957747155\n#define EPSILON           1e-6\n#define EPSILON_LOWP      1e-4\n#define LOG2              1.442695\n#define EXP_VALUE         2.71828183f\n#define FP_MAX            65504.0\n#define FP_SCALE          0.0009765625\n#define FP_SCALE_INV      1024.0\n#define GRAY_VECTOR       vec3(0.299, 0.587, 0.114)\n#define LIGHT_MAP_TYPE_DISABLED 0\n#define LIGHT_MAP_TYPE_ALL_IN_ONE 1\n#define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2\n#define REFLECTION_PROBE_TYPE_NONE 0\n#define REFLECTION_PROBE_TYPE_CUBE 1\n#define REFLECTION_PROBE_TYPE_PLANAR 2\n#define LIGHT_TYPE_DIRECTIONAL 0.0\n#define LIGHT_TYPE_SPHERE 1.0\n#define LIGHT_TYPE_SPOT 2.0\n#define IS_DIRECTIONAL_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_DIRECTIONAL)) < EPSILON)\n#define IS_SPHERE_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPHERE)) < EPSILON)\n#define IS_SPOT_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPOT)) < EPSILON)\nstruct StandardVertInput {\n  highp vec4 position;\n  vec3 normal;\n  vec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\n    attribute vec4 a_joints;\n  attribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n  #if CC_USE_BAKED_ANIMATION\n    attribute highp vec4 a_jointAnimInfo;\n  #endif\n  attribute vec4 a_matWorld0;\n  attribute vec4 a_matWorld1;\n  attribute vec4 a_matWorld2;\n  #if CC_USE_LIGHTMAP\n    attribute vec4 a_lightingMapUVParam;\n  #endif\n  #if CC_RECEIVE_SHADOW\n    attribute vec2 a_localShadowBias;\n  #endif\n  #if CC_USE_LIGHT_PROBE\n    attribute vec4 a_sh_linear_const_r;\n    attribute vec4 a_sh_linear_const_g;\n    attribute vec4 a_sh_linear_const_b;\n  #endif\n#endif\n#if CC_USE_MORPH\n    attribute float a_vertexId;\n#endif\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\n  vec4 position;\n    position = vec4(a_position, 1.0);\n  position.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\n  gl_Position = vec4(position.x, position.y, 1.0, 1.0);\n  v_uv = a_texCoord;\n}",
        "frag": "\n#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives: enable\n#endif\n#ifdef GL_EXT_shader_texture_lod\n#extension GL_EXT_shader_texture_lod: enable\n#endif\n  precision highp float;\n  uniform mediump vec4 cc_debug_view_mode;\n  uniform mediump vec4 cc_debug_view_composite_pack_1;\n  uniform mediump vec4 cc_debug_view_composite_pack_2;\n  uniform mediump vec4 cc_debug_view_composite_pack_3;\n  uniform highp mat4 cc_matView;\n  uniform highp mat4 cc_matProj;\n  uniform highp mat4 cc_matViewProj;\n  uniform highp mat4 cc_matViewProjInv;\n  uniform highp vec4 cc_cameraPos;\n  uniform mediump vec4 cc_surfaceTransform;\n  uniform mediump vec4 cc_exposure;\n  uniform mediump vec4 cc_mainLitDir;\n  uniform mediump vec4 cc_mainLitColor;\n  uniform mediump vec4 cc_ambientSky;\n  uniform mediump vec4 cc_ambientGround;\n  uniform mediump vec4 cc_fogColor;\n  uniform mediump vec4 cc_fogBase;\n  uniform mediump vec4 cc_fogAdd;\n  uniform mediump vec4 cc_nearFar;\n  uniform mediump vec4 cc_viewPort;\n  #define QUATER_PI         0.78539816340\n  #define HALF_PI           1.57079632679\n  #define PI                3.14159265359\n  #define PI2               6.28318530718\n  #define PI4               12.5663706144\n  #define INV_QUATER_PI     1.27323954474\n  #define INV_HALF_PI       0.63661977237\n  #define INV_PI            0.31830988618\n  #define INV_PI2           0.15915494309\n  #define INV_PI4           0.07957747155\n  #define EPSILON           1e-6\n  #define EPSILON_LOWP      1e-4\n  #define LOG2              1.442695\n  #define EXP_VALUE         2.71828183f\n  #define FP_MAX            65504.0\n  #define FP_SCALE          0.0009765625\n  #define FP_SCALE_INV      1024.0\n  #define GRAY_VECTOR       vec3(0.299, 0.587, 0.114)\n      #define LIGHT_MAP_TYPE_DISABLED 0\n  #define LIGHT_MAP_TYPE_ALL_IN_ONE 1\n  #define LIGHT_MAP_TYPE_INDIRECT_OCCLUSION 2\n  #define REFLECTION_PROBE_TYPE_NONE 0\n  #define REFLECTION_PROBE_TYPE_CUBE 1\n  #define REFLECTION_PROBE_TYPE_PLANAR 2\n  #define LIGHT_TYPE_DIRECTIONAL 0.0\n  #define LIGHT_TYPE_SPHERE 1.0\n  #define LIGHT_TYPE_SPOT 2.0\n  #define IS_DIRECTIONAL_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_DIRECTIONAL)) < EPSILON)\n  #define IS_SPHERE_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPHERE)) < EPSILON)\n  #define IS_SPOT_LIGHT(light_type) (abs(float(light_type) - float(LIGHT_TYPE_SPOT)) < EPSILON)\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_COLOR 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_NORMAL CC_SURFACES_DEBUG_VIEW_VERTEX_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_TANGENT CC_SURFACES_DEBUG_VIEW_VERTEX_NORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_WORLD_POS CC_SURFACES_DEBUG_VIEW_VERTEX_TANGENT + 1\n  #define CC_SURFACES_DEBUG_VIEW_VERTEX_MIRROR CC_SURFACES_DEBUG_VIEW_WORLD_POS + 1\n  #define CC_SURFACES_DEBUG_VIEW_FACE_SIDE CC_SURFACES_DEBUG_VIEW_VERTEX_MIRROR + 1\n  #define CC_SURFACES_DEBUG_VIEW_UV0 CC_SURFACES_DEBUG_VIEW_FACE_SIDE + 1\n  #define CC_SURFACES_DEBUG_VIEW_UV1 CC_SURFACES_DEBUG_VIEW_UV0 + 1\n  #define CC_SURFACES_DEBUG_VIEW_UVLIGHTMAP CC_SURFACES_DEBUG_VIEW_UV1 + 1\n  #define CC_SURFACES_DEBUG_VIEW_PROJ_DEPTH CC_SURFACES_DEBUG_VIEW_UVLIGHTMAP + 1\n  #define CC_SURFACES_DEBUG_VIEW_LINEAR_DEPTH CC_SURFACES_DEBUG_VIEW_PROJ_DEPTH + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_NORMAL CC_SURFACES_DEBUG_VIEW_LINEAR_DEPTH + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_TANGENT CC_SURFACES_DEBUG_VIEW_FRAGMENT_NORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_FRAGMENT_BINORMAL CC_SURFACES_DEBUG_VIEW_FRAGMENT_TANGENT + 1\n  #define CC_SURFACES_DEBUG_VIEW_BASE_COLOR CC_SURFACES_DEBUG_VIEW_FRAGMENT_BINORMAL + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIFFUSE_COLOR CC_SURFACES_DEBUG_VIEW_BASE_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_SPECULAR_COLOR CC_SURFACES_DEBUG_VIEW_DIFFUSE_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_TRANSPARENCY CC_SURFACES_DEBUG_VIEW_SPECULAR_COLOR + 1\n  #define CC_SURFACES_DEBUG_VIEW_METALLIC CC_SURFACES_DEBUG_VIEW_TRANSPARENCY + 1\n  #define CC_SURFACES_DEBUG_VIEW_ROUGHNESS CC_SURFACES_DEBUG_VIEW_METALLIC + 1\n  #define CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY CC_SURFACES_DEBUG_VIEW_ROUGHNESS + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE CC_SURFACES_DEBUG_VIEW_SPECULAR_INTENSITY + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR CC_SURFACES_DEBUG_VIEW_DIRECT_DIFFUSE + 1\n  #define CC_SURFACES_DEBUG_VIEW_DIRECT_ALL CC_SURFACES_DEBUG_VIEW_DIRECT_SPECULAR + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE CC_SURFACES_DEBUG_VIEW_DIRECT_ALL + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR CC_SURFACES_DEBUG_VIEW_ENV_DIFFUSE + 1\n  #define CC_SURFACES_DEBUG_VIEW_ENV_ALL CC_SURFACES_DEBUG_VIEW_ENV_SPECULAR + 1\n  #define CC_SURFACES_DEBUG_VIEW_EMISSIVE CC_SURFACES_DEBUG_VIEW_ENV_ALL + 1\n  #define CC_SURFACES_DEBUG_VIEW_LIGHT_MAP CC_SURFACES_DEBUG_VIEW_EMISSIVE + 1\n  #define CC_SURFACES_DEBUG_VIEW_SHADOW CC_SURFACES_DEBUG_VIEW_LIGHT_MAP + 1\n  #define CC_SURFACES_DEBUG_VIEW_AO CC_SURFACES_DEBUG_VIEW_SHADOW + 1\n  #define CC_SURFACES_DEBUG_VIEW_FOG CC_SURFACES_DEBUG_VIEW_AO + 1\n  #define CC_SURFACES_DEBUG_VIEW_SINGLE 1\n  #define CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC 2\n  #define IS_DEBUG_VIEW_ENABLE_WITH_CAMERA (cc_surfaceTransform.y != 3.0)\n    #define IS_DEBUG_VIEW_LIGHTING_ENABLE_WITH_ALBEDO ((cc_debug_view_mode.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_MISC_ENABLE_CSM_LAYER_COLORATION ((cc_debug_view_mode.z > 0.0) && IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_DIFFUSE ((cc_debug_view_composite_pack_1.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_DIRECT_SPECULAR ((cc_debug_view_composite_pack_1.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_DIFFUSE ((cc_debug_view_composite_pack_1.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_ENV_SPECULAR ((cc_debug_view_composite_pack_1.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_EMISSIVE ((cc_debug_view_composite_pack_2.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_LIGHT_MAP ((cc_debug_view_composite_pack_2.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_SHADOW ((cc_debug_view_composite_pack_2.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_AO ((cc_debug_view_composite_pack_2.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_NORMAL_MAP ((cc_debug_view_composite_pack_3.x > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_FOG ((cc_debug_view_composite_pack_3.y > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_TONE_MAPPING ((cc_debug_view_composite_pack_3.z > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  #define IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION ((cc_debug_view_composite_pack_3.w > 0.0) || !IS_DEBUG_VIEW_ENABLE_WITH_CAMERA)\n  vec3 SRGBToLinear (vec3 gamma) {\n  #ifdef CC_USE_SURFACE_SHADER\n    #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC\n      if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION) {\n        return gamma;\n      }\n    #endif\n  #endif\n    return gamma * gamma;\n  }\n  vec3 LinearToSRGB(vec3 linear) {\n  #ifdef CC_USE_SURFACE_SHADER\n    #if CC_USE_DEBUG_VIEW == CC_SURFACES_DEBUG_VIEW_COMPOSITE_AND_MISC\n      if (!IS_DEBUG_VIEW_COMPOSITE_ENABLE_GAMMA_CORRECTION) {\n        return linear;\n      }\n    #endif\n  #endif\n    return sqrt(linear);\n  }\n  uniform highp mat4 cc_matLightView;\n  uniform highp mat4 cc_matLightViewProj;\n  uniform highp vec4 cc_shadowInvProjDepthInfo;\n  uniform highp vec4 cc_shadowProjDepthInfo;\n  uniform highp vec4 cc_shadowProjInfo;\n  uniform mediump vec4 cc_shadowNFLSInfo;\n  uniform mediump vec4 cc_shadowWHPBInfo;\n  uniform mediump vec4 cc_shadowLPNNInfo;\n  #if CC_SUPPORT_CASCADED_SHADOW_MAP\n    uniform highp vec4 cc_csmViewDir0[4];\n  uniform highp vec4 cc_csmViewDir1[4];\n  uniform highp vec4 cc_csmViewDir2[4];\n  uniform highp vec4 cc_csmAtlas[4];\n  uniform highp mat4 cc_matCSMViewProj[4];\n  uniform highp vec4 cc_csmProjDepthInfo[4];\n  uniform highp vec4 cc_csmProjInfo[4];\n  uniform highp vec4 cc_csmSplitsInfo;\n  #endif\n  vec2 GetPlanarReflectScreenUV(vec3 worldPos, mat4 matVirtualCameraViewProj, float flipNDCSign, vec3 viewDir, vec3 reflectDir)\n  {\n    vec4 clipPos = matVirtualCameraViewProj * vec4(worldPos, 1.0);\n    vec2 screenUV = clipPos.xy / clipPos.w * 0.5 + 0.5;\n    screenUV = vec2(1.0 - screenUV.x, screenUV.y);\n    screenUV = flipNDCSign == 1.0 ? vec2(screenUV.x, 1.0 - screenUV.y) : screenUV;\n    return screenUV;\n  }\n  float GetCameraDepthRH(float depthHS, mat4 matProj)\n  {\n      return -matProj[3][2] / (depthHS + matProj[2][2]);\n  }\n  float GetCameraDepthRH(float depthHS, float matProj32, float matProj22)\n  {\n      return -matProj32 / (depthHS + matProj22);\n  }\n  vec4 GetWorldPosFromNDCPosRH(vec3 posHS, mat4 matProj, mat4 matViewProjInv)\n  {\n      float w = -GetCameraDepthRH(posHS.z, matProj);\n      return matViewProjInv * vec4(posHS * w, w);\n  }\n  float GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\n    float dist = length(viewPos);\n    return (dist - near) / (far - near);\n  }\n  vec3 RotationVecFromAxisY(vec3 v, float cosTheta, float sinTheta)\n  {\n      vec3 result;\n      result.x = dot(v, vec3(cosTheta, 0.0, -sinTheta));\n      result.y = v.y;\n      result.z = dot(v, vec3(sinTheta, 0.0,  cosTheta));\n      return result;\n  }\n  float CCGetLinearDepth(vec3 worldPos, float viewSpaceBias) {\n  \tvec4 viewPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\n    viewPos.z += viewSpaceBias;\n  \treturn GetLinearDepthFromViewSpace(viewPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n  }\n  float CCGetLinearDepth(vec3 worldPos) {\n  \treturn CCGetLinearDepth(worldPos, 0.0);\n  }\n  #if CC_RECEIVE_SHADOW\n    uniform highp sampler2D cc_shadowMap;\n    uniform highp sampler2D cc_spotShadowMap;\n        highp float unpackHighpData (float mainPart, float modPart) {\n          highp float data = mainPart;\n          return data + modPart;\n        }\n        highp float unpackHighpData (float mainPart, float modPart, const float modValue) {\n          highp float data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\n          highp vec2 data = mainPart;\n          return data + modPart;\n        }\n        highp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\n          highp vec2 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\n          highp vec3 data = mainPart;\n          return data + modPart;\n        }\n        highp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\n          highp vec3 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n        highp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\n          highp vec4 data = mainPart;\n          return data + modPart;\n        }\n        highp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\n          highp vec4 data = mainPart * modValue;\n          return data + modPart * modValue;\n        }\n    float NativePCFShadowFactorHard (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      #if CC_SHADOWMAP_FORMAT == 1\n        return step(shadowNDCPos.z, dot(texture2D(shadowMap, shadowNDCPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        return step(shadowNDCPos.z, texture2D(shadowMap, shadowNDCPos.xy).x);\n      #endif\n    }\n    float NativePCFShadowFactorSoft (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      vec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap;\n      float block0, block1, block2, block3;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block0 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block1 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block0 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\n        block1 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)).x);\n        block2 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)).x);\n        block3 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)).x);\n      #endif\n      float coefX   = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\n      float resultX = mix(block0, block1, coefX);\n      float resultY = mix(block2, block3, coefX);\n      float coefY   = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\n      return mix(resultX, resultY, coefY);\n    }\n    float NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      float shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x;\n      float shadowNDCPos_offset_R = shadowNDCPos.x + oneTap.x;\n      float shadowNDCPos_offset_U = shadowNDCPos.y - oneTap.y;\n      float shadowNDCPos_offset_D = shadowNDCPos.y + oneTap.y;\n      float block0, block1, block2, block3, block4, block5, block6, block7, block8;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block0 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block1 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block4 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block5 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block6 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block7 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block8 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block0 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)).x);\n        block1 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)).x);\n        block2 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)).x);\n        block3 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)).x);\n        block4 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\n        block5 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)).x);\n        block6 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)).x);\n        block7 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)).x);\n        block8 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)).x);\n      #endif\n      float coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\n      float coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\n      float shadow = 0.0;\n      float resultX = mix(block0, block1, coefX);\n      float resultY = mix(block3, block4, coefX);\n      shadow += mix(resultX , resultY, coefY);\n      resultX = mix(block1, block2, coefX);\n      resultY = mix(block4, block5, coefX);\n      shadow += mix(resultX , resultY, coefY);\n      resultX = mix(block3, block4, coefX);\n      resultY = mix(block6, block7, coefX);\n      shadow += mix(resultX, resultY, coefY);\n      resultX = mix(block4, block5, coefX);\n      resultY = mix(block7, block8, coefX);\n      shadow += mix(resultX, resultY, coefY);\n      return shadow * 0.25;\n    }\n    float NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, highp sampler2D shadowMap, vec2 shadowMapResolution)\n    {\n      vec2 oneTap = 1.0 / shadowMapResolution;\n      vec2 twoTap = oneTap * 2.0;\n      vec2 offset1 = shadowNDCPos.xy + vec2(-twoTap.x, -twoTap.y);\n      vec2 offset2 = shadowNDCPos.xy + vec2(-oneTap.x, -twoTap.y);\n      vec2 offset3 = shadowNDCPos.xy + vec2(0.0, -twoTap.y);\n      vec2 offset4 = shadowNDCPos.xy + vec2(oneTap.x, -twoTap.y);\n      vec2 offset5 = shadowNDCPos.xy + vec2(twoTap.x, -twoTap.y);\n      vec2 offset6 = shadowNDCPos.xy + vec2(-twoTap.x, -oneTap.y);\n      vec2 offset7 = shadowNDCPos.xy + vec2(-oneTap.x, -oneTap.y);\n      vec2 offset8 = shadowNDCPos.xy + vec2(0.0, -oneTap.y);\n      vec2 offset9 = shadowNDCPos.xy + vec2(oneTap.x, -oneTap.y);\n      vec2 offset10 = shadowNDCPos.xy + vec2(twoTap.x, -oneTap.y);\n      vec2 offset11 = shadowNDCPos.xy + vec2(-twoTap.x, 0.0);\n      vec2 offset12 = shadowNDCPos.xy + vec2(-oneTap.x, 0.0);\n      vec2 offset13 = shadowNDCPos.xy + vec2(0.0, 0.0);\n      vec2 offset14 = shadowNDCPos.xy + vec2(oneTap.x, 0.0);\n      vec2 offset15 = shadowNDCPos.xy + vec2(twoTap.x, 0.0);\n      vec2 offset16 = shadowNDCPos.xy + vec2(-twoTap.x, oneTap.y);\n      vec2 offset17 = shadowNDCPos.xy + vec2(-oneTap.x, oneTap.y);\n      vec2 offset18 = shadowNDCPos.xy + vec2(0.0, oneTap.y);\n      vec2 offset19 = shadowNDCPos.xy + vec2(oneTap.x, oneTap.y);\n      vec2 offset20 = shadowNDCPos.xy + vec2(twoTap.x, oneTap.y);\n      vec2 offset21 = shadowNDCPos.xy + vec2(-twoTap.x, twoTap.y);\n      vec2 offset22 = shadowNDCPos.xy + vec2(-oneTap.x, twoTap.y);\n      vec2 offset23 = shadowNDCPos.xy + vec2(0.0, twoTap.y);\n      vec2 offset24 = shadowNDCPos.xy + vec2(oneTap.x, twoTap.y);\n      vec2 offset25 = shadowNDCPos.xy + vec2(twoTap.x, twoTap.y);\n      float block1, block2, block3, block4, block5, block6, block7, block8, block9, block10, block11, block12, block13, block14, block15, block16, block17, block18, block19, block20, block21, block22, block23, block24, block25;\n      #if CC_SHADOWMAP_FORMAT == 1\n        block1 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset1), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block2 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset2), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block3 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset3), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block4 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset4), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block5 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset5), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block6 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset6), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block7 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset7), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block8 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset8), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block9 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset9), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block10 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset10), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block11 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset11), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block12 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset12), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block13 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset13), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block14 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset14), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block15 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset15), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block16 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset16), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block17 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset17), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block18 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset18), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block19 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset19), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block20 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset20), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block21 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset21), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block22 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset22), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block23 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset23), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block24 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset24), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n        block25 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset25), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n      #else\n        block1 = step(shadowNDCPos.z, texture2D(shadowMap, offset1).x);\n        block2 = step(shadowNDCPos.z, texture2D(shadowMap, offset2).x);\n        block3 = step(shadowNDCPos.z, texture2D(shadowMap, offset3).x);\n        block4 = step(shadowNDCPos.z, texture2D(shadowMap, offset4).x);\n        block5 = step(shadowNDCPos.z, texture2D(shadowMap, offset5).x);\n        block6 = step(shadowNDCPos.z, texture2D(shadowMap, offset6).x);\n        block7 = step(shadowNDCPos.z, texture2D(shadowMap, offset7).x);\n        block8 = step(shadowNDCPos.z, texture2D(shadowMap, offset8).x);\n        block9 = step(shadowNDCPos.z, texture2D(shadowMap, offset9).x);\n        block10 = step(shadowNDCPos.z, texture2D(shadowMap, offset10).x);\n        block11 = step(shadowNDCPos.z, texture2D(shadowMap, offset11).x);\n        block12 = step(shadowNDCPos.z, texture2D(shadowMap, offset12).x);\n        block13 = step(shadowNDCPos.z, texture2D(shadowMap, offset13).x);\n        block14 = step(shadowNDCPos.z, texture2D(shadowMap, offset14).x);\n        block15 = step(shadowNDCPos.z, texture2D(shadowMap, offset15).x);\n        block16 = step(shadowNDCPos.z, texture2D(shadowMap, offset16).x);\n        block17 = step(shadowNDCPos.z, texture2D(shadowMap, offset17).x);\n        block18 = step(shadowNDCPos.z, texture2D(shadowMap, offset18).x);\n        block19 = step(shadowNDCPos.z, texture2D(shadowMap, offset19).x);\n        block20 = step(shadowNDCPos.z, texture2D(shadowMap, offset20).x);\n        block21 = step(shadowNDCPos.z, texture2D(shadowMap, offset21).x);\n        block22 = step(shadowNDCPos.z, texture2D(shadowMap, offset22).x);\n        block23 = step(shadowNDCPos.z, texture2D(shadowMap, offset23).x);\n        block24 = step(shadowNDCPos.z, texture2D(shadowMap, offset24).x);\n        block25 = step(shadowNDCPos.z, texture2D(shadowMap, offset25).x);\n      #endif\n      vec2 coef = fract(shadowNDCPos.xy * shadowMapResolution);\n      vec2 v1X1 = mix(vec2(block1, block6), vec2(block2, block7), coef.xx);\n      vec2 v1X2 = mix(vec2(block2, block7), vec2(block3, block8), coef.xx);\n      vec2 v1X3 = mix(vec2(block3, block8), vec2(block4, block9), coef.xx);\n      vec2 v1X4 = mix(vec2(block4, block9), vec2(block5, block10), coef.xx);\n      float v1 = mix(v1X1.x, v1X1.y, coef.y) + mix(v1X2.x, v1X2.y, coef.y) + mix(v1X3.x, v1X3.y, coef.y) + mix(v1X4.x, v1X4.y, coef.y);\n      vec2 v2X1 = mix(vec2(block6, block11), vec2(block7, block12), coef.xx);\n      vec2 v2X2 = mix(vec2(block7, block12), vec2(block8, block13), coef.xx);\n      vec2 v2X3 = mix(vec2(block8, block13), vec2(block9, block14), coef.xx);\n      vec2 v2X4 = mix(vec2(block9, block14), vec2(block10, block15), coef.xx);\n      float v2 = mix(v2X1.x, v2X1.y, coef.y) + mix(v2X2.x, v2X2.y, coef.y) + mix(v2X3.x, v2X3.y, coef.y) + mix(v2X4.x, v2X4.y, coef.y);\n      vec2 v3X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\n      vec2 v3X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\n      vec2 v3X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\n      vec2 v3X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\n      float v3 = mix(v3X1.x, v3X1.y, coef.y) + mix(v3X2.x, v3X2.y, coef.y) + mix(v3X3.x, v3X3.y, coef.y) + mix(v3X4.x, v3X4.y, coef.y);\n      vec2 v4X1 = mix(vec2(block16, block21), vec2(block17, block22), coef.xx);\n      vec2 v4X2 = mix(vec2(block17, block22), vec2(block18, block23), coef.xx);\n      vec2 v4X3 = mix(vec2(block18, block23), vec2(block19, block24), coef.xx);\n      vec2 v4X4 = mix(vec2(block19, block24), vec2(block20, block25), coef.xx);\n      float v4 = mix(v4X1.x, v4X1.y, coef.y) + mix(v4X2.x, v4X2.y, coef.y) + mix(v4X3.x, v4X3.y, coef.y) + mix(v4X4.x, v4X4.y, coef.y);\n      float fAvg = (v1 + v2 + v3 + v4) * 0.0625;\n      return fAvg;\n    }\n    bool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)\n    {\n    \tshadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;\n    \tif (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||\n    \t\tshadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||\n    \t\tshadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {\n    \t\treturn false;\n    \t}\n    \tshadowNDCPos.xy = cc_cameraPos.w == 1.0 ? vec2(shadowNDCPos.xy.x, 1.0 - shadowNDCPos.xy.y) : shadowNDCPos.xy;\n    \treturn true;\n    }\n    vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, vec3 matViewDir0, vec3 matViewDir1, vec3 matViewDir2, vec2 projScaleXY)\n    {\n      vec4 newShadowPos = shadowPos;\n      if (normalBias > EPSILON_LOWP)\n      {\n        vec3 viewNormal = vec3(dot(matViewDir0, worldNormal), dot(matViewDir1, worldNormal), dot(matViewDir2, worldNormal));\n        if (viewNormal.z < 0.1)\n          newShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n      }\n      return newShadowPos;\n    }\n    vec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)\n    {\n    \tvec4 newShadowPos = shadowPos;\n    \tif (normalBias > EPSILON_LOWP)\n    \t{\n    \t\tvec4 viewNormal = matLightView * vec4(worldNormal, 0.0);\n    \t\tif (viewNormal.z < 0.1)\n    \t\t\tnewShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n    \t}\n    \treturn newShadowPos;\n    }\n    float GetViewSpaceDepthFromNDCDepth_Orthgraphic(float NDCDepth, float projScaleZ, float projBiasZ)\n    {\n    \treturn (NDCDepth - projBiasZ) / projScaleZ;\n    }\n    float GetViewSpaceDepthFromNDCDepth_Perspective(float NDCDepth, float homogenousDividW, float invProjScaleZ, float invProjBiasZ)\n    {\n    \treturn NDCDepth * invProjScaleZ + homogenousDividW * invProjBiasZ;\n    }\n    vec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n    {\n    \tvec3 viewSpacePos;\n    \tviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\n    \tviewSpacePos.z = GetViewSpaceDepthFromNDCDepth_Perspective(shadowPos.z, shadowPos.w, cc_shadowInvProjDepthInfo.x, cc_shadowInvProjDepthInfo.y);\n    \tviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\n    \tvec4 clipSpacePos;\n    \tclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\n    \tclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\n    \t#if CC_SHADOWMAP_USE_LINEAR_DEPTH\n    \t\tclipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n    \t\tclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n    \t#endif\n    \treturn clipSpacePos;\n    }\n    vec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)\n    {\n    \tfloat coeffA = projScaleZ;\n    \tfloat coeffB = projBiasZ;\n    \tfloat viewSpacePos_z = GetViewSpaceDepthFromNDCDepth_Orthgraphic(shadowPos.z, projScaleZ, projBiasZ);\n    \tviewSpacePos_z += viewspaceDepthBias;\n    \tvec4 result = shadowPos;\n    \tresult.z = viewSpacePos_z * coeffA + coeffB;\n    \treturn result;\n    }\n    vec4 ApplyShadowDepthBias_PerspectiveLinearDepth(vec4 shadowPos, float viewspaceDepthBias, vec3 worldPos)\n    {\n      shadowPos.z = CCGetLinearDepth(worldPos, viewspaceDepthBias) * 2.0 - 1.0;\n      shadowPos.z *= shadowPos.w;\n      return shadowPos;\n    }\n    float CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorHard(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\n  \t  vec3 shadowNDCPos;\n  \t  if (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\n  \t\t  return 1.0;\n  \t  }\n      return NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotShadowMap, cc_shadowWHPBInfo.xy);\n    }\n    float CCSpotShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n    {\n      float pcf = cc_shadowWHPBInfo.z;\n      vec4 pos = vec4(1.0);\n      #if CC_SHADOWMAP_USE_LINEAR_DEPTH\n        pos = ApplyShadowDepthBias_PerspectiveLinearDepth(shadowPos, shadowBias.x, worldPos);\n      #else\n        pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);\n      #endif\n      float realtimeShadow = 1.0;\n      if (pcf > 2.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft5X(pos, worldPos);\n      }else if (pcf > 1.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft3X(pos, worldPos);\n      }else if (pcf > 0.9) {\n        realtimeShadow = CCGetSpotLightShadowFactorSoft(pos, worldPos);\n      }else {\n        realtimeShadow = CCGetSpotLightShadowFactorHard(pos, worldPos);\n      }\n      shadowNDCPosWithBias = pos;\n      return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n    }\n    float CCShadowFactorBase(out vec4 shadowNDCPosWithBias, vec4 shadowPos, vec3 N, vec2 shadowBias)\n    {\n      vec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);\n      pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);\n      float realtimeShadow = 1.0;\n      #if CC_DIR_SHADOW_PCF_TYPE == 3\n        realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 2\n        realtimeShadow =  CCGetDirLightShadowFactorSoft3X(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 1\n        realtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n      #endif\n      #if CC_DIR_SHADOW_PCF_TYPE == 0\n        realtimeShadow = CCGetDirLightShadowFactorHard(pos);\n      #endif\n      shadowNDCPosWithBias = pos;\n      return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n    }\n    #if CC_SUPPORT_CASCADED_SHADOW_MAP\n      bool CCGetCSMLevelWithTransition(out float ratio, vec3 clipPos) {\n        highp float layerThreshold = cc_csmViewDir0[0].w;\n        highp float maxRange = 1.0 - cc_csmSplitsInfo.x - layerThreshold;\n        highp float minRange = cc_csmSplitsInfo.x - layerThreshold;\n        if (clipPos.x <= minRange || clipPos.x >= maxRange ||\n            clipPos.y <= minRange || clipPos.y >= maxRange) {\n          if (clipPos.x >= layerThreshold && clipPos.x <= cc_csmSplitsInfo.x) {\n            ratio = (clipPos.x - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          if (clipPos.x >= maxRange && clipPos.x <= 1.0 - layerThreshold) {\n            ratio = (clipPos.x - maxRange) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          if (clipPos.y >= 0.0 && clipPos.y <= cc_csmSplitsInfo.x) {\n            ratio = min((clipPos.y - layerThreshold) / (cc_csmSplitsInfo.x - layerThreshold), 1.0);\n          }\n          if (clipPos.y >= maxRange && clipPos.y <= 1.0 - layerThreshold) {\n            ratio = (clipPos.y - maxRange) / (cc_csmSplitsInfo.x - layerThreshold);\n          }\n          return true;\n        }\n        return false;\n      }\n      int CCGetCSMLevel(out bool hasNextTransition, out bool transitionArea, out float transitionRatio, out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos, int nextLayer)\n      {\n        int layer = -1;\n        highp float layerThreshold = cc_csmViewDir0[0].w;\n        for (int i = 0; i < 4; i++) {\n          vec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\n          vec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;\n          if (clipPos.x >= (0.0 + layerThreshold) && clipPos.x <= (1.0 - layerThreshold) &&\n              clipPos.y >= (0.0 + layerThreshold) && clipPos.y <= (1.0 - layerThreshold) &&\n              clipPos.z >= 0.0 && clipPos.z <= 1.0) {\n            #if CC_CASCADED_LAYERS_TRANSITION\n              if (layer < 0 || (nextLayer >= 0 && i == nextLayer))\n            #else\n              if (layer < 0)\n            #endif\n            {\n              #if CC_CASCADED_LAYERS_TRANSITION\n                if (nextLayer < 0) {\n                  transitionArea = CCGetCSMLevelWithTransition(transitionRatio, clipPos);\n                }\n              #endif\n              csmPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\n              csmPos.xy = csmPos.xy * cc_csmAtlas[i].xy + cc_csmAtlas[i].zw;\n              shadowProjDepthInfo = cc_csmProjDepthInfo[i];\n              shadowProjInfo = cc_csmProjInfo[i];\n              shadowViewDir0 = cc_csmViewDir0[i].xyz;\n              shadowViewDir1 = cc_csmViewDir1[i].xyz;\n              shadowViewDir2 = cc_csmViewDir2[i].xyz;\n              layer = i;\n              #if CC_CASCADED_LAYERS_TRANSITION\n                hasNextTransition = true;\n              #endif\n            }\n          }\n        }\n        return layer;\n      }\n      int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos)\n      {\n        bool hasNextTransition = false;\n        bool transitionArea = false;\n        float transitionRatio = 0.0;\n        int nextLayer = -1;\n        return CCGetCSMLevel(hasNextTransition, transitionArea, transitionRatio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, nextLayer);\n      }\n      float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias)\n      {\n        bool hasNext = false;\n        bool transitionArea = false;\n        float ratio = 0.0;\n        csmPos = vec4(1.0);\n        vec4 shadowProjDepthInfo, shadowProjInfo;\n        vec3 shadowViewDir0, shadowViewDir1, shadowViewDir2;\n        int level = -1;\n        #if CC_CASCADED_LAYERS_TRANSITION\n          level = CCGetCSMLevel(hasNext, transitionArea, ratio, csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos, -1);\n        #else\n          level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, shadowViewDir0, shadowViewDir1, shadowViewDir2, worldPos);\n        #endif\n        if (level < 0) { return 1.0; }\n        vec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, shadowViewDir0, shadowViewDir1, shadowViewDir2, shadowProjInfo.xy);\n        pos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);\n        csmNDCPosWithBias = pos;\n        float realtimeShadow = 1.0;\n        #if CC_DIR_SHADOW_PCF_TYPE == 3\n          realtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 2\n          realtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 1\n          realtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n        #endif\n        #if CC_DIR_SHADOW_PCF_TYPE == 0\n          realtimeShadow = CCGetDirLightShadowFactorHard(pos);\n        #endif\n        #if CC_CASCADED_LAYERS_TRANSITION\n          vec4 nextCSMPos = vec4(1.0);\n          vec4 nextShadowProjDepthInfo, nextShadowProjInfo;\n          vec3 nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2;\n          float nextRealtimeShadow = 1.0;\n          CCGetCSMLevel(hasNext, transitionArea, ratio, nextCSMPos, nextShadowProjDepthInfo, nextShadowProjInfo, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, worldPos, level + 1);\n          if (hasNext && transitionArea) {\n            vec4 nexPos = ApplyShadowDepthBias_FaceNormal(nextCSMPos, N, shadowBias.y, nextShadowViewDir0, nextShadowViewDir1, nextShadowViewDir2, nextShadowProjInfo.xy);\n            nexPos = ApplyShadowDepthBias_Orthographic(nexPos, shadowBias.x, nextShadowProjDepthInfo.x, nextShadowProjDepthInfo.y);\n            #if CC_DIR_SHADOW_PCF_TYPE == 3\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft5X(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 2\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft3X(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 1\n              nextRealtimeShadow = CCGetDirLightShadowFactorSoft(nexPos);\n            #endif\n            #if CC_DIR_SHADOW_PCF_TYPE == 0\n              nextRealtimeShadow = CCGetDirLightShadowFactorHard(nexPos);\n            #endif\n            return mix(mix(nextRealtimeShadow, realtimeShadow, ratio), 1.0, cc_shadowNFLSInfo.w);\n          }\n          return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n        #else\n          return mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n        #endif\n      }\n    #else\n      int CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out vec3 shadowViewDir0, out vec3 shadowViewDir1, out vec3 shadowViewDir2, vec3 worldPos) {\n        return -1;\n      }\n      float CCCSMFactorBase(out vec4 csmPos, out vec4 csmNDCPosWithBias, vec3 worldPos, vec3 N, vec2 shadowBias) {\n        csmPos = cc_matLightViewProj * vec4(worldPos, 1.0);\n        return CCShadowFactorBase(csmNDCPosWithBias, csmPos, N, shadowBias);\n      }\n    #endif\n    float CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias) {\n      vec4 shadowNDCPosWithBias;\n      return CCShadowFactorBase(shadowNDCPosWithBias, shadowPos, N, shadowBias);\n    }\n    float CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias) {\n      vec4 csmPos, csmNDCPosWithBias;\n      return CCCSMFactorBase(csmPos, csmNDCPosWithBias, worldPos, N, shadowBias);\n    }\n    float CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n    {\n      vec4 shadowNDCPosWithBias;\n      return CCSpotShadowFactorBase(shadowNDCPosWithBias, shadowPos, worldPos, shadowBias);\n    }\n  #endif\n  vec3 unpackRGBE (vec4 rgbe) {\n    return rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n  }\n  vec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n      #ifdef GL_EXT_shader_texture_lod\n        return texture2DLodEXT(tex, coord, lod);\n      #else\n        return texture2D(tex, coord, lod);\n      #endif\n  }\n  vec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n      #ifdef GL_EXT_shader_texture_lod\n        return textureCubeLodEXT(tex, coord, lod);\n      #else\n        return textureCube(tex, coord, lod);\n      #endif\n  }\n  #if CC_USE_IBL\n    uniform samplerCube cc_environment;\n    #if CC_USE_DIFFUSEMAP\n      uniform samplerCube cc_diffuseMap;\n    #endif\n  #endif\n  #if CC_USE_REFLECTION_PROBE\n    uniform samplerCube cc_reflectionProbeCubemap;\n    uniform sampler2D cc_reflectionProbePlanarMap;\n  #endif\n  #if CC_USE_LIGHT_PROBE\n  #if CC_USE_LIGHT_PROBE\n    #if USE_INSTANCING\n      varying mediump vec4 v_sh_linear_const_r;\n      varying mediump vec4 v_sh_linear_const_g;\n      varying mediump vec4 v_sh_linear_const_b;\n    #else\n      uniform vec4 cc_sh_linear_const_r;\n  uniform vec4 cc_sh_linear_const_g;\n  uniform vec4 cc_sh_linear_const_b;\n  uniform vec4 cc_sh_quadratic_r;\n  uniform vec4 cc_sh_quadratic_g;\n  uniform vec4 cc_sh_quadratic_b;\n  uniform vec4 cc_sh_quadratic_a;\n    #endif\n    #if CC_USE_LIGHT_PROBE\n    vec3 SHEvaluate(vec3 normal)\n    {\n    #if USE_INSTANCING\n        vec3 result;\n        vec4 normal4 = vec4(normal, 1.0);\n        result.r = dot(v_sh_linear_const_r, normal4);\n        result.g = dot(v_sh_linear_const_g, normal4);\n        result.b = dot(v_sh_linear_const_b, normal4);\n        return result;\n    #else\n        vec3 result;\n        vec4 normal4 = vec4(normal, 1.0);\n        result.r = dot(cc_sh_linear_const_r, normal4);\n        result.g = dot(cc_sh_linear_const_g, normal4);\n        result.b = dot(cc_sh_linear_const_b, normal4);\n        vec4 n14 = normal.xyzz * normal.yzzx;\n        float n5 = normal.x * normal.x - normal.y * normal.y;\n        result.r += dot(cc_sh_quadratic_r, n14);\n        result.g += dot(cc_sh_quadratic_g, n14);\n        result.b += dot(cc_sh_quadratic_b, n14);\n        result += (cc_sh_quadratic_a.rgb * n5);\n        return result;\n    #endif\n    }\n    #endif\n  #endif\n  #endif\n  float GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\n    vec3 NxH = cross(N, H);\n    float OneMinusNoHSqr = dot(NxH, NxH);\n    float a = roughness * roughness;\n    float n = NoH * a;\n    float p = a / (OneMinusNoHSqr + n * n);\n    return p * p;\n  }\n  float CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\n    return (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n  }\n  vec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\n    const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\n    const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\n    vec4 r = roughness * c0 + c1;\n    float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\n    vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\n    AB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\n    return specular * AB.x + AB.y;\n  }\n  #if USE_REFLECTION_DENOISE\n    vec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity, vec2 screenUV) {\n      #if CC_USE_IBL\n      \tfloat mip = roughness * (mipCount - 1.0);\n      \tfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\n      \tfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\n        #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE\n          vec4 biased = fragTextureLod(cc_reflectionProbeCubemap, R, mip + mipBias);\n       \t  vec4 filtered = textureCube(cc_reflectionProbeCubemap, R);\n        #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR\n          vec4 biased = fragTextureLod(cc_reflectionProbePlanarMap, screenUV, mip + mipBias);\n          vec4 filtered = texture2D(cc_reflectionProbePlanarMap, screenUV);\n        #else\n          vec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\n       \t  vec4 filtered = textureCube(cc_environment, R);\n        #endif\n        #if CC_USE_IBL == 2 || CC_USE_REFLECTION_PROBE != REFLECTION_PROBE_TYPE_NONE\n          biased.rgb = unpackRGBE(biased);\n        \tfiltered.rgb = unpackRGBE(filtered);\n        #else\n        \tbiased.rgb = SRGBToLinear(biased.rgb);\n        \tfiltered.rgb = SRGBToLinear(filtered.rgb);\n        #endif\n        return mix(biased.rgb, filtered.rgb, denoiseIntensity);\n      #else\n        return vec3(0.0, 0.0, 0.0);\n      #endif\n    }\n  #endif\n  struct StandardSurface {\n    vec4 albedo;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        vec3 position, position_fract_part;\n        #else\n        vec3 position;\n        #endif\n    vec3 normal;\n    vec3 emissive;\n    vec4 lightmap;\n    float lightmap_test;\n    float roughness;\n    float metallic;\n    float occlusion;\n    float specularIntensity;\n    #if CC_RECEIVE_SHADOW\n      vec2 shadowBias;\n    #endif\n  };\n  vec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    vec3 L = normalize(-cc_mainLitDir.xyz);\n    float NL = max(dot(N, L), 0.0);\n    float shadow = 1.0;\n    #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == 2\n      if (NL > 0.0 && cc_mainLitDir.w > 0.0) {\n        if (cc_shadowLPNNInfo.w > 0.0) {\n          #if CC_DIR_LIGHT_SHADOW_TYPE == 2\n            shadow = CCCSMFactorBase(position, N, s.shadowBias);\n          #endif\n        } else {\n          #if CC_DIR_LIGHT_SHADOW_TYPE == 1\n            shadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n          #endif\n        }\n      }\n    #endif\n    vec3 finalColor = vec3(0.0);\n    #if CC_USE_LIGHTMAP && !CC_FORWARD_ADD\n      vec3 lightmap = s.lightmap.rgb;\n      #if CC_USE_HDR\n          lightmap.rgb *= cc_exposure.w * cc_exposure.x;\n      #endif\n      #if CC_USE_LIGHTMAP == LIGHT_MAP_TYPE_INDIRECT_OCCLUSION\n        shadow *= s.lightmap.a;\n        s.occlusion *= s.lightmap_test;\n        finalColor += diffuse * lightmap.rgb;\n      #else\n        finalColor += diffuse * lightmap.rgb * shadow;\n      #endif\n    #endif\n    #if CC_USE_LIGHTMAP != LIGHT_MAP_TYPE_ALL_IN_ONE\n      float NV = max(abs(dot(N, V)), 0.0);\n      specular = BRDFApprox(specular, s.roughness, NV);\n      vec3 H = normalize(L + V);\n      float NH = max(dot(N, H), 0.0);\n      vec3 lightingColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\n      vec3 diffuseContrib = diffuse / PI;\n      vec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\n      vec3 dirlightContrib = (diffuseContrib + specularContrib);\n      dirlightContrib *= shadow;\n      finalColor += lightingColor * dirlightContrib;\n    #endif\n    float fAmb = 0.5 - N.y * 0.5;\n    vec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n    vec3 env = vec3(0.0);\n    #if CC_USE_IBL\n      #if CC_USE_DIFFUSEMAP && !CC_USE_LIGHT_PROBE\n        vec4 diffuseMap = textureCube(cc_diffuseMap, N);\n        #if CC_USE_DIFFUSEMAP == 2\n          ambDiff = unpackRGBE(diffuseMap);\n        #else\n          ambDiff = SRGBToLinear(diffuseMap.rgb);\n        #endif\n      #endif\n      #if !CC_USE_REFLECTION_PROBE\n        vec3 R = normalize(reflect(-V, N));\n        vec3 rotationDir = RotationVecFromAxisY(R.xyz, cc_surfaceTransform.z, cc_surfaceTransform.w);\n        #if USE_REFLECTION_DENOISE && !CC_IBL_CONVOLUTED\n          env = GetEnvReflectionWithMipFiltering(rotationDir, s.roughness, cc_ambientGround.w, 0.6, vec2(0.0));\n        #else\n          vec4 envmap = fragTextureLod(cc_environment, rotationDir, s.roughness * (cc_ambientGround.w - 1.0));\n          #if CC_USE_IBL == 2\n            env = unpackRGBE(envmap);\n          #else\n            env = SRGBToLinear(envmap.rgb);\n            #endif\n        #endif\n      #endif\n    #endif\n    #if CC_USE_REFLECTION_PROBE\n      vec4 probe = vec4(0.0);\n      vec3 R = normalize(reflect(-V, N));\n      #if CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_CUBE\n        probe = fragTextureLod(cc_reflectionProbeCubemap, R, s.roughness * (cc_ambientGround.w - 1.0));\n      #elif CC_USE_REFLECTION_PROBE == REFLECTION_PROBE_TYPE_PLANAR\n        vec2 screenUV = GetPlanarReflectScreenUV(s.position, cc_matViewProj, cc_cameraPos.w, V, R);\n        probe = texture2D(cc_reflectionProbePlanarMap, screenUV);\n      #endif\n      env = unpackRGBE(probe);\n    #endif\n    finalColor += env * cc_ambientSky.w * specular * s.occlusion;\n  #if CC_USE_LIGHT_PROBE\n    finalColor += SHEvaluate(N) * diffuse * s.occlusion;\n  #endif\n    finalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\n    finalColor += s.emissive;\n    return vec4(finalColor, s.albedo.a);\n  }\n  #if CC_PIPELINE_TYPE == 0\n    #define LIGHTS_PER_PASS 1\n  #else\n    #define LIGHTS_PER_PASS 10\n  #endif\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\n  uniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\n  uniform vec4 cc_lightColor[LIGHTS_PER_PASS];\n  uniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\n  uniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n  #endif\n  float SmoothDistAtt (float distSqr, float invSqrAttRadius) {\n    float factor = distSqr * invSqrAttRadius;\n    float smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\n    return smoothFactor * smoothFactor;\n  }\n  float GetDistAtt (float distSqr, float invSqrAttRadius) {\n    float attenuation = 1.0 / max(distSqr, 0.01*0.01);\n    attenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\n    return attenuation;\n  }\n  float GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\n    float cd = dot(litDir, L);\n    float attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\n    return (attenuation * attenuation);\n  }\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\n  vec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\n    vec3 diffuseContrib = diffuse / PI;\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    float NV = max(abs(dot(N, V)), 0.0);\n    specular = BRDFApprox(specular, s.roughness, NV);\n    vec3 finalColor = vec3(0.0);\n    int numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\n    for (int i = 0; i < LIGHTS_PER_PASS; i++) {\n      if (i >= numLights) break;\n      vec3 SLU = cc_lightPos[i].xyz - position;\n      vec3 SL = normalize(SLU);\n      vec3 SH = normalize(SL + V);\n      float SNL = max(dot(N, SL), 0.0);\n      float SNH = max(dot(N, SH), 0.0);\n      float distSqr = dot(SLU, SLU);\n      float litRadius = cc_lightSizeRangeAngle[i].x;\n      float litRadiusSqr = litRadius * litRadius;\n      float illum = litRadiusSqr / max(litRadiusSqr, distSqr);\n      float attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\n      attRadiusSqrInv *= attRadiusSqrInv;\n      float att = GetDistAtt(distSqr, attRadiusSqrInv);\n      vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\n      if (cc_lightPos[i].w > 0.0) {\n        float cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\n        float cosOuter = cc_lightSizeRangeAngle[i].z;\n        float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\n        float litAngleOffset = -cosOuter * litAngleScale;\n        att *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n      }\n      vec3 lightColor = cc_lightColor[i].rgb;\n      float shadow = 1.0;\n      #if CC_RECEIVE_SHADOW  && CC_SHADOW_TYPE == 2\n        if (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\n          shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n        }\n      #endif\n      lightColor *= shadow;\n      finalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n    }\n    return vec4(finalColor, 0.0);\n  }\n  #endif\n  #if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\n  readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\n  readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\n  readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\n  struct CCLight\n  {\n    vec4 cc_lightPos;\n    vec4 cc_lightColor;\n    vec4 cc_lightSizeRangeAngle;\n    vec4 cc_lightDir;\n  };\n  struct Cluster\n  {\n    vec3 minBounds;\n    vec3 maxBounds;\n  };\n  struct LightGrid\n  {\n    uint offset;\n    uint ccLights;\n  };\n  CCLight getCCLight(uint i)\n  {\n    CCLight light;\n    light.cc_lightPos = b_ccLights[4u * i + 0u];\n    light.cc_lightColor = b_ccLights[4u * i + 1u];\n    light.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\n    light.cc_lightDir = b_ccLights[4u * i + 3u];\n    return light;\n  }\n  LightGrid getLightGrid(uint cluster)\n  {\n    uvec4 gridvec = b_clusterLightGrid[cluster];\n    LightGrid grid;\n    grid.offset = gridvec.x;\n    grid.ccLights = gridvec.y;\n    return grid;\n  }\n  uint getGridLightIndex(uint start, uint offset)\n  {\n    return b_clusterLightIndices[start + offset];\n  }\n  uint getClusterZIndex(vec4 worldPos)\n  {\n    float scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\n    float bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\n    float eyeDepth = -(cc_matView * worldPos).z;\n    uint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\n    return zIndex;\n  }\n  uint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n  {\n    uint zIndex = getClusterZIndex(worldPos);\n    float clusterSizeX = ceil(cc_viewPort.z / float(16));\n    float clusterSizeY = ceil(cc_viewPort.w / float(8));\n    uvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\n    uint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\n    return cluster;\n  }\n  vec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\n    vec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\n    vec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\n    vec3 diffuseContrib = diffuse / PI;\n    vec3 position;\n        #if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\n        position = unpackHighpData(s.position, s.position_fract_part);\n        #else\n        position = s.position;\n        #endif\n    vec3 N = normalize(s.normal);\n    vec3 V = normalize(cc_cameraPos.xyz - position);\n    float NV = max(abs(dot(N, V)), 0.001);\n    specular = BRDFApprox(specular, s.roughness, NV);\n    vec3 finalColor = vec3(0.0);\n    uint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\n    LightGrid grid = getLightGrid(cluster);\n    uint numLights = grid.ccLights;\n    for (uint i = 0u; i < 100u; i++) {\n      if (i >= numLights) break;\n      uint lightIndex = getGridLightIndex(grid.offset, i);\n      CCLight light = getCCLight(lightIndex);\n      vec3 SLU = light.cc_lightPos.xyz - position;\n      vec3 SL = normalize(SLU);\n      vec3 SH = normalize(SL + V);\n      float SNL = max(dot(N, SL), 0.001);\n      float SNH = max(dot(N, SH), 0.0);\n      float distSqr = dot(SLU, SLU);\n      float litRadius = light.cc_lightSizeRangeAngle.x;\n      float litRadiusSqr = litRadius * litRadius;\n      float illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\n      float attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\n      attRadiusSqrInv *= attRadiusSqrInv;\n      float att = GetDistAtt(distSqr, attRadiusSqrInv);\n      vec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\n      if (light.cc_lightPos.w > 0.0) {\n        float cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\n        float cosOuter = light.cc_lightSizeRangeAngle.z;\n        float litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\n        float litAngleOffset = -cosOuter * litAngleScale;\n        att *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n      }\n      vec3 lightColor = light.cc_lightColor.rgb;\n      float shadow = 1.0;\n      #if CC_RECEIVE_SHADOW && CC_SHADOW_TYPE == 2\n        if (light.cc_lightPos.w > 0.0) {\n          shadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n        }\n      #endif\n      lightColor *= shadow;\n      finalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n    }\n    return vec4(finalColor, 0.0);\n  }\n  #endif\n  vec3 ACESToneMap (vec3 color) {\n    color = min(color, vec3(8.0));\n    const float A = 2.51;\n    const float B = 0.03;\n    const float C = 2.43;\n    const float D = 0.59;\n    const float E = 0.14;\n    return (color * (A * color + B)) / (color * (C * color + D) + E);\n  }\n  vec4 CCFragOutput (vec4 color) {\n    #if !CC_USE_RGBE_OUTPUT\n      #if CC_USE_HDR\n        color.rgb = ACESToneMap(color.rgb);\n      #endif\n      color.rgb = LinearToSRGB(color.rgb);\n    #endif\n    return color;\n  }\n  #if CC_USE_FOG != 4\n    float LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\n        vec4 wPos = pos;\n        float cam_dis = distance(cameraPos, wPos.xyz);\n        return clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n    }\n    float ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\n        vec4 wPos = pos;\n        float cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\n        float f = exp(-cam_dis * fogDensity);\n        return f;\n    }\n    float ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\n        vec4 wPos = pos;\n        float cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\n        float f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\n        return f;\n    }\n    float LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\n        vec4 wPos = pos;\n        vec3 camWorldProj = cameraPos.xyz;\n        camWorldProj.y = 0.;\n        vec3 worldPosProj = wPos.xyz;\n        worldPosProj.y = 0.;\n        float fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\n        float fDeltaY, fDensityIntegral;\n        if (cameraPos.y > fogTop) {\n            if (wPos.y < fogTop) {\n                fDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\n                fDensityIntegral = fDeltaY * fDeltaY * 0.5;\n            }\n            else {\n                fDeltaY = 0.;\n                fDensityIntegral = 0.;\n            }\n        }\n        else {\n            if (wPos.y < fogTop) {\n                float fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\n                float fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\n                fDeltaY = abs(fDeltaA - fDeltaB);\n                fDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n            }\n            else {\n                fDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\n                fDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n            }\n        }\n        float fDensity;\n        if (fDeltaY != 0.) {\n            fDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n        }\n        else {\n            fDensity = 0.;\n        }\n        float f = exp(-fDensity);\n        return f;\n    }\n  #endif\n  void CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n  {\n  #if CC_USE_FOG == 0\n  \tfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n  #elif CC_USE_FOG == 1\n  \tfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n  #elif CC_USE_FOG == 2\n  \tfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n  #elif CC_USE_FOG == 3\n  \tfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n  #else\n  \tfactor = 1.0;\n  #endif\n  }\n  void CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\n  \tcolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n  }\n  vec2 signNotZero(vec2 v) {\n    return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n  }\n  vec3 oct_to_float32x3(vec2 e) {\n    vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\n    if (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\n    return normalize(v);\n  }\n  varying vec2 v_uv;\n  uniform sampler2D gbuffer_albedoMap;\n  uniform sampler2D gbuffer_normalMap;\n  uniform sampler2D gbuffer_emissiveMap;\n  uniform sampler2D depth_stencil;\n  vec4 screen2WS(vec3 coord) {\n    vec3 ndc = vec3(\n      2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n      2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n      2.0 * coord.z - 1.0);\n    return GetWorldPosFromNDCPosRH(ndc, cc_matProj, cc_matViewProjInv);\n  }\n  void main () {\n    StandardSurface s;\n    vec4 albedoMap = texture2D(gbuffer_albedoMap,v_uv);\n    vec4 normalMap = texture2D(gbuffer_normalMap,v_uv);\n    vec4 emissiveMap = texture2D(gbuffer_emissiveMap,v_uv);\n    float depth = texture2D(depth_stencil, v_uv).x;\n    s.albedo = albedoMap;\n    vec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\n    s.position = position;\n    s.roughness = normalMap.z;\n    s.normal = oct_to_float32x3(normalMap.xy);\n    s.specularIntensity = 0.5;\n    s.metallic = normalMap.w;\n    s.emissive = emissiveMap.xyz;\n    s.occlusion = emissiveMap.w;\n    float fogFactor;\n    CC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\n    vec4 shadowPos;\n    shadowPos = cc_matLightViewProj * vec4(position, 1);\n    vec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\n                 CCClusterShadingAdditive(s, shadowPos);\n#else\n                 CCStandardShadingAdditive(s, shadowPos);\n#endif\n    CC_APPLY_FOG_BASE(color, fogFactor);\n    color = CCFragOutput(color);\n    gl_FragColor = color;\n  }"
      },
      "builtins": {
        "globals": {
          "blocks": [
            {
              "name": "CCGlobal",
              "defines": []
            },
            {
              "name": "CCCamera",
              "defines": []
            },
            {
              "name": "CCShadow",
              "defines": []
            },
            {
              "name": "CCCSM",
              "defines": [
                "CC_SUPPORT_CASCADED_SHADOW_MAP"
              ]
            }
          ],
          "samplerTextures": [
            {
              "name": "cc_shadowMap",
              "defines": [
                "CC_RECEIVE_SHADOW"
              ]
            },
            {
              "name": "cc_spotShadowMap",
              "defines": [
                "CC_RECEIVE_SHADOW"
              ]
            },
            {
              "name": "cc_environment",
              "defines": [
                "CC_USE_IBL"
              ]
            },
            {
              "name": "cc_diffuseMap",
              "defines": [
                "CC_USE_IBL",
                "CC_USE_DIFFUSEMAP"
              ]
            }
          ],
          "buffers": [],
          "images": []
        },
        "locals": {
          "blocks": [
            {
              "name": "CCSH",
              "defines": [
                "CC_USE_LIGHT_PROBE",
                "!USE_INSTANCING"
              ]
            },
            {
              "name": "CCForwardLight",
              "defines": [
                "CC_ENABLE_CLUSTERED_LIGHT_CULLING"
              ]
            }
          ],
          "samplerTextures": [
            {
              "name": "cc_reflectionProbeCubemap",
              "defines": [
                "CC_USE_REFLECTION_PROBE"
              ]
            },
            {
              "name": "cc_reflectionProbePlanarMap",
              "defines": [
                "CC_USE_REFLECTION_PROBE"
              ]
            }
          ],
          "buffers": [],
          "images": []
        },
        "statistics": {
          "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 44,
          "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 108
        }
      },
      "defines": [
        {
          "name": "USE_INSTANCING",
          "type": "boolean",
          "defines": [],
          "editor": {
            "elevated": true
          }
        },
        {
          "name": "CC_USE_SKINNING",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_BAKED_ANIMATION",
          "type": "boolean",
          "defines": [
            "USE_INSTANCING"
          ]
        },
        {
          "name": "CC_USE_LIGHTMAP",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_RECEIVE_SHADOW",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_LIGHT_PROBE",
          "type": "boolean",
          "defines": [],
          "default": 0
        },
        {
          "name": "CC_USE_MORPH",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_DEBUG_VIEW",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_SUPPORT_CASCADED_SHADOW_MAP",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_SHADOWMAP_FORMAT",
          "type": "number",
          "defines": [
            "CC_RECEIVE_SHADOW"
          ],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_SHADOWMAP_USE_LINEAR_DEPTH",
          "type": "boolean",
          "defines": [
            "CC_RECEIVE_SHADOW"
          ]
        },
        {
          "name": "CC_DIR_SHADOW_PCF_TYPE",
          "type": "number",
          "defines": [
            "CC_RECEIVE_SHADOW"
          ],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_CASCADED_LAYERS_TRANSITION",
          "type": "boolean",
          "defines": [
            "CC_RECEIVE_SHADOW",
            "CC_SUPPORT_CASCADED_SHADOW_MAP"
          ]
        },
        {
          "name": "CC_USE_IBL",
          "type": "number",
          "defines": [],
          "range": [
            0,
            2
          ]
        },
        {
          "name": "CC_USE_DIFFUSEMAP",
          "type": "number",
          "defines": [
            "CC_USE_IBL"
          ],
          "range": [
            0,
            2
          ]
        },
        {
          "name": "CC_USE_REFLECTION_PROBE",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "USE_REFLECTION_DENOISE",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_SHADOW_TYPE",
          "type": "number",
          "defines": [
            "CC_RECEIVE_SHADOW"
          ],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_DIR_LIGHT_SHADOW_TYPE",
          "type": "number",
          "defines": [
            "CC_RECEIVE_SHADOW",
            "CC_SHADOW_TYPE"
          ],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_FORWARD_ADD",
          "type": "boolean",
          "defines": [
            "CC_USE_LIGHTMAP"
          ]
        },
        {
          "name": "CC_USE_HDR",
          "type": "boolean",
          "defines": [
            "!CC_USE_RGBE_OUTPUT"
          ]
        },
        {
          "name": "CC_IBL_CONVOLUTED",
          "type": "boolean",
          "defines": [
            "USE_REFLECTION_DENOISE",
            "CC_USE_IBL",
            "!CC_USE_REFLECTION_PROBE"
          ]
        },
        {
          "name": "CC_PIPELINE_TYPE",
          "type": "number",
          "defines": [],
          "range": [
            0,
            1
          ]
        },
        {
          "name": "CC_FORCE_FORWARD_SHADING",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_RGBE_OUTPUT",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_FOG",
          "type": "number",
          "defines": [],
          "range": [
            0,
            4
          ]
        }
      ],
      "name": "pipeline/deferred-lighting|lighting-vs|lighting-fs"
    }
  ],
  "combinations": [],
  "hideInEditor": false
}