{
  "__type__": "cc.EffectAsset",
  "_name": "builtin-phong",
  "_objFlags": 0,
  "_native": "",
  "properties": null,
  "techniques": [
    {
      "passes": [
        {
          "rasterizerState": {
            "cullMode": 1029
          },
          "program": "builtin-phong|phong-vs|phong-fs",
          "depthStencilState": {
            "depthTest": true,
            "depthWrite": true
          },
          "properties": {
            "alphaThreshold": {
              "value": [
                0.5
              ],
              "type": 13
            },
            "mainTiling": {
              "value": [
                1,
                1
              ],
              "type": 14
            },
            "mainOffset": {
              "value": [
                0,
                0
              ],
              "type": 14
            },
            "diffuseColor": {
              "value": [
                1,
                1,
                1,
                1
              ],
              "inspector": {
                "type": "color"
              },
              "type": 16
            },
            "diffuseTexture": {
              "value": "white",
              "type": 29
            },
            "specularColor": {
              "value": [
                1,
                1,
                1,
                1
              ],
              "inspector": {
                "type": "color"
              },
              "type": 16
            },
            "specularTexture": {
              "value": "white",
              "type": 29
            },
            "emissiveColor": {
              "value": [
                0,
                0,
                0,
                1
              ],
              "inspector": {
                "type": "color"
              },
              "type": 16
            },
            "emissiveTexture": {
              "value": "white",
              "type": 29
            },
            "glossiness": {
              "value": [
                10
              ],
              "type": 13
            },
            "normalTexture": {
              "value": "white",
              "type": 29
            }
          }
        }
      ]
    },
    {
      "stages": [
        "shadowcast"
      ],
      "passes": [
        {
          "rasterizerState": {
            "cullMode": 1029
          },
          "program": "builtin-phong|shadow-map-vs|shadow-map-fs",
          "depthStencilState": {
            "depthTest": true,
            "depthWrite": true
          }
        }
      ]
    }
  ],
  "shaders": [
    {
      "hash": 1292388708,
      "glsl3": {
        "vert": "\nprecision highp float;\nuniform CCLocal {\n  mat4 cc_matWorld;\n  mat4 cc_matWorldIT;\n};\nuniform CCGlobal {\n  vec4 cc_time;\n\n  vec4 cc_screenSize;\n\n  vec4 cc_screenScale;\n\n  vec4 cc_nativeSize;\n\n  mat4 cc_matView;\n  mat4 cc_matViewInv;\n  mat4 cc_matProj;\n  mat4 cc_matProjInv;\n  mat4 cc_matViewProj;\n  mat4 cc_matViewProjInv;\n  vec4 cc_cameraPos;\n\n  vec4 cc_exposure;\n\n  vec4 cc_mainLitDir;\n\n  vec4 cc_mainLitColor;\n\n  vec4 cc_ambientSky;\n  vec4 cc_ambientGround;\n};\n\nstruct StandardAttributes {\n  vec2 uv;\n  vec4 position;\n  vec3 normal;\n  vec4 tangent;\n  vec4 color;\n};\n\nin vec3 a_position;\n\n#if CC_USE_ATTRIBUTE_UV0\nin vec2 a_uv0;\n#endif\n\n#if CC_USE_ATTRIBUTE_COLOR\nin vec4 a_color;\n#endif\n\n#if CC_USE_ATTRIBUTE_NORMAL\nin vec3 a_normal;\n#endif\n\n#if CC_USE_ATTRIBUTE_TANGENT\nin vec4 a_tangent;\n#endif\n\nvoid CCAttribute (out StandardAttributes attr) {\n  attr.position = vec4(a_position, 1.0);\n\n  #if CC_USE_ATTRIBUTE_UV0\n    attr.uv = a_uv0;\n  #else\n    attr.uv = vec2(0.0);\n  #endif\n  \n  #if CC_USE_ATTRIBUTE_COLOR\n    attr.color = a_color;\n  #else\n    attr.color = vec4(1.0);\n  #endif\n  \n  #if CC_USE_ATTRIBUTE_NORMAL\n    attr.normal = a_normal;\n  #else\n    attr.normal = vec3(0.0, 1.0, 0.0);\n  #endif\n\n  #if CC_USE_ATTRIBUTE_TANGENT\n    attr.tangent = a_tangent;\n  #else\n    attr.tangent = vec4(1.0, 0.0, 0.0, 0.0);\n  #endif\n}\n\n#if CC_USE_SKINNING\n\n#if CC_USE_SKINNING\n\n  in vec4 a_weights;\n  in vec4 a_joints;\n\n  #if CC_USE_JOINTS_TEXTRUE\n    uniform SKINNING {\n      vec2 cc_jointsTextureSize;\n    }\n    uniform sampler2D cc_jointsTexture;\n\n    #if CC_JOINTS_TEXTURE_FLOAT32\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 4.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y));\n        vec4 v2 = texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y));\n        vec4 v3 = texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y));\n        vec4 v4 = texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y));\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #else\n      float decode32(vec4 rgba) {\n        float Sign = 1.0 - step(128.0, rgba[0]) * 2.0;\n        float Exponent = 2.0 * mod(rgba[0], 128.0) + step(128.0, rgba[1]) - 127.0;\n        float Mantissa = mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + 8388608.0;\n        return Sign * exp2(Exponent - 23.0) * Mantissa;\n      }\n      vec4 decodevec4 (vec4 x, vec4 y, vec4 z, vec4 w) {\n\n        return vec4(\n          decode32(x.wzyx * 255.0),\n          decode32(y.wzyx * 255.0),\n          decode32(z.wzyx * 255.0),\n          decode32(w.wzyx * 255.0)\n        );\n      }\n\n      vec4 decodevec4 (float dx, float x, float y) {\n        return decodevec4(\n          texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y))\n        );\n      }\n\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 16.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = decodevec4(dx, x,       y);\n        vec4 v2 = decodevec4(dx, x+4.0,   y);\n        vec4 v3 = decodevec4(dx, x+8.0,   y);\n        vec4 v4 = decodevec4(dx, x+12.0,  y);\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #endif\n  #else\n    uniform CC_JOINT_MATRIX {\n      mat4 cc_jointMatrices[50];\n    }\n\n    mat4 getBoneMatrix(const in float i) {\n      return cc_jointMatrices[int(i)];\n    }\n  #endif\n\n    mat4 skinMatrix() {\n      return\n        getBoneMatrix(a_joints.x) * a_weights.x +\n        getBoneMatrix(a_joints.y) * a_weights.y +\n        getBoneMatrix(a_joints.z) * a_weights.z +\n        getBoneMatrix(a_joints.w) * a_weights.w\n        ;\n    }\n#endif\n\nvoid SKIN_VERTEX(inout vec4 a1) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2, inout vec4 a3) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n    a3 = m * a3;\n  #endif\n}\n\n  void CCSkin(inout StandardAttributes attr) {\n    mat4 m = skinMatrix();\n    attr.position = m * attr.position;\n    attr.normal = (m * vec4(attr.normal, 0)).xyz;\n    attr.tangent = m * attr.tangent;\n  }\n#endif\n\nstruct StandardVertInput {\n  vec2 uv;\n  vec4 position;\n  vec3 normal;\n  vec4 tangent;\n  vec4 color;\n};\n\nvoid CCAttrToInput (in StandardAttributes attr, out StandardVertInput In) {\n  In.position = attr.position;\n  In.normal = attr.normal;\n  In.tangent = attr.tangent;\n  In.uv = attr.uv;\n  In.color = attr.color;\n}\n\nvoid CCVertInput (out StandardVertInput In) {\n  StandardAttributes attr;\n  CCAttribute(attr);\n  #if CC_USE_SKINNING\n    CCSkin(attr);\n  #endif\n  CCAttrToInput(attr, In);\n}\n\n#if CC_USE_SHADOW_MAP \n  uniform CC_SHADOW {\n    mat4 cc_shadow_lightViewProjMatrix[2];\n    vec4 cc_shadow_info[2];\n\n  };\n  uniform sampler2D cc_shadow_map[2];\n\n  varying vec4 v_posLightSpace[2];\n  varying float v_depth[2];\n#endif\n\n#if 1\n\n  void CLAC_SHADOW (vec3 worldPos) {\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n      v_posLightSpace[i] = cc_shadow_lightViewProjMatrix[i] * vec4(worldPos, 1.0);\n      v_depth[i] = (v_posLightSpace[i].z + cc_shadow_info[i].x) / (cc_shadow_info[i].x + cc_shadow_info[i].y);\n    }\n    #endif\n  }\n\n#else\n\nvec4 packDepthToRGBA(float depth) {\n  vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n  ret = fract(ret);\n  ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n  return ret;\n}\n\nfloat unpackRGBAToDepth(vec4 color) {\n  return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));\n}\n\n  float computeFallOff(float esm, vec2 coords, float frustumEdgeFalloff) {\n    float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.0, clamp(dot(coords, coords), 0.0, 1.0));\n    return mix(esm, 1.0, mask);\n  }\n\n  float computeShadowESM(sampler2D shadowMap, vec4 pos_lightspace, float vDepth, float depthScale, float darkness, float frustumEdgeFalloff) {\n    vec2 projCoords = pos_lightspace.xy / pos_lightspace.w;\n    vec2 shadowUV = projCoords * 0.5 + vec2(0.5);\n    if (shadowUV.x < 0.0 || shadowUV.x > 1.0 || shadowUV.y < 0.0 || shadowUV.y > 1.0) {\n      return 1.0;\n    }\n    float currentDepth = clamp(vDepth, 0.0, 1.0);\n    float closestDepth = unpackRGBAToDepth(texture2D(shadowMap, shadowUV));\n\n    float esm = clamp(exp(-depthScale * (currentDepth - closestDepth)), 1.0 - darkness, 1.0);\n    return computeFallOff(esm, projCoords, frustumEdgeFalloff);\n  }\n\n  float computeShadow() {\n    float shadow = 1.0;\n    float frustumEdgeFalloff = 0.0;\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n        shadow *= computeShadowESM(cc_shadow_map[i], v_posLightSpace[i], v_depth[i], cc_shadow_info[i].z, cc_shadow_info[i].w, frustumEdgeFalloff);\n    }\n    #endif\n    return shadow;\n  }\n\n#endif\n\nuniform MAIN_TILING {\n  vec2 mainTiling;\n  vec2 mainOffset;\n}\n\nout mediump vec2 v_uv0;\nout lowp vec4 v_color;\nout vec3 v_worldNormal;\nout vec3 v_worldPos;\n\nvoid main () {\n  StandardVertInput In;\n  CCVertInput(In);\n\n  vec4 position = In.position;\n  vec4 normal = vec4(In.normal, 0);\n\n  v_worldPos = (cc_matWorld * position).xyz;\n  v_worldNormal = (cc_matWorldIT * normal).xyz;\n  v_color = In.color;\n  v_uv0 = In.uv * mainTiling + mainOffset;\n\n  CLAC_SHADOW(v_worldPos);\n  \n  gl_Position = cc_matViewProj * cc_matWorld * position;\n}\n",
        "frag": "\nprecision highp float;\nuniform CCGlobal {\n  vec4 cc_time;\n\n  vec4 cc_screenSize;\n\n  vec4 cc_screenScale;\n\n  vec4 cc_nativeSize;\n\n  mat4 cc_matView;\n  mat4 cc_matViewInv;\n  mat4 cc_matProj;\n  mat4 cc_matProjInv;\n  mat4 cc_matViewProj;\n  mat4 cc_matViewProjInv;\n  vec4 cc_cameraPos;\n\n  vec4 cc_exposure;\n\n  vec4 cc_mainLitDir;\n\n  vec4 cc_mainLitColor;\n\n  vec4 cc_ambientSky;\n  vec4 cc_ambientGround;\n};\n\nvec3 SRGBToLinear(vec3 gamma)\n{\n\treturn pow(gamma, vec3(2.2));\n\n}\n\nvec3 LinearToSRGB(vec3 linear)\n{\n\treturn pow(linear, vec3(0.454545));\n\n}\n\nvec4 TEXEL_TO_LINEAR (in vec4 color) {\n  #if INPUT_IS_GAMMA\n    return vec4(SRGBToLinear(color.rgb), color.a);\n  #else\n    return color;\n  #endif\n}\n\nvec4 LINEAR_TO_OUTPUT_TEXEL (in vec4 color) {\n  #if OUTPUT_TO_GAMMA\n    return vec4(LinearToSRGB(color.rgb), color.a);\n  #else\n    return color;\n  #endif\n}\n\n#define saturate(a) clamp( a, 0.0, 1.0 )\n\nmat4 transposeMat4(in mat4 mat) {\n    vec4 i0 = mat[0];\n    vec4 i1 = mat[1];\n    vec4 i2 = mat[2];\n    vec4 i3 = mat[3];\n    return mat4(vec4(i0.x, i1.x, i2.x, i3.x),\n                vec4(i0.y, i1.y, i2.y, i3.y),\n                vec4(i0.z, i1.z, i2.z, i3.z),\n                vec4(i0.w, i1.w, i2.w, i3.w));\n}\n\n#if USE_NORMAL_TEXTURE\n\n  uniform sampler2D normalTexture;\n\n#endif\n\nvoid CALC_NORMAL (inout vec3 normal, in vec3 worldPos, in vec2 uv) {\n  #if USE_NORMAL_TEXTURE\n\n  #endif\n}\n\nuniform DIFFUSE {\n  lowp vec4 diffuseColor;\n};\n\n#if USE_DIFFUSE_TEXTURE\n  uniform sampler2D diffuseTexture;\n#endif\n\nvoid MULTIPLY_DIFFUSE_TEXTRUE_COLOR (inout vec4 color, in vec2 uv) {\n  #if USE_DIFFUSE_TEXTURE && CC_USE_ATTRIBUTE_UV0\n    vec4 diffuseTextureColor = texture2D(diffuseTexture, uv);\n    #if CC_USE_ALPHA_ATLAS_DIFFUSETEXTURE\n      diffuseTextureColor.a *= texture2D(diffuseTexture, uv + vec2(0, 0.5)).r;\n    #endif\n    color *= TEXEL_TO_LINEAR(diffuseTextureColor);\n  #endif\n}\n\nvoid CALC_DIFFUSE (inout vec4 color, in vec2 uv) {\n  color *= diffuseColor;\n  MULTIPLY_DIFFUSE_TEXTRUE_COLOR(color, uv);\n}\n\nvoid CALC_DIFFUSE (inout vec4 color) {\n  color *= diffuseColor;\n}\n\n#if USE_SPECULAR\n  uniform SPECULAR {\n    lowp vec4 specularColor;\n  };\n\n  #if USE_SPECULAR_TEXTURE\n    uniform sampler2D specularTexture;\n  #endif\n\n#endif\n\nvoid MULTIPLY_SPECULAR_TEXTRUE_COLOR (inout vec3 color, in vec2 uv) {\n  #if USE_SPECULAR_TEXTURE && CC_USE_ATTRIBUTE_UV0\n    vec4 specularTextureColor = texture2D(specularTexture, uv);\n    specularTextureColor = TEXEL_TO_LINEAR(specularTextureColor);\n    color *= specularTextureColor.rgb;\n  #endif\n}\n\nvoid CALC_SPECULAR (inout vec3 specular, in vec2 uv) {\n  #if USE_SPECULAR\n    specular = specularColor.xyz;\n    MULTIPLY_SPECULAR_TEXTRUE_COLOR(specular, uv);\n  #endif\n}\n\nvoid CALC_SPECULAR (inout vec3 specular) {\n  #if USE_SPECULAR\n    specular = specularColor.xyz;\n  #endif\n}\n\n#if USE_EMISSIVE\n  uniform EMISSIVE {\n    lowp vec4 emissiveColor;\n  };\n\n  #if USE_EMISSIVE_TEXTURE\n    uniform sampler2D emissiveTexture;\n  #endif\n\n#endif\n\nvoid MULTIPLY_EMISSIVE_TEXTRUE_COLOR (inout vec3 color, in vec2 uv) {\n  #if USE_EMISSIVE_TEXTURE && CC_USE_ATTRIBUTE_UV0\n    vec4 emissiveTextureColor = texture2D(emissiveTexture, uv);\n    #if CC_USE_ALPHA_ATLAS_EMISSIVETEXTURE\n      emissiveTextureColor.a *= texture2D(emissiveTexture, uv + vec2(0, 0.5)).r;\n    #endif\n    emissiveTextureColor = TEXEL_TO_LINEAR(emissiveTextureColor);\n    color *= emissiveTextureColor.rgb;\n  #endif\n}\n\nvoid CALC_EMISSIVE (inout vec3 emissive, in vec2 uv) {\n  #if USE_EMISSIVE\n    emissive = emissiveColor.xyz;\n    MULTIPLY_EMISSIVE_TEXTRUE_COLOR(emissive, uv);\n  #endif\n}\n\nvoid CALC_EMISSIVE (inout vec3 emissive) {\n  #if USE_EMISSIVE\n    emissive = emissiveColor.xyz;\n  #endif\n}\n\n#if USE_ALPHA_TEST\n  \n  uniform ALPHA_TEST {\n    float alphaThreshold;\n  }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n  #if USE_ALPHA_TEST\n      if (color.a < alphaThreshold) discard;\n  #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n  #if USE_ALPHA_TEST\n      if (alpha < alphaThreshold) discard;\n  #endif\n}\n\nin vec3 v_worldNormal;\nin vec3 v_worldPos;\nin mediump vec2 v_uv0;\nin lowp vec4 v_color;\n\n#if CC_NUM_DIR_LIGHTS > 0 || CC_NUM_POINT_LIGHTS > 0 || CC_NUM_SPOT_LIGHTS > 0 || CC_NUM_AMBIENT_LIGHTS > 0\nuniform CCLIGHTS {\n  vec4 cc_dirLightDirection[4];\n\n  vec4 cc_dirLightColor[4];\n\n  vec4 cc_pointLightPositionAndRange[4];\n\n  vec4 cc_pointLightColor[4];\n\n  vec4 cc_spotLightPositionAndRange[4];\n\n  vec4 cc_spotLightDirection[4];\n\n  vec4 cc_spotLightColor[4];\n\n  vec4 cc_ambientColor[4];\n\n};\n\n#endif\n\nstruct LightInfo {\n  vec3 lightDir;\n  vec3 radiance;\n};\n\nLightInfo computeDirectionalLighting(\n  vec4 lightDirection,\n  vec4 lightColor\n) {\n  LightInfo ret;\n  ret.lightDir = -normalize(lightDirection.xyz);\n  ret.radiance = lightColor.rgb;\n  return ret;\n}\n\nLightInfo computePointLighting(\n  vec3 worldPosition,\n  vec4 lightPositionAndRange,\n  vec4 lightColor\n) {\n  LightInfo ret;\n  vec3 lightDir = lightPositionAndRange.xyz - worldPosition;\n  float attenuation = max(0., 1.0 - length(lightDir) / lightPositionAndRange.w);\n  \n  ret.lightDir = normalize(lightDir);\n  ret.radiance = lightColor.rgb * attenuation;\n  return ret;\n}\n\nLightInfo computeSpotLighting(\n  vec3 worldPosition,\n  vec4 lightPositionAndRange,\n  vec4 lightDirection,\n  vec4 lightColor\n) {\n  LightInfo ret;\n  vec3 lightDir = lightPositionAndRange.xyz - worldPosition;\n  float attenuation = max(0., 1.0 - length(lightDir) / lightPositionAndRange.w);\n  lightDir = normalize(lightDir);\n  float cosConeAngle = max(0., dot(lightDirection.xyz, -lightDir));\n  cosConeAngle = cosConeAngle < lightDirection.w ? 0. : cosConeAngle;\n  cosConeAngle = pow(cosConeAngle, lightColor.w);\n  \n  ret.lightDir = lightDir;\n  ret.radiance = lightColor.rgb * attenuation * cosConeAngle;\n  return ret;\n}\n\n#if CC_USE_SHADOW_MAP \n  uniform CC_SHADOW {\n    mat4 cc_shadow_lightViewProjMatrix[2];\n    vec4 cc_shadow_info[2];\n\n  };\n  uniform sampler2D cc_shadow_map[2];\n\n  varying vec4 v_posLightSpace[2];\n  varying float v_depth[2];\n#endif\n\n#if 0\n\n  void CLAC_SHADOW (vec3 worldPos) {\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n      v_posLightSpace[i] = cc_shadow_lightViewProjMatrix[i] * vec4(worldPos, 1.0);\n      v_depth[i] = (v_posLightSpace[i].z + cc_shadow_info[i].x) / (cc_shadow_info[i].x + cc_shadow_info[i].y);\n    }\n    #endif\n  }\n\n#else\n\nvec4 packDepthToRGBA(float depth) {\n  vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n  ret = fract(ret);\n  ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n  return ret;\n}\n\nfloat unpackRGBAToDepth(vec4 color) {\n  return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));\n}\n\n  float computeFallOff(float esm, vec2 coords, float frustumEdgeFalloff) {\n    float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.0, clamp(dot(coords, coords), 0.0, 1.0));\n    return mix(esm, 1.0, mask);\n  }\n\n  float computeShadowESM(sampler2D shadowMap, vec4 pos_lightspace, float vDepth, float depthScale, float darkness, float frustumEdgeFalloff) {\n    vec2 projCoords = pos_lightspace.xy / pos_lightspace.w;\n    vec2 shadowUV = projCoords * 0.5 + vec2(0.5);\n    if (shadowUV.x < 0.0 || shadowUV.x > 1.0 || shadowUV.y < 0.0 || shadowUV.y > 1.0) {\n      return 1.0;\n    }\n    float currentDepth = clamp(vDepth, 0.0, 1.0);\n    float closestDepth = unpackRGBAToDepth(texture2D(shadowMap, shadowUV));\n\n    float esm = clamp(exp(-depthScale * (currentDepth - closestDepth)), 1.0 - darkness, 1.0);\n    return computeFallOff(esm, projCoords, frustumEdgeFalloff);\n  }\n\n  float computeShadow() {\n    float shadow = 1.0;\n    float frustumEdgeFalloff = 0.0;\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n        shadow *= computeShadowESM(cc_shadow_map[i], v_posLightSpace[i], v_depth[i], cc_shadow_info[i].z, cc_shadow_info[i].w, frustumEdgeFalloff);\n    }\n    #endif\n    return shadow;\n  }\n\n#endif\n\nuniform PHONG {\n  float glossiness;\n}\n\nstruct PhongMaterial {\n  vec3 diffuse;\n  vec3 emissive;\n  vec3 specular;\n  float opacity;\n};\n\nstruct Lighting {\n  vec3 diffuse;\n  vec3 specular;\n};\n\nvoid brdf (inout Lighting result, LightInfo info, vec3 normal, vec3 viewDirection, float glossiness) {\n  float ndh = 0.0;\n\n  vec3 halfDir = normalize(viewDirection + info.lightDir);\n  float NdotH = max(0.0, dot(normal, halfDir));\n  NdotH = pow(NdotH, max(1.0, glossiness * 128.0));\n\n  vec3 diffuse = info.radiance * max(0.0, dot(normal, info.lightDir));\n  vec3 specular = info.radiance * NdotH;\n\n  result.diffuse += diffuse;\n  result.specular += specular;\n}\n\nLighting getPhongLighting (vec3 normal, vec3 worldPos, vec3 viewDirection, float glossiness) {\n  Lighting result;\n  result.diffuse = vec3(0, 0, 0);\n  result.specular = vec3(0, 0, 0);\n\n  #if CC_NUM_DIR_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_DIR_LIGHTS; i++) {\n      LightInfo info = computeDirectionalLighting(cc_dirLightDirection[i], cc_dirLightColor[i]);\n      brdf(result, info, normal, viewDirection, glossiness);\n    }\n  #endif\n\n  #if CC_NUM_POINT_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_POINT_LIGHTS; i++) {\n      LightInfo info = computePointLighting(worldPos, cc_pointLightPositionAndRange[i], cc_pointLightColor[i]);\n      brdf(result, info, normal, viewDirection, glossiness);\n    }\n  #endif\n\n  #if CC_NUM_SPOT_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_SPOT_LIGHTS; i++) {\n      LightInfo info = computeSpotLighting(worldPos, cc_spotLightPositionAndRange[i], cc_spotLightDirection[i], cc_spotLightColor[i]);\n      brdf(result, info, normal, viewDirection, glossiness);\n    }\n  #endif\n\n  #if CC_NUM_AMBIENT_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_AMBIENT_LIGHTS; i++) {\n      result.diffuse += cc_ambientColor[i].rgb;\n    }\n  #endif\n\n  return result;\n}\n\nvec4 composePhongShading (Lighting lighting, PhongMaterial mtl) {\n  vec4 o = vec4(0.0, 0.0, 0.0, 1.0);\n\n  o.rgb = lighting.diffuse * mtl.diffuse;\n  \n  #if USE_EMISSIVE\n    o.rgb += mtl.emissive;\n  #endif\n\n  #if USE_SPECULAR\n    o.rgb += lighting.specular * mtl.specular;\n  #endif\n  \n  #if CC_USE_SHADOW_MAP\n    o.rgb *= computeShadow();\n  #endif\n\n  o.a = mtl.opacity;\n\n  return o;\n}\n\nvoid CALC_PHONG_LIGHTING (inout vec4 outColor, in PhongMaterial material, in vec3 normal, in vec3 worldPosition, in vec3 viewDirection) {\n  Lighting phongLighting = getPhongLighting(normal, worldPosition, viewDirection, glossiness);\n  outColor = composePhongShading(phongLighting, material);\n}\n\nvoid main () {\n  vec4 diffuse = vec4(1, 1, 1, 1);\n  \n  #if CC_USE_ATTRIBUTE_COLOR\n    diffuse *= v_color;\n  #endif\n\n  #if USE_DIFFUSE_TEXTURE\n    CALC_DIFFUSE(diffuse, v_uv0);\n  #else\n    CALC_DIFFUSE(diffuse);\n  #endif\n\n  ALPHA_TEST(diffuse);\n\n  PhongMaterial material;\n  material.diffuse = diffuse.rgb;\n  material.opacity = diffuse.a;\n\n  #if USE_EMISSIVE_TEXTURE\n    CALC_EMISSIVE(material.emissive, v_uv0);\n  #else\n    CALC_EMISSIVE(material.emissive);\n  #endif\n\n  #if USE_SPECULAR_TEXTURE\n    CALC_SPECULAR(material.specular, v_uv0);\n  #else\n    CALC_SPECULAR(material.specular);\n  #endif\n\n  vec3 viewDirection = normalize(cc_cameraPos.xyz - v_worldPos);\n  vec4 phongColor;\n\n  vec3 normal = normalize(v_worldNormal);\n  #if USE_NORMAL_TEXTURE\n    CALC_NORMAL(normal, v_worldPos, v_uv0);\n  #endif\n\n  CALC_PHONG_LIGHTING(phongColor, material, normal, v_worldPos, viewDirection);\n\n  gl_FragColor = LINEAR_TO_OUTPUT_TEXEL( phongColor );\n}\n"
      },
      "glsl1": {
        "vert": "\nprecision highp float;\nuniform mat4 cc_matWorld;\nuniform mat4 cc_matWorldIT;\nuniform mat4 cc_matViewProj;\n\nstruct StandardAttributes {\n  vec2 uv;\n  vec4 position;\n  vec3 normal;\n  vec4 tangent;\n  vec4 color;\n};\n\nattribute vec3 a_position;\n\n#if CC_USE_ATTRIBUTE_UV0\nattribute vec2 a_uv0;\n#endif\n\n#if CC_USE_ATTRIBUTE_COLOR\nattribute vec4 a_color;\n#endif\n\n#if CC_USE_ATTRIBUTE_NORMAL\nattribute vec3 a_normal;\n#endif\n\n#if CC_USE_ATTRIBUTE_TANGENT\nattribute vec4 a_tangent;\n#endif\n\nvoid CCAttribute (out StandardAttributes attr) {\n  attr.position = vec4(a_position, 1.0);\n\n  #if CC_USE_ATTRIBUTE_UV0\n    attr.uv = a_uv0;\n  #else\n    attr.uv = vec2(0.0);\n  #endif\n  \n  #if CC_USE_ATTRIBUTE_COLOR\n    attr.color = a_color;\n  #else\n    attr.color = vec4(1.0);\n  #endif\n  \n  #if CC_USE_ATTRIBUTE_NORMAL\n    attr.normal = a_normal;\n  #else\n    attr.normal = vec3(0.0, 1.0, 0.0);\n  #endif\n\n  #if CC_USE_ATTRIBUTE_TANGENT\n    attr.tangent = a_tangent;\n  #else\n    attr.tangent = vec4(1.0, 0.0, 0.0, 0.0);\n  #endif\n}\n\n#if CC_USE_SKINNING\n\n#if CC_USE_SKINNING\n\n  attribute vec4 a_weights;\n  attribute vec4 a_joints;\n\n  #if CC_USE_JOINTS_TEXTRUE\n    uniform vec2 cc_jointsTextureSize;\n    uniform sampler2D cc_jointsTexture;\n\n    #if CC_JOINTS_TEXTURE_FLOAT32\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 4.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y));\n        vec4 v2 = texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y));\n        vec4 v3 = texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y));\n        vec4 v4 = texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y));\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #else\n      float decode32(vec4 rgba) {\n        float Sign = 1.0 - step(128.0, rgba[0]) * 2.0;\n        float Exponent = 2.0 * mod(rgba[0], 128.0) + step(128.0, rgba[1]) - 127.0;\n        float Mantissa = mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + 8388608.0;\n        return Sign * exp2(Exponent - 23.0) * Mantissa;\n      }\n      vec4 decodevec4 (vec4 x, vec4 y, vec4 z, vec4 w) {\n\n        return vec4(\n          decode32(x.wzyx * 255.0),\n          decode32(y.wzyx * 255.0),\n          decode32(z.wzyx * 255.0),\n          decode32(w.wzyx * 255.0)\n        );\n      }\n\n      vec4 decodevec4 (float dx, float x, float y) {\n        return decodevec4(\n          texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y))\n        );\n      }\n\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 16.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = decodevec4(dx, x,       y);\n        vec4 v2 = decodevec4(dx, x+4.0,   y);\n        vec4 v3 = decodevec4(dx, x+8.0,   y);\n        vec4 v4 = decodevec4(dx, x+12.0,  y);\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #endif\n  #else\n    uniform mat4 cc_jointMatrices[50];\nmat4 getBoneMatrix(const in float i) {\n      return cc_jointMatrices[int(i)];\n    }\n  #endif\n\n    mat4 skinMatrix() {\n      return\n        getBoneMatrix(a_joints.x) * a_weights.x +\n        getBoneMatrix(a_joints.y) * a_weights.y +\n        getBoneMatrix(a_joints.z) * a_weights.z +\n        getBoneMatrix(a_joints.w) * a_weights.w\n        ;\n    }\n#endif\n\nvoid SKIN_VERTEX(inout vec4 a1) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2, inout vec4 a3) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n    a3 = m * a3;\n  #endif\n}\n\n  void CCSkin(inout StandardAttributes attr) {\n    mat4 m = skinMatrix();\n    attr.position = m * attr.position;\n    attr.normal = (m * vec4(attr.normal, 0)).xyz;\n    attr.tangent = m * attr.tangent;\n  }\n#endif\n\nstruct StandardVertInput {\n  vec2 uv;\n  vec4 position;\n  vec3 normal;\n  vec4 tangent;\n  vec4 color;\n};\n\nvoid CCAttrToInput (in StandardAttributes attr, out StandardVertInput In) {\n  In.position = attr.position;\n  In.normal = attr.normal;\n  In.tangent = attr.tangent;\n  In.uv = attr.uv;\n  In.color = attr.color;\n}\n\nvoid CCVertInput (out StandardVertInput In) {\n  StandardAttributes attr;\n  CCAttribute(attr);\n  #if CC_USE_SKINNING\n    CCSkin(attr);\n  #endif\n  CCAttrToInput(attr, In);\n}\n\n#if CC_USE_SHADOW_MAP \n  uniform mat4 cc_shadow_lightViewProjMatrix[2];\nuniform vec4 cc_shadow_info[2];\n  uniform sampler2D cc_shadow_map[2];\n\n  varying vec4 v_posLightSpace[2];\n  varying float v_depth[2];\n#endif\n\n#if 1\n\n  void CLAC_SHADOW (vec3 worldPos) {\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n      v_posLightSpace[i] = cc_shadow_lightViewProjMatrix[i] * vec4(worldPos, 1.0);\n      v_depth[i] = (v_posLightSpace[i].z + cc_shadow_info[i].x) / (cc_shadow_info[i].x + cc_shadow_info[i].y);\n    }\n    #endif\n  }\n\n#else\n\nvec4 packDepthToRGBA(float depth) {\n  vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n  ret = fract(ret);\n  ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n  return ret;\n}\n\nfloat unpackRGBAToDepth(vec4 color) {\n  return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));\n}\n\n  float computeFallOff(float esm, vec2 coords, float frustumEdgeFalloff) {\n    float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.0, clamp(dot(coords, coords), 0.0, 1.0));\n    return mix(esm, 1.0, mask);\n  }\n\n  float computeShadowESM(sampler2D shadowMap, vec4 pos_lightspace, float vDepth, float depthScale, float darkness, float frustumEdgeFalloff) {\n    vec2 projCoords = pos_lightspace.xy / pos_lightspace.w;\n    vec2 shadowUV = projCoords * 0.5 + vec2(0.5);\n    if (shadowUV.x < 0.0 || shadowUV.x > 1.0 || shadowUV.y < 0.0 || shadowUV.y > 1.0) {\n      return 1.0;\n    }\n    float currentDepth = clamp(vDepth, 0.0, 1.0);\n    float closestDepth = unpackRGBAToDepth(texture2D(shadowMap, shadowUV));\n\n    float esm = clamp(exp(-depthScale * (currentDepth - closestDepth)), 1.0 - darkness, 1.0);\n    return computeFallOff(esm, projCoords, frustumEdgeFalloff);\n  }\n\n  float computeShadow() {\n    float shadow = 1.0;\n    float frustumEdgeFalloff = 0.0;\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n        shadow *= computeShadowESM(cc_shadow_map[i], v_posLightSpace[i], v_depth[i], cc_shadow_info[i].z, cc_shadow_info[i].w, frustumEdgeFalloff);\n    }\n    #endif\n    return shadow;\n  }\n\n#endif\n\nuniform vec2 mainTiling;\nuniform vec2 mainOffset;\nvarying mediump vec2 v_uv0;\nvarying lowp vec4 v_color;\nvarying vec3 v_worldNormal;\nvarying vec3 v_worldPos;\n\nvoid main () {\n  StandardVertInput In;\n  CCVertInput(In);\n\n  vec4 position = In.position;\n  vec4 normal = vec4(In.normal, 0);\n\n  v_worldPos = (cc_matWorld * position).xyz;\n  v_worldNormal = (cc_matWorldIT * normal).xyz;\n  v_color = In.color;\n  v_uv0 = In.uv * mainTiling + mainOffset;\n\n  CLAC_SHADOW(v_worldPos);\n  \n  gl_Position = cc_matViewProj * cc_matWorld * position;\n}\n",
        "frag": "\nprecision highp float;\nuniform vec4 cc_cameraPos;\n\nvec3 SRGBToLinear(vec3 gamma)\n{\n\treturn pow(gamma, vec3(2.2));\n\n}\n\nvec3 LinearToSRGB(vec3 linear)\n{\n\treturn pow(linear, vec3(0.454545));\n\n}\n\nvec4 TEXEL_TO_LINEAR (in vec4 color) {\n  #if INPUT_IS_GAMMA\n    return vec4(SRGBToLinear(color.rgb), color.a);\n  #else\n    return color;\n  #endif\n}\n\nvec4 LINEAR_TO_OUTPUT_TEXEL (in vec4 color) {\n  #if OUTPUT_TO_GAMMA\n    return vec4(LinearToSRGB(color.rgb), color.a);\n  #else\n    return color;\n  #endif\n}\n\n#define saturate(a) clamp( a, 0.0, 1.0 )\n\nmat4 transposeMat4(in mat4 mat) {\n    vec4 i0 = mat[0];\n    vec4 i1 = mat[1];\n    vec4 i2 = mat[2];\n    vec4 i3 = mat[3];\n    return mat4(vec4(i0.x, i1.x, i2.x, i3.x),\n                vec4(i0.y, i1.y, i2.y, i3.y),\n                vec4(i0.z, i1.z, i2.z, i3.z),\n                vec4(i0.w, i1.w, i2.w, i3.w));\n}\n\n#if USE_NORMAL_TEXTURE\n\n  uniform sampler2D normalTexture;\n\n#endif\n\nvoid CALC_NORMAL (inout vec3 normal, in vec3 worldPos, in vec2 uv) {\n  #if USE_NORMAL_TEXTURE\n\n  #endif\n}\n\nuniform lowp vec4 diffuseColor;\n\n#if USE_DIFFUSE_TEXTURE\n  uniform sampler2D diffuseTexture;\n#endif\n\nvoid MULTIPLY_DIFFUSE_TEXTRUE_COLOR (inout vec4 color, in vec2 uv) {\n  #if USE_DIFFUSE_TEXTURE && CC_USE_ATTRIBUTE_UV0\n    vec4 diffuseTextureColor = texture2D(diffuseTexture, uv);\n    #if CC_USE_ALPHA_ATLAS_DIFFUSETEXTURE\n      diffuseTextureColor.a *= texture2D(diffuseTexture, uv + vec2(0, 0.5)).r;\n    #endif\n    color *= TEXEL_TO_LINEAR(diffuseTextureColor);\n  #endif\n}\n\nvoid CALC_DIFFUSE (inout vec4 color, in vec2 uv) {\n  color *= diffuseColor;\n  MULTIPLY_DIFFUSE_TEXTRUE_COLOR(color, uv);\n}\n\nvoid CALC_DIFFUSE (inout vec4 color) {\n  color *= diffuseColor;\n}\n\n#if USE_SPECULAR\n  uniform lowp vec4 specularColor;\n\n  #if USE_SPECULAR_TEXTURE\n    uniform sampler2D specularTexture;\n  #endif\n\n#endif\n\nvoid MULTIPLY_SPECULAR_TEXTRUE_COLOR (inout vec3 color, in vec2 uv) {\n  #if USE_SPECULAR_TEXTURE && CC_USE_ATTRIBUTE_UV0\n    vec4 specularTextureColor = texture2D(specularTexture, uv);\n    specularTextureColor = TEXEL_TO_LINEAR(specularTextureColor);\n    color *= specularTextureColor.rgb;\n  #endif\n}\n\nvoid CALC_SPECULAR (inout vec3 specular, in vec2 uv) {\n  #if USE_SPECULAR\n    specular = specularColor.xyz;\n    MULTIPLY_SPECULAR_TEXTRUE_COLOR(specular, uv);\n  #endif\n}\n\nvoid CALC_SPECULAR (inout vec3 specular) {\n  #if USE_SPECULAR\n    specular = specularColor.xyz;\n  #endif\n}\n\n#if USE_EMISSIVE\n  uniform lowp vec4 emissiveColor;\n\n  #if USE_EMISSIVE_TEXTURE\n    uniform sampler2D emissiveTexture;\n  #endif\n\n#endif\n\nvoid MULTIPLY_EMISSIVE_TEXTRUE_COLOR (inout vec3 color, in vec2 uv) {\n  #if USE_EMISSIVE_TEXTURE && CC_USE_ATTRIBUTE_UV0\n    vec4 emissiveTextureColor = texture2D(emissiveTexture, uv);\n    #if CC_USE_ALPHA_ATLAS_EMISSIVETEXTURE\n      emissiveTextureColor.a *= texture2D(emissiveTexture, uv + vec2(0, 0.5)).r;\n    #endif\n    emissiveTextureColor = TEXEL_TO_LINEAR(emissiveTextureColor);\n    color *= emissiveTextureColor.rgb;\n  #endif\n}\n\nvoid CALC_EMISSIVE (inout vec3 emissive, in vec2 uv) {\n  #if USE_EMISSIVE\n    emissive = emissiveColor.xyz;\n    MULTIPLY_EMISSIVE_TEXTRUE_COLOR(emissive, uv);\n  #endif\n}\n\nvoid CALC_EMISSIVE (inout vec3 emissive) {\n  #if USE_EMISSIVE\n    emissive = emissiveColor.xyz;\n  #endif\n}\n\n#if USE_ALPHA_TEST\n  \n  uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n  #if USE_ALPHA_TEST\n      if (color.a < alphaThreshold) discard;\n  #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n  #if USE_ALPHA_TEST\n      if (alpha < alphaThreshold) discard;\n  #endif\n}\n\nvarying vec3 v_worldNormal;\nvarying vec3 v_worldPos;\nvarying mediump vec2 v_uv0;\nvarying lowp vec4 v_color;\n\n#if CC_NUM_DIR_LIGHTS > 0 || CC_NUM_POINT_LIGHTS > 0 || CC_NUM_SPOT_LIGHTS > 0 || CC_NUM_AMBIENT_LIGHTS > 0\nuniform vec4 cc_dirLightDirection[4];\nuniform vec4 cc_dirLightColor[4];\nuniform vec4 cc_pointLightPositionAndRange[4];\nuniform vec4 cc_pointLightColor[4];\nuniform vec4 cc_spotLightPositionAndRange[4];\nuniform vec4 cc_spotLightDirection[4];\nuniform vec4 cc_spotLightColor[4];\nuniform vec4 cc_ambientColor[4];\n\n#endif\n\nstruct LightInfo {\n  vec3 lightDir;\n  vec3 radiance;\n};\n\nLightInfo computeDirectionalLighting(\n  vec4 lightDirection,\n  vec4 lightColor\n) {\n  LightInfo ret;\n  ret.lightDir = -normalize(lightDirection.xyz);\n  ret.radiance = lightColor.rgb;\n  return ret;\n}\n\nLightInfo computePointLighting(\n  vec3 worldPosition,\n  vec4 lightPositionAndRange,\n  vec4 lightColor\n) {\n  LightInfo ret;\n  vec3 lightDir = lightPositionAndRange.xyz - worldPosition;\n  float attenuation = max(0., 1.0 - length(lightDir) / lightPositionAndRange.w);\n  \n  ret.lightDir = normalize(lightDir);\n  ret.radiance = lightColor.rgb * attenuation;\n  return ret;\n}\n\nLightInfo computeSpotLighting(\n  vec3 worldPosition,\n  vec4 lightPositionAndRange,\n  vec4 lightDirection,\n  vec4 lightColor\n) {\n  LightInfo ret;\n  vec3 lightDir = lightPositionAndRange.xyz - worldPosition;\n  float attenuation = max(0., 1.0 - length(lightDir) / lightPositionAndRange.w);\n  lightDir = normalize(lightDir);\n  float cosConeAngle = max(0., dot(lightDirection.xyz, -lightDir));\n  cosConeAngle = cosConeAngle < lightDirection.w ? 0. : cosConeAngle;\n  cosConeAngle = pow(cosConeAngle, lightColor.w);\n  \n  ret.lightDir = lightDir;\n  ret.radiance = lightColor.rgb * attenuation * cosConeAngle;\n  return ret;\n}\n\n#if CC_USE_SHADOW_MAP \n  uniform mat4 cc_shadow_lightViewProjMatrix[2];\nuniform vec4 cc_shadow_info[2];\n  uniform sampler2D cc_shadow_map[2];\n\n  varying vec4 v_posLightSpace[2];\n  varying float v_depth[2];\n#endif\n\n#if 0\n\n  void CLAC_SHADOW (vec3 worldPos) {\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n      v_posLightSpace[i] = cc_shadow_lightViewProjMatrix[i] * vec4(worldPos, 1.0);\n      v_depth[i] = (v_posLightSpace[i].z + cc_shadow_info[i].x) / (cc_shadow_info[i].x + cc_shadow_info[i].y);\n    }\n    #endif\n  }\n\n#else\n\nvec4 packDepthToRGBA(float depth) {\n  vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n  ret = fract(ret);\n  ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n  return ret;\n}\n\nfloat unpackRGBAToDepth(vec4 color) {\n  return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));\n}\n\n  float computeFallOff(float esm, vec2 coords, float frustumEdgeFalloff) {\n    float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.0, clamp(dot(coords, coords), 0.0, 1.0));\n    return mix(esm, 1.0, mask);\n  }\n\n  float computeShadowESM(sampler2D shadowMap, vec4 pos_lightspace, float vDepth, float depthScale, float darkness, float frustumEdgeFalloff) {\n    vec2 projCoords = pos_lightspace.xy / pos_lightspace.w;\n    vec2 shadowUV = projCoords * 0.5 + vec2(0.5);\n    if (shadowUV.x < 0.0 || shadowUV.x > 1.0 || shadowUV.y < 0.0 || shadowUV.y > 1.0) {\n      return 1.0;\n    }\n    float currentDepth = clamp(vDepth, 0.0, 1.0);\n    float closestDepth = unpackRGBAToDepth(texture2D(shadowMap, shadowUV));\n\n    float esm = clamp(exp(-depthScale * (currentDepth - closestDepth)), 1.0 - darkness, 1.0);\n    return computeFallOff(esm, projCoords, frustumEdgeFalloff);\n  }\n\n  float computeShadow() {\n    float shadow = 1.0;\n    float frustumEdgeFalloff = 0.0;\n    #if CC_USE_SHADOW_MAP\n    for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {\n        shadow *= computeShadowESM(cc_shadow_map[i], v_posLightSpace[i], v_depth[i], cc_shadow_info[i].z, cc_shadow_info[i].w, frustumEdgeFalloff);\n    }\n    #endif\n    return shadow;\n  }\n\n#endif\n\nuniform float glossiness;\nstruct PhongMaterial {\n  vec3 diffuse;\n  vec3 emissive;\n  vec3 specular;\n  float opacity;\n};\n\nstruct Lighting {\n  vec3 diffuse;\n  vec3 specular;\n};\n\nvoid brdf (inout Lighting result, LightInfo info, vec3 normal, vec3 viewDirection, float glossiness) {\n  float ndh = 0.0;\n\n  vec3 halfDir = normalize(viewDirection + info.lightDir);\n  float NdotH = max(0.0, dot(normal, halfDir));\n  NdotH = pow(NdotH, max(1.0, glossiness * 128.0));\n\n  vec3 diffuse = info.radiance * max(0.0, dot(normal, info.lightDir));\n  vec3 specular = info.radiance * NdotH;\n\n  result.diffuse += diffuse;\n  result.specular += specular;\n}\n\nLighting getPhongLighting (vec3 normal, vec3 worldPos, vec3 viewDirection, float glossiness) {\n  Lighting result;\n  result.diffuse = vec3(0, 0, 0);\n  result.specular = vec3(0, 0, 0);\n\n  #if CC_NUM_DIR_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_DIR_LIGHTS; i++) {\n      LightInfo info = computeDirectionalLighting(cc_dirLightDirection[i], cc_dirLightColor[i]);\n      brdf(result, info, normal, viewDirection, glossiness);\n    }\n  #endif\n\n  #if CC_NUM_POINT_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_POINT_LIGHTS; i++) {\n      LightInfo info = computePointLighting(worldPos, cc_pointLightPositionAndRange[i], cc_pointLightColor[i]);\n      brdf(result, info, normal, viewDirection, glossiness);\n    }\n  #endif\n\n  #if CC_NUM_SPOT_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_SPOT_LIGHTS; i++) {\n      LightInfo info = computeSpotLighting(worldPos, cc_spotLightPositionAndRange[i], cc_spotLightDirection[i], cc_spotLightColor[i]);\n      brdf(result, info, normal, viewDirection, glossiness);\n    }\n  #endif\n\n  #if CC_NUM_AMBIENT_LIGHTS > 0\n    for (int i = 0; i < CC_NUM_AMBIENT_LIGHTS; i++) {\n      result.diffuse += cc_ambientColor[i].rgb;\n    }\n  #endif\n\n  return result;\n}\n\nvec4 composePhongShading (Lighting lighting, PhongMaterial mtl) {\n  vec4 o = vec4(0.0, 0.0, 0.0, 1.0);\n\n  o.rgb = lighting.diffuse * mtl.diffuse;\n  \n  #if USE_EMISSIVE\n    o.rgb += mtl.emissive;\n  #endif\n\n  #if USE_SPECULAR\n    o.rgb += lighting.specular * mtl.specular;\n  #endif\n  \n  #if CC_USE_SHADOW_MAP\n    o.rgb *= computeShadow();\n  #endif\n\n  o.a = mtl.opacity;\n\n  return o;\n}\n\nvoid CALC_PHONG_LIGHTING (inout vec4 outColor, in PhongMaterial material, in vec3 normal, in vec3 worldPosition, in vec3 viewDirection) {\n  Lighting phongLighting = getPhongLighting(normal, worldPosition, viewDirection, glossiness);\n  outColor = composePhongShading(phongLighting, material);\n}\n\nvoid main () {\n  vec4 diffuse = vec4(1, 1, 1, 1);\n  \n  #if CC_USE_ATTRIBUTE_COLOR\n    diffuse *= v_color;\n  #endif\n\n  #if USE_DIFFUSE_TEXTURE\n    CALC_DIFFUSE(diffuse, v_uv0);\n  #else\n    CALC_DIFFUSE(diffuse);\n  #endif\n\n  ALPHA_TEST(diffuse);\n\n  PhongMaterial material;\n  material.diffuse = diffuse.rgb;\n  material.opacity = diffuse.a;\n\n  #if USE_EMISSIVE_TEXTURE\n    CALC_EMISSIVE(material.emissive, v_uv0);\n  #else\n    CALC_EMISSIVE(material.emissive);\n  #endif\n\n  #if USE_SPECULAR_TEXTURE\n    CALC_SPECULAR(material.specular, v_uv0);\n  #else\n    CALC_SPECULAR(material.specular);\n  #endif\n\n  vec3 viewDirection = normalize(cc_cameraPos.xyz - v_worldPos);\n  vec4 phongColor;\n\n  vec3 normal = normalize(v_worldNormal);\n  #if USE_NORMAL_TEXTURE\n    CALC_NORMAL(normal, v_worldPos, v_uv0);\n  #endif\n\n  CALC_PHONG_LIGHTING(phongColor, material, normal, v_worldPos, viewDirection);\n\n  gl_FragColor = LINEAR_TO_OUTPUT_TEXEL( phongColor );\n}\n"
      },
      "builtins": {
        "globals": {
          "blocks": [
            {
              "name": "CCGlobal",
              "defines": []
            },
            {
              "name": "CC_SHADOW",
              "defines": [
                "CC_USE_SHADOW_MAP"
              ]
            },
            {
              "name": "CCLIGHTS",
              "defines": []
            }
          ],
          "samplers": [
            {
              "name": "cc_shadow_map",
              "defines": [
                "CC_USE_SHADOW_MAP"
              ]
            }
          ]
        },
        "locals": {
          "blocks": [
            {
              "name": "CCLocal",
              "defines": []
            },
            {
              "name": "CC_JOINT_MATRIX",
              "defines": [
                "CC_USE_SKINNING"
              ]
            }
          ],
          "samplers": [
            {
              "name": "cc_jointsTexture",
              "defines": [
                "CC_USE_SKINNING",
                "CC_USE_JOINTS_TEXTRUE"
              ]
            }
          ]
        }
      },
      "defines": [
        {
          "name": "CC_USE_ATTRIBUTE_UV0",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_ATTRIBUTE_COLOR",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_ATTRIBUTE_NORMAL",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_ATTRIBUTE_TANGENT",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_SKINNING",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_JOINTS_TEXTRUE",
          "type": "boolean",
          "defines": [
            "CC_USE_SKINNING",
            "CC_USE_SKINNING"
          ]
        },
        {
          "name": "CC_JOINTS_TEXTURE_FLOAT32",
          "type": "boolean",
          "defines": [
            "CC_USE_SKINNING",
            "CC_USE_SKINNING",
            "CC_USE_JOINTS_TEXTRUE"
          ]
        },
        {
          "name": "CC_USE_SHADOW_MAP",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "INPUT_IS_GAMMA",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "OUTPUT_TO_GAMMA",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "USE_NORMAL_TEXTURE",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "USE_DIFFUSE_TEXTURE",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_ALPHA_ATLAS_DIFFUSETEXTURE",
          "type": "boolean",
          "defines": [
            "USE_DIFFUSE_TEXTURE",
            "CC_USE_ATTRIBUTE_UV0"
          ]
        },
        {
          "name": "USE_SPECULAR",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "USE_SPECULAR_TEXTURE",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "USE_EMISSIVE",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "USE_EMISSIVE_TEXTURE",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_ALPHA_ATLAS_EMISSIVETEXTURE",
          "type": "boolean",
          "defines": [
            "USE_EMISSIVE_TEXTURE",
            "CC_USE_ATTRIBUTE_UV0"
          ]
        },
        {
          "name": "USE_ALPHA_TEST",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_NUM_DIR_LIGHTS",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_NUM_POINT_LIGHTS",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_NUM_SPOT_LIGHTS",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        },
        {
          "name": "CC_NUM_AMBIENT_LIGHTS",
          "type": "number",
          "defines": [],
          "range": [
            0,
            3
          ]
        }
      ],
      "blocks": [
        {
          "name": "SKINNING",
          "members": [
            {
              "name": "cc_jointsTextureSize",
              "type": 14,
              "count": 1
            }
          ],
          "defines": [
            "CC_USE_SKINNING",
            "CC_USE_JOINTS_TEXTRUE"
          ],
          "binding": 0
        },
        {
          "name": "MAIN_TILING",
          "members": [
            {
              "name": "mainTiling",
              "type": 14,
              "count": 1
            },
            {
              "name": "mainOffset",
              "type": 14,
              "count": 1
            }
          ],
          "defines": [],
          "binding": 1
        },
        {
          "name": "DIFFUSE",
          "members": [
            {
              "name": "diffuseColor",
              "type": 16,
              "count": 1
            }
          ],
          "defines": [],
          "binding": 2
        },
        {
          "name": "SPECULAR",
          "members": [
            {
              "name": "specularColor",
              "type": 16,
              "count": 1
            }
          ],
          "defines": [
            "USE_SPECULAR"
          ],
          "binding": 3
        },
        {
          "name": "EMISSIVE",
          "members": [
            {
              "name": "emissiveColor",
              "type": 16,
              "count": 1
            }
          ],
          "defines": [
            "USE_EMISSIVE"
          ],
          "binding": 4
        },
        {
          "name": "ALPHA_TEST",
          "members": [
            {
              "name": "alphaThreshold",
              "type": 13,
              "count": 1
            }
          ],
          "defines": [
            "USE_ALPHA_TEST"
          ],
          "binding": 5
        },
        {
          "name": "PHONG",
          "members": [
            {
              "name": "glossiness",
              "type": 13,
              "count": 1
            }
          ],
          "defines": [],
          "binding": 6
        }
      ],
      "samplers": [
        {
          "name": "normalTexture",
          "type": 29,
          "count": 1,
          "defines": [
            "USE_NORMAL_TEXTURE"
          ],
          "binding": 30
        },
        {
          "name": "diffuseTexture",
          "type": 29,
          "count": 1,
          "defines": [
            "USE_DIFFUSE_TEXTURE"
          ],
          "binding": 31
        },
        {
          "name": "specularTexture",
          "type": 29,
          "count": 1,
          "defines": [
            "USE_SPECULAR",
            "USE_SPECULAR_TEXTURE"
          ],
          "binding": 32
        },
        {
          "name": "emissiveTexture",
          "type": 29,
          "count": 1,
          "defines": [
            "USE_EMISSIVE",
            "USE_EMISSIVE_TEXTURE"
          ],
          "binding": 33
        }
      ],
      "dependencies": {},
      "name": "builtin-phong|phong-vs|phong-fs"
    },
    {
      "hash": 1437876711,
      "glsl3": {
        "vert": "\nprecision highp float;\n\nin vec3 a_position;\nuniform CCLocal {\n  mat4 cc_matWorld;\n  mat4 cc_matWorldIT;\n};\nuniform CC_SHADOW_MAP {\n  mat4  cc_shadow_map_lightViewProjMatrix;\n  vec4  cc_shadow_map_info;\n\n  float cc_shadow_map_bias;\n};\n\nout float v_depth;\n\n#if CC_USE_SKINNING\n\n  in vec4 a_weights;\n  in vec4 a_joints;\n\n  #if CC_USE_JOINTS_TEXTRUE\n    uniform SKINNING {\n      vec2 cc_jointsTextureSize;\n    }\n    uniform sampler2D cc_jointsTexture;\n\n    #if CC_JOINTS_TEXTURE_FLOAT32\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 4.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y));\n        vec4 v2 = texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y));\n        vec4 v3 = texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y));\n        vec4 v4 = texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y));\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #else\n      float decode32(vec4 rgba) {\n        float Sign = 1.0 - step(128.0, rgba[0]) * 2.0;\n        float Exponent = 2.0 * mod(rgba[0], 128.0) + step(128.0, rgba[1]) - 127.0;\n        float Mantissa = mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + 8388608.0;\n        return Sign * exp2(Exponent - 23.0) * Mantissa;\n      }\n      vec4 decodevec4 (vec4 x, vec4 y, vec4 z, vec4 w) {\n\n        return vec4(\n          decode32(x.wzyx * 255.0),\n          decode32(y.wzyx * 255.0),\n          decode32(z.wzyx * 255.0),\n          decode32(w.wzyx * 255.0)\n        );\n      }\n\n      vec4 decodevec4 (float dx, float x, float y) {\n        return decodevec4(\n          texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y))\n        );\n      }\n\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 16.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = decodevec4(dx, x,       y);\n        vec4 v2 = decodevec4(dx, x+4.0,   y);\n        vec4 v3 = decodevec4(dx, x+8.0,   y);\n        vec4 v4 = decodevec4(dx, x+12.0,  y);\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #endif\n  #else\n    uniform CC_JOINT_MATRIX {\n      mat4 cc_jointMatrices[50];\n    }\n\n    mat4 getBoneMatrix(const in float i) {\n      return cc_jointMatrices[int(i)];\n    }\n  #endif\n\n    mat4 skinMatrix() {\n      return\n        getBoneMatrix(a_joints.x) * a_weights.x +\n        getBoneMatrix(a_joints.y) * a_weights.y +\n        getBoneMatrix(a_joints.z) * a_weights.z +\n        getBoneMatrix(a_joints.w) * a_weights.w\n        ;\n    }\n#endif\n\nvoid SKIN_VERTEX(inout vec4 a1) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2, inout vec4 a3) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n    a3 = m * a3;\n  #endif\n}\n\nvoid main () {\n  vec4 position = vec4(a_position, 1);\n\n  SKIN_VERTEX(position);\n\n  gl_Position = cc_shadow_map_lightViewProjMatrix * cc_matWorld * position;\n\n  v_depth = ((gl_Position.z + cc_shadow_map_info.x) / (cc_shadow_map_info.x + cc_shadow_map_info.y)) + cc_shadow_map_bias;\n}\n",
        "frag": "\nprecision highp float;\n\nin float v_depth;\n\nvec4 packDepthToRGBA(float depth) {\n  vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n  ret = fract(ret);\n  ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n  return ret;\n}\n\nfloat unpackRGBAToDepth(vec4 color) {\n  return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));\n}\n\nvoid main () {\n\n  gl_FragColor = packDepthToRGBA(v_depth);\n\n}\n"
      },
      "glsl1": {
        "vert": "\nprecision highp float;\n\nattribute vec3 a_position;\nuniform mat4 cc_matWorld;\nuniform mat4 cc_shadow_map_lightViewProjMatrix;\nuniform vec4 cc_shadow_map_info;\nuniform float cc_shadow_map_bias;\n\nvarying float v_depth;\n\n#if CC_USE_SKINNING\n\n  attribute vec4 a_weights;\n  attribute vec4 a_joints;\n\n  #if CC_USE_JOINTS_TEXTRUE\n    uniform vec2 cc_jointsTextureSize;\n    uniform sampler2D cc_jointsTexture;\n\n    #if CC_JOINTS_TEXTURE_FLOAT32\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 4.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y));\n        vec4 v2 = texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y));\n        vec4 v3 = texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y));\n        vec4 v4 = texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y));\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #else\n      float decode32(vec4 rgba) {\n        float Sign = 1.0 - step(128.0, rgba[0]) * 2.0;\n        float Exponent = 2.0 * mod(rgba[0], 128.0) + step(128.0, rgba[1]) - 127.0;\n        float Mantissa = mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + 8388608.0;\n        return Sign * exp2(Exponent - 23.0) * Mantissa;\n      }\n      vec4 decodevec4 (vec4 x, vec4 y, vec4 z, vec4 w) {\n\n        return vec4(\n          decode32(x.wzyx * 255.0),\n          decode32(y.wzyx * 255.0),\n          decode32(z.wzyx * 255.0),\n          decode32(w.wzyx * 255.0)\n        );\n      }\n\n      vec4 decodevec4 (float dx, float x, float y) {\n        return decodevec4(\n          texture2D(cc_jointsTexture, vec2(dx * (x + 0.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 1.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 2.5), y)),\n          texture2D(cc_jointsTexture, vec2(dx * (x + 3.5), y))\n        );\n      }\n\n      mat4 getBoneMatrix(const in float i) {\n        float width = cc_jointsTextureSize.x;\n        float height = cc_jointsTextureSize.y;\n        float j = i * 16.0;\n        float x = mod(j, width);\n        float y = floor(j / width);\n\n        float dx = 1.0 / width;\n        float dy = 1.0 / height;\n\n        y = dy * (y + 0.5);\n\n        vec4 v1 = decodevec4(dx, x,       y);\n        vec4 v2 = decodevec4(dx, x+4.0,   y);\n        vec4 v3 = decodevec4(dx, x+8.0,   y);\n        vec4 v4 = decodevec4(dx, x+12.0,  y);\n\n        return mat4(v1, v2, v3, v4);\n      }\n    #endif\n  #else\n    uniform mat4 cc_jointMatrices[50];\nmat4 getBoneMatrix(const in float i) {\n      return cc_jointMatrices[int(i)];\n    }\n  #endif\n\n    mat4 skinMatrix() {\n      return\n        getBoneMatrix(a_joints.x) * a_weights.x +\n        getBoneMatrix(a_joints.y) * a_weights.y +\n        getBoneMatrix(a_joints.z) * a_weights.z +\n        getBoneMatrix(a_joints.w) * a_weights.w\n        ;\n    }\n#endif\n\nvoid SKIN_VERTEX(inout vec4 a1) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n  #endif\n}\n\nvoid SKIN_VERTEX(inout vec4 a1, inout vec4 a2, inout vec4 a3) {\n  #if CC_USE_SKINNING\n    mat4 m = skinMatrix();\n    a1 = m * a1;\n    a2 = m * a2;\n    a3 = m * a3;\n  #endif\n}\n\nvoid main () {\n  vec4 position = vec4(a_position, 1);\n\n  SKIN_VERTEX(position);\n\n  gl_Position = cc_shadow_map_lightViewProjMatrix * cc_matWorld * position;\n\n  v_depth = ((gl_Position.z + cc_shadow_map_info.x) / (cc_shadow_map_info.x + cc_shadow_map_info.y)) + cc_shadow_map_bias;\n}\n",
        "frag": "\nprecision highp float;\n\nvarying float v_depth;\n\nvec4 packDepthToRGBA(float depth) {\n  vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n  ret = fract(ret);\n  ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);\n  return ret;\n}\n\nfloat unpackRGBAToDepth(vec4 color) {\n  return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));\n}\n\nvoid main () {\n\n  gl_FragColor = packDepthToRGBA(v_depth);\n\n}\n"
      },
      "builtins": {
        "globals": {
          "blocks": [
            {
              "name": "CC_SHADOW_MAP",
              "defines": []
            }
          ],
          "samplers": []
        },
        "locals": {
          "blocks": [
            {
              "name": "CCLocal",
              "defines": []
            },
            {
              "name": "CC_JOINT_MATRIX",
              "defines": [
                "CC_USE_SKINNING"
              ]
            }
          ],
          "samplers": [
            {
              "name": "cc_jointsTexture",
              "defines": [
                "CC_USE_SKINNING",
                "CC_USE_JOINTS_TEXTRUE"
              ]
            }
          ]
        }
      },
      "defines": [
        {
          "name": "CC_USE_SKINNING",
          "type": "boolean",
          "defines": []
        },
        {
          "name": "CC_USE_JOINTS_TEXTRUE",
          "type": "boolean",
          "defines": [
            "CC_USE_SKINNING"
          ]
        },
        {
          "name": "CC_JOINTS_TEXTURE_FLOAT32",
          "type": "boolean",
          "defines": [
            "CC_USE_SKINNING",
            "CC_USE_JOINTS_TEXTRUE"
          ]
        }
      ],
      "blocks": [
        {
          "name": "SKINNING",
          "members": [
            {
              "name": "cc_jointsTextureSize",
              "type": 14,
              "count": 1
            }
          ],
          "defines": [
            "CC_USE_SKINNING",
            "CC_USE_JOINTS_TEXTRUE"
          ],
          "binding": 0
        }
      ],
      "samplers": [],
      "dependencies": {},
      "name": "builtin-phong|shadow-map-vs|shadow-map-fs"
    }
  ]
}