diff --git a/cocos/core/builtin/effects.ts b/cocos/core/builtin/effects.ts index 400d6b0aee3..c894b2b7ad0 100644 --- a/cocos/core/builtin/effects.ts +++ b/cocos/core/builtin/effects.ts @@ -9,13 +9,15 @@ export const effects = [ "shaders": [ { "name": "billboard|vert:vs_main|tinted-fs:add", - "hash": 3642336485, + "hash": 1267104656, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 54, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 94, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } }, - "defines": [], + "defines": [ + { "name": "USE_BATCHING", "type": "boolean" } + ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, { "name": "a_texCoord", "defines": [], "format": 21, "location": 1 }, @@ -235,13 +237,15 @@ export const effects = [ "shaders": [ { "name": "graphics|vs:vert|fs:frag", - "hash": 4284763886, + "hash": 818680106, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 49, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 0 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 89, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 0 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } }, - "defines": [], + "defines": [ + { "name": "USE_BATCHING", "type": "boolean" } + ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, { "name": "a_color", "defines": [], "format": 44, "location": 1 }, @@ -293,14 +297,15 @@ export const effects = [ "shaders": [ { "name": "particle-gpu|particle-vs-gpu:gpvs_main|tinted-fs:add", - "hash": 851293782, + "hash": 1492719419, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 64, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 104, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } }, "defines": [ { "name": "CC_RENDER_MODE", "type": "number", "range": [0, 4] }, + { "name": "USE_BATCHING", "type": "boolean" }, { "name": "USE_VK_SHADER", "type": "boolean" }, { "name": "COLOR_OVER_TIME_MODULE_ENABLE", "type": "boolean" }, { "name": "ROTATION_OVER_TIME_MODULE_ENABLE", "type": "boolean" }, @@ -385,14 +390,15 @@ export const effects = [ "shaders": [ { "name": "particle-trail|particle-trail:vs_main|tinted-fs:add", - "hash": 2502358098, + "hash": 2681867487, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 53, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 93, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } }, "defines": [ { "name": "CC_RENDER_MODE", "type": "number", "range": [0, 4] }, + { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_DRAW_WIRE_FRAME", "type": "boolean" }, { "name": "CC_USE_WORLD_SPACE", "type": "boolean" } ], @@ -433,14 +439,15 @@ export const effects = [ "shaders": [ { "name": "particle|particle-vs-legacy:lpvs_main|tinted-fs:add", - "hash": 585841727, + "hash": 714317392, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 53, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 93, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } }, "defines": [ { "name": "CC_RENDER_MODE", "type": "number", "range": [0, 4] }, + { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_WORLD_SPACE", "type": "boolean" }, { "name": "ROTATION_OVER_TIME_MODULE_ENABLE", "type": "boolean" } ], @@ -484,14 +491,15 @@ export const effects = [ "shaders": [ { "name": "spine|sprite-vs:vert|sprite-fs:frag", - "hash": 2499219289, + "hash": 1713049466, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 49, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 1 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 89, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 1 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": ["USE_LOCAL"] }], "samplerTextures": [{ "name": "cc_spriteTexture", "defines": [] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_LOCAL", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["USE_LOCAL"] }], "samplerTextures": [{ "name": "cc_spriteTexture", "defines": [] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_LOCAL", "type": "boolean" }, + { "name": "USE_BATCHING", "type": "boolean" }, { "name": "TWO_COLORED", "type": "boolean" }, { "name": "USE_ALPHA_TEST", "type": "boolean" } ], @@ -523,14 +531,15 @@ export const effects = [ "shaders": [ { "name": "sprite|sprite-vs:vert|sprite-fs:frag", - "hash": 813679071, + "hash": 528700848, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 49, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 1 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 89, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 1 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": ["USE_LOCAL"] }], "samplerTextures": [{ "name": "cc_spriteTexture", "defines": ["USE_TEXTURE"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_LOCAL", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["USE_LOCAL"] }], "samplerTextures": [{ "name": "cc_spriteTexture", "defines": ["USE_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_LOCAL", "type": "boolean" }, + { "name": "USE_BATCHING", "type": "boolean" }, { "name": "SAMPLE_FROM_RT", "type": "boolean" }, { "name": "USE_PIXEL_ALIGNMENT", "type": "boolean" }, { "name": "CC_USE_EMBEDDED_ALPHA", "type": "boolean" }, @@ -565,11 +574,11 @@ export const effects = [ "shaders": [ { "name": "standard|standard-vs|standard-fs", - "hash": 2358998302, + "hash": 1937716204, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 223, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 75 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 223, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 115 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [{ "name": "cc_shadowMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_spotLightingMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_environment", "defines": ["CC_USE_IBL"] }, { "name": "cc_diffuseMap", "defines": ["CC_USE_DIFFUSEMAP"] }], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }, { "name": "CCForwardLight", "defines": ["CC_FORWARD_ADD", "CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_lightingMap", "defines": ["USE_LIGHTMAP", "!USE_BATCHING", "!CC_FORWARD_ADD"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }, { "name": "CCForwardLight", "defines": ["CC_FORWARD_ADD", "CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_lightingMap", "defines": ["USE_LIGHTMAP", "!USE_BATCHING", "!CC_FORWARD_ADD"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -578,7 +587,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -623,7 +631,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 }, { "name": "a_color", "defines": ["USE_VERTEX_COLOR"], "format": 44, "location": 14 }, @@ -659,11 +667,11 @@ export const effects = [ }, { "name": "standard|shadow-caster-vs:vert|shadow-caster-fs:frag", - "hash": 3059264880, + "hash": 3038657594, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 184, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 75 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 184, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 115 }, "globals": { "blocks": [{ "name": "CCShadow", "defines": [] }, { "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [{ "name": "cc_shadowMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_spotLightingMap", "defines": ["CC_RECEIVE_SHADOW"] }], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -672,7 +680,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -697,7 +704,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 }, { "name": "a_texCoord1", "defines": [], "format": 21, "location": 14 } @@ -731,22 +738,23 @@ export const effects = [ "shaders": [ { "name": "terrain|terrain-vs|terrain-fs", - "hash": 38922979, + "hash": 3377788356, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 71, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 71 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 111, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 111 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [{ "name": "cc_shadowMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_spotLightingMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_environment", "defines": ["CC_USE_IBL"] }, { "name": "cc_diffuseMap", "defines": ["CC_USE_DIFFUSEMAP"] }], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }, { "name": "CCForwardLight", "defines": ["CC_FORWARD_ADD", "CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [{ "name": "cc_lightingMap", "defines": ["USE_LIGHTMAP", "!USE_BATCHING", "!CC_FORWARD_ADD"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }, { "name": "CCForwardLight", "defines": ["CC_FORWARD_ADD", "CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [{ "name": "cc_lightingMap", "defines": ["USE_LIGHTMAP", "!USE_BATCHING", "!CC_FORWARD_ADD"] }], "buffers": [], "images": [] } }, "defines": [ + { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_FOG", "type": "number", "range": [0, 4] }, { "name": "CC_USE_ACCURATE_FOG", "type": "boolean" }, + { "name": "USE_INSTANCING", "type": "boolean" }, { "name": "CC_RECEIVE_SHADOW", "type": "boolean" }, { "name": "USE_NORMALMAP", "type": "boolean" }, { "name": "USE_LIGHTMAP", "type": "boolean" }, { "name": "CC_USE_IBL", "type": "number", "range": [0, 2] }, { "name": "CC_USE_DIFFUSEMAP", "type": "number", "range": [0, 2] }, { "name": "USE_REFLECTION_DENOISE", "type": "boolean" }, - { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_FORWARD_ADD", "type": "boolean" }, { "name": "CC_USE_HDR", "type": "boolean" }, { "name": "LAYERS", "type": "number", "range": [0, 4] }, @@ -793,13 +801,15 @@ export const effects = [ }, { "name": "terrain|shadow-caster-vs:vert|shadow-caster-fs:frag", - "hash": 2218105608, + "hash": 182319298, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 69, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 0 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 109, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 0 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] } }, - "defines": [], + "defines": [ + { "name": "USE_BATCHING", "type": "boolean" } + ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, { "name": "a_normal", "defines": [], "format": 32, "location": 1 }, @@ -823,11 +833,11 @@ export const effects = [ "shaders": [ { "name": "unlit|unlit-vs:vert|unlit-fs:frag", - "hash": 267820933, + "hash": 3763836392, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 198, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 41 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -836,7 +846,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -864,7 +873,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 }, { "name": "a_color", "defines": ["USE_VERTEX_COLOR"], "format": 44, "location": 14 } @@ -897,7 +906,7 @@ export const effects = [ "shaders": [ { "name": "bloom|bloom-vs|prefilter-fs", - "hash": 4024722102, + "hash": 1694283355, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 147, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, @@ -910,7 +919,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -930,7 +938,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 } ], @@ -950,7 +958,7 @@ export const effects = [ }, { "name": "bloom|bloom-vs|downsample-fs", - "hash": 2813518838, + "hash": 546996885, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 147, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, @@ -963,7 +971,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -983,7 +990,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 } ], @@ -1003,7 +1010,7 @@ export const effects = [ }, { "name": "bloom|bloom-vs|upsample-fs", - "hash": 3878242894, + "hash": 4202381467, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 147, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, @@ -1016,7 +1023,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -1036,7 +1042,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 } ], @@ -1056,7 +1062,7 @@ export const effects = [ }, { "name": "bloom|bloom-vs|combine-fs", - "hash": 1531599890, + "hash": 1033011508, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 147, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 40 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, @@ -1069,7 +1075,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -1089,7 +1094,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 } ], @@ -1118,11 +1123,11 @@ export const effects = [ "shaders": [ { "name": "deferred-lighting|lighting-vs|lighting-fs", - "hash": 3102536052, + "hash": 4169577096, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 39, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 69 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 39, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 109 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [{ "name": "cc_shadowMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_spotLightingMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_environment", "defines": ["CC_USE_IBL"] }, { "name": "cc_diffuseMap", "defines": ["CC_USE_DIFFUSEMAP"] }], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCLocal", "defines": [] }, { "name": "CCForwardLight", "defines": ["CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }, { "name": "CCForwardLight", "defines": ["CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1131,7 +1136,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_USE_IBL", "type": "number", "range": [0, 2] }, { "name": "CC_USE_DIFFUSEMAP", "type": "number", "range": [0, 2] }, { "name": "USE_REFLECTION_DENOISE", "type": "boolean" }, @@ -1153,7 +1157,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 } ], "blocks": [], @@ -1184,11 +1188,11 @@ export const effects = [ "shaders": [ { "name": "planar-shadow|planar-shadow-vs:vert|planar-shadow-fs:frag", - "hash": 2743321009, + "hash": 3508735230, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 217, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 59 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["USE_BATCHING"] }, { "name": "CCLocal", "defines": [] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1197,7 +1201,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -1217,7 +1220,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 } ], @@ -1239,7 +1242,7 @@ export const effects = [ "shaders": [ { "name": "post-process|post-process-vs|post-process-fs", - "hash": 166324175, + "hash": 3459002230, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 147, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 39 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, @@ -1252,7 +1255,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_MORPH_TARGET_COUNT", "type": "number", "range": [2, 8] }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, @@ -1273,7 +1275,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 }, { "name": "a_jointAnimInfo", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION", "USE_INSTANCING"], "format": 44, "isInstanced": true, "location": 13 } ], @@ -1297,7 +1299,7 @@ export const effects = [ "shaders": [ { "name": "skybox|sky-vs:vert|sky-fs:frag", - "hash": 3763602160, + "hash": 3078878888, "builtins": { "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 39, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 39 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [{ "name": "cc_environment", "defines": [] }], "buffers": [], "images": [] }, @@ -1310,7 +1312,6 @@ export const effects = [ { "name": "USE_BATCHING", "type": "boolean" }, { "name": "CC_USE_MORPH", "type": "boolean" }, { "name": "CC_USE_SKINNING", "type": "boolean" }, - { "name": "CC_PLATFORM_NX", "type": "boolean" }, { "name": "CC_USE_IBL", "type": "number", "range": [0, 2] }, { "name": "CC_USE_HDR", "type": "boolean" }, { "name": "USE_RGBE_CUBEMAP", "type": "boolean" } @@ -1327,7 +1328,7 @@ export const effects = [ { "name": "a_localShadowBias", "defines": ["USE_INSTANCING", "CC_RECEIVE_SHADOW"], "format": 21, "isInstanced": true, "location": 10 }, { "name": "a_dyn_batch_id", "defines": ["!USE_INSTANCING", "USE_BATCHING"], "format": 11, "location": 11 }, { "name": "a_vertexId", "defines": ["CC_USE_MORPH"], "format": 11, "location": 12 }, - { "name": "a_joints", "defines": ["CC_USE_SKINNING", "!CC_PLATFORM_NX"], "location": 4 }, + { "name": "a_joints", "defines": ["CC_USE_SKINNING"], "location": 4 }, { "name": "a_weights", "defines": ["CC_USE_SKINNING"], "format": 44, "location": 5 } ], "blocks": [], diff --git a/cocos/core/builtin/shader-sources/glsl1.ts b/cocos/core/builtin/shader-sources/glsl1.ts index bd88448d30a..a719517621f 100644 --- a/cocos/core/builtin/shader-sources/glsl1.ts +++ b/cocos/core/builtin/shader-sources/glsl1.ts @@ -2,7 +2,7 @@ export const glsl1 = [ [ { - "vert": "\nprecision mediump float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp mat4 cc_matWorld;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n, mat4 viewInv\n) {\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n}\nattribute vec3 a_position;\nattribute vec2 a_texCoord;\nattribute vec4 a_color;\nuniform vec4 cc_size_rotation;\nvec4 vs_main() {\nvec4 pos = vec4(a_position, 1);\npos = cc_matWorld * pos;\nvec2 vertOffset = a_texCoord.xy - 0.5;\ncomputeVertPos(pos, vertOffset, quaternionFromEuler(vec3(0., 0., cc_size_rotation.z)), vec3(cc_size_rotation.xy, 0.), cc_matViewInv);\npos = cc_matViewProj * pos;\nuv = a_texCoord.xy;\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", + "vert": "\nprecision mediump float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n, mat4 viewInv\n) {\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n}\nattribute vec3 a_position;\nattribute vec2 a_texCoord;\nattribute vec4 a_color;\nuniform vec4 cc_size_rotation;\nvec4 vs_main() {\nvec4 pos = vec4(a_position, 1);\npos = cc_matWorld * pos;\nvec2 vertOffset = a_texCoord.xy - 0.5;\ncomputeVertPos(pos, vertOffset, quaternionFromEuler(vec3(0., 0., cc_size_rotation.z)), vec3(cc_size_rotation.xy, 0.), cc_matViewInv);\npos = cc_matViewProj * pos;\nuv = a_texCoord.xy;\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", "frag": "\nprecision mediump float;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying vec2 uv;\nvarying vec4 color;\nuniform sampler2D mainTexture;\nuniform vec4 tintColor;\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture2D(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nvoid main() { gl_FragColor = add(); }", } ], @@ -40,7 +40,7 @@ export const glsl1 = [ ], [ { - "vert": "\nprecision highp float;\nuniform highp mat4 cc_matViewProj;\nuniform highp mat4 cc_matWorld;\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\nattribute float a_dist;\nvarying float v_dist;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\npos = cc_matViewProj * cc_matWorld * pos;\nv_color = a_color;\nv_dist = a_dist;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nuniform highp mat4 cc_matViewProj;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\nattribute float a_dist;\nvarying float v_dist;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\npos = cc_matViewProj * cc_matWorld * pos;\nv_color = a_color;\nv_dist = a_dist;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\n#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives: enable\n#endif\nprecision highp float;\nvarying vec4 v_color;\nvarying float v_dist;\nvec4 frag () {\nvec4 o = v_color;\n#ifdef GL_OES_standard_derivatives\nfloat aa = fwidth(v_dist);\n#else\nfloat aa = 0.05;\n#endif\nfloat alpha = 1. - smoothstep(-aa, 0., abs(v_dist) - 1.0);\no.rgb *= o.a;\no *= alpha;\nreturn o;\n}\nvoid main() { gl_FragColor = frag(); }", } ], @@ -52,99 +52,99 @@ export const glsl1 = [ ], [ { - "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nuniform vec4 mainTiling_Offset;\nuniform vec4 frameTile_velLenScale;\nuniform vec4 scale;\nuniform vec4 nodeRotation;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nuniform vec4 u_sampleInfo;\nuniform vec4 u_worldRot;\nuniform vec4 u_timeDelta;\nattribute vec4 a_position_starttime;\nattribute vec4 a_size_uv;\nattribute vec4 a_rotation_uv;\nattribute vec4 a_color;\nattribute vec4 a_dir_life;\nattribute float a_rndSeed;\n#if CC_RENDER_MODE == 4\nattribute vec3 a_texCoord;\nattribute vec3 a_texCoord3;\nattribute vec3 a_normal;\nattribute vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nuniform int u_color_mode;\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nuniform int u_rotation_mode;\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nuniform int u_size_mode;\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nuniform int u_force_mode;\nuniform int u_force_space;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nuniform int u_velocity_mode;\nuniform int u_velocity_space;\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nuniform vec4 u_anim_info;\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture2D(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture2D(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture2D(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", + "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nuniform vec4 mainTiling_Offset;\nuniform vec4 frameTile_velLenScale;\nuniform vec4 scale;\nuniform vec4 nodeRotation;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nuniform vec4 u_sampleInfo;\nuniform vec4 u_worldRot;\nuniform vec4 u_timeDelta;\nattribute vec4 a_position_starttime;\nattribute vec4 a_size_uv;\nattribute vec4 a_rotation_uv;\nattribute vec4 a_color;\nattribute vec4 a_dir_life;\nattribute float a_rndSeed;\n#if CC_RENDER_MODE == 4\nattribute vec3 a_texCoord;\nattribute vec3 a_texCoord3;\nattribute vec3 a_normal;\nattribute vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture2D(tex, coord);\nvec4 b = texture2D(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nuniform int u_color_mode;\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nuniform int u_rotation_mode;\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nuniform int u_size_mode;\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nuniform int u_force_mode;\nuniform int u_force_space;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nuniform int u_velocity_mode;\nuniform int u_velocity_space;\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nuniform vec4 u_anim_info;\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture2D(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture2D(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture2D(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", "frag": "\nprecision mediump float;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying vec2 uv;\nvarying vec4 color;\nuniform sampler2D mainTexture;\nuniform vec4 tintColor;\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture2D(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nvoid main() { gl_FragColor = add(); }", } ], [ { - "vert": "\nprecision mediump float;\nuniform vec4 mainTiling_Offset;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nattribute vec3 a_position;\nattribute vec4 a_texCoord;\nattribute vec3 a_texCoord1;\nattribute vec3 a_texCoord2;\nattribute vec4 a_color;\n#if CC_DRAW_WIRE_FRAME\nvarying vec3 vBarycentric;\n#endif\nvec4 vs_main() {\nhighp vec4 pos = vec4(a_position, 1);\nvec4 velocity = vec4(a_texCoord1.xyz, 0);\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\nvelocity = cc_matWorld * velocity;\n#endif\nfloat vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;\nvec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));\npos.xyz += camUp * vertOffset;\npos = cc_matViewProj * pos;\nuv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;\ncolor = a_color;\n#if CC_DRAW_WIRE_FRAME\nvBarycentric = a_texCoord2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", + "vert": "\nprecision mediump float;\nuniform vec4 mainTiling_Offset;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nattribute vec3 a_position;\nattribute vec4 a_texCoord;\nattribute vec3 a_texCoord1;\nattribute vec3 a_texCoord2;\nattribute vec4 a_color;\n#if CC_DRAW_WIRE_FRAME\nvarying vec3 vBarycentric;\n#endif\nvec4 vs_main() {\nhighp vec4 pos = vec4(a_position, 1);\nvec4 velocity = vec4(a_texCoord1.xyz, 0);\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\nvelocity = cc_matWorld * velocity;\n#endif\nfloat vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;\nvec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));\npos.xyz += camUp * vertOffset;\npos = cc_matViewProj * pos;\nuv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;\ncolor = a_color;\n#if CC_DRAW_WIRE_FRAME\nvBarycentric = a_texCoord2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", "frag": "\nprecision mediump float;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying vec2 uv;\nvarying vec4 color;\n#if CC_DRAW_WIRE_FRAME\nvarying vec3 vBarycentric;\n#endif\nuniform sampler2D mainTexture;\nuniform vec4 tintColor;\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture2D(mainTexture, uv);\n#if CC_DRAW_WIRE_FRAME\nif (any(lessThan(vBarycentric, vec3(0.02)))) {\ncol = vec4(0., 1., 1., 1.);\n}\n#endif\nreturn CCFragOutput(col);\n}\nvoid main() { gl_FragColor = add(); }", } ], [ { - "vert": "\nprecision highp float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nuniform vec4 mainTiling_Offset;\nuniform vec4 frameTile_velLenScale;\nuniform vec4 scale;\nuniform vec4 nodeRotation;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nattribute vec3 a_position;\nattribute vec3 a_texCoord;\nattribute vec3 a_texCoord1;\nattribute vec3 a_texCoord2;\nattribute vec4 a_color;\n#if CC_RENDER_MODE == 1\nattribute vec3 a_color1;\n#endif\n#if CC_RENDER_MODE == 4\nattribute vec3 a_texCoord3;\nattribute vec3 a_normal;\nattribute vec4 a_color1;\n#endif\nvec4 lpvs_main () {\nvec3 compScale = scale.xyz * a_texCoord1;\nvec4 pos = vec4(a_position, 1);\n#if CC_RENDER_MODE == 1\nvec4 velocity = vec4(a_color1.xyz, 0);\n#endif\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = cc_matWorld * velocity;\n#endif\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nvec3 rotTmp = a_texCoord2;\nfloat mulFactor = 1.0;\nif (rotTmp.x > 10.0 * 0.5) {\nrotTmp.x -= 10.0;\nmulFactor = -1.0;\n}\nvec4 rot = vec4(rotTmp, 0.0);\nrot.w = mulFactor * sqrt(abs(1.0 - rot.x * rot.x - rot.y * rot.y - rot.z * rot.z));\n#else\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = a_texCoord2;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., a_texCoord2.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(a_texCoord2);\n#endif\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((a_texCoord.xy - 0.5));\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_matViewInv);\n#elif CC_RENDER_MODE == 1\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_cameraPos.xyz, velocity, frameTile_velLenScale.z, frameTile_velLenScale.w, a_texCoord.x);\n#elif 2\ncomputeVertPos(pos, cornerOffset, rot, compScale);\n#endif\ncolor = a_color;\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor = a_color * a_color1;\n#endif\nuv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\npos = cc_matViewProj * pos;\nreturn pos;\n}\nvoid main() { gl_Position = lpvs_main(); }", + "vert": "\nprecision highp float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nuniform vec4 mainTiling_Offset;\nuniform vec4 frameTile_velLenScale;\nuniform vec4 scale;\nuniform vec4 nodeRotation;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewInv;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nvarying mediump vec2 uv;\nvarying mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nattribute vec3 a_position;\nattribute vec3 a_texCoord;\nattribute vec3 a_texCoord1;\nattribute vec3 a_texCoord2;\nattribute vec4 a_color;\n#if CC_RENDER_MODE == 1\nattribute vec3 a_color1;\n#endif\n#if CC_RENDER_MODE == 4\nattribute vec3 a_texCoord3;\nattribute vec3 a_normal;\nattribute vec4 a_color1;\n#endif\nvec4 lpvs_main () {\nvec3 compScale = scale.xyz * a_texCoord1;\nvec4 pos = vec4(a_position, 1);\n#if CC_RENDER_MODE == 1\nvec4 velocity = vec4(a_color1.xyz, 0);\n#endif\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = cc_matWorld * velocity;\n#endif\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nvec3 rotTmp = a_texCoord2;\nfloat mulFactor = 1.0;\nif (rotTmp.x > 10.0 * 0.5) {\nrotTmp.x -= 10.0;\nmulFactor = -1.0;\n}\nvec4 rot = vec4(rotTmp, 0.0);\nrot.w = mulFactor * sqrt(abs(1.0 - rot.x * rot.x - rot.y * rot.y - rot.z * rot.z));\n#else\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = a_texCoord2;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., a_texCoord2.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(a_texCoord2);\n#endif\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((a_texCoord.xy - 0.5));\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_matViewInv);\n#elif CC_RENDER_MODE == 1\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_cameraPos.xyz, velocity, frameTile_velLenScale.z, frameTile_velLenScale.w, a_texCoord.x);\n#elif 2\ncomputeVertPos(pos, cornerOffset, rot, compScale);\n#endif\ncolor = a_color;\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor = a_color * a_color1;\n#endif\nuv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\npos = cc_matViewProj * pos;\nreturn pos;\n}\nvoid main() { gl_Position = lpvs_main(); }", "frag": "\nprecision mediump float;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying vec2 uv;\nvarying vec4 color;\nuniform sampler2D mainTexture;\nuniform vec4 tintColor;\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture2D(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nvoid main() { gl_FragColor = add(); }", } ], [ { - "vert": "\nprecision highp float;\nuniform highp mat4 cc_matViewProj;\n#if USE_LOCAL\nuniform highp mat4 cc_matWorld;\n#endif\nattribute vec3 a_position;\nattribute vec2 a_texCoord;\nattribute vec4 a_color;\nvarying vec4 v_light;\nvarying vec2 uv0;\n#if TWO_COLORED\nattribute vec4 a_color2;\nvarying vec4 v_dark;\n#endif\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\npos = cc_matViewProj * pos;\nuv0 = a_texCoord;\nv_light = a_color;\n#if TWO_COLORED\nv_dark = a_color2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nuniform highp mat4 cc_matViewProj;\n#if USE_LOCAL\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\n#endif\nattribute vec3 a_position;\nattribute vec2 a_texCoord;\nattribute vec4 a_color;\nvarying vec4 v_light;\nvarying vec2 uv0;\n#if TWO_COLORED\nattribute vec4 a_color2;\nvarying vec4 v_dark;\n#endif\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\npos = cc_matViewProj * pos;\nuv0 = a_texCoord;\nv_light = a_color;\n#if TWO_COLORED\nv_dark = a_color2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\n#if USE_ALPHA_TEST\nuniform float alphaThreshold;\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n#if USE_ALPHA_TEST\nif (color.a < alphaThreshold) discard;\n#endif\n}\nvoid ALPHA_TEST (in float alpha) {\n#if USE_ALPHA_TEST\nif (alpha < alphaThreshold) discard;\n#endif\n}\nvarying vec4 v_light;\n#if TWO_COLORED\nvarying vec4 v_dark;\n#endif\nvarying vec2 uv0;\nuniform sampler2D cc_spriteTexture;\nvec4 frag () {\nvec4 o = vec4(1, 1, 1, 1);\n#if TWO_COLORED\nvec4 texColor = vec4(1, 1, 1, 1);\ntexColor *= texture2D(cc_spriteTexture, uv0);\no.a = texColor.a * v_light.a;\no.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n#else\no *= texture2D(cc_spriteTexture, uv0);\no *= v_light;\n#endif\nALPHA_TEST(o);\nreturn o;\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\n#if USE_LOCAL\nuniform highp mat4 cc_matWorld;\n#endif\n#if SAMPLE_FROM_RT\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#endif\nattribute vec3 a_position;\nattribute vec2 a_texCoord;\nattribute vec4 a_color;\nvarying vec4 color;\nvarying vec2 uv0;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\n#if USE_PIXEL_ALIGNMENT\npos = cc_matView * pos;\npos.xyz = floor(pos.xyz);\npos = cc_matProj * pos;\n#else\npos = cc_matViewProj * pos;\n#endif\nuv0 = a_texCoord;\n#if SAMPLE_FROM_RT\nuv0 = cc_cameraPos.w > 1.0 ? vec2(uv0.x, 1.0 - uv0.y) : uv0;\n#endif\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\n#if USE_LOCAL\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\n#endif\n#if SAMPLE_FROM_RT\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#endif\nattribute vec3 a_position;\nattribute vec2 a_texCoord;\nattribute vec4 a_color;\nvarying vec4 color;\nvarying vec2 uv0;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\n#if USE_PIXEL_ALIGNMENT\npos = cc_matView * pos;\npos.xyz = floor(pos.xyz);\npos = cc_matProj * pos;\n#else\npos = cc_matViewProj * pos;\n#endif\nuv0 = a_texCoord;\n#if SAMPLE_FROM_RT\nuv0 = cc_cameraPos.w > 1.0 ? vec2(uv0.x, 1.0 - uv0.y) : uv0;\n#endif\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec4 CCSampleWithAlphaSeparated(sampler2D tex, vec2 uv) {\n#if CC_USE_EMBEDDED_ALPHA\nreturn vec4(texture2D(tex, uv).rgb, texture2D(tex, uv + vec2(0.0, 0.5)).r);\n#else\nreturn texture2D(tex, uv);\n#endif\n}\n#if USE_ALPHA_TEST\nuniform float alphaThreshold;\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n#if USE_ALPHA_TEST\nif (color.a < alphaThreshold) discard;\n#endif\n}\nvoid ALPHA_TEST (in float alpha) {\n#if USE_ALPHA_TEST\nif (alpha < alphaThreshold) discard;\n#endif\n}\nvarying vec4 color;\n#if USE_TEXTURE\nvarying vec2 uv0;\nuniform sampler2D cc_spriteTexture;\n#endif\nvec4 frag () {\nvec4 o = vec4(1, 1, 1, 1);\n#if USE_TEXTURE\no *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);\n#if IS_GRAY\nfloat gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;\no.r = o.g = o.b = gray;\n#endif\n#endif\no *= color;\nALPHA_TEST(o);\nreturn o;\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\nuniform highp vec4 cc_lightingMapUVParam;\nuniform highp vec4 cc_localShadowBias;\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nvarying highp vec4 v_shadowPos;\nuniform highp mat4 cc_matLightViewProj;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nattribute vec4 a_color;\nvarying vec4 v_color;\n#endif\nvarying vec3 v_position;\nvarying vec3 v_normal;\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvarying vec3 v_tangent;\nvarying vec3 v_bitangent;\n#endif\n#if HAS_SECOND_UV || USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_bitangent = cross(v_normal, v_tangent) * In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", - "frag": "\n#ifdef GL_EXT_draw_buffers\n#extension GL_EXT_draw_buffers: enable\n#endif\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\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\nuniform vec4 albedo;\nuniform vec4 albedoScaleAndCutoff;\nuniform vec4 pbrParams;\nuniform vec4 emissive;\nuniform vec4 emissiveScaleParam;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nvarying highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nuniform sampler2D cc_lightingMap;\n#endif\nvarying vec3 v_position;\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\nvarying vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nvarying vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nvarying vec3 v_tangent;\nvarying vec3 v_bitangent;\nuniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nuniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nuniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nuniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nuniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture2D(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture2D(cc_lightingMap, v_luv.xy);\ns.lightmap = lightColor.xyz * v_luv.z;\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture2D(normalMap, NORMAL_UV).xyz - vec3(0.5);\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent) +\n(nmmp.y * emissiveScaleParam.w) * normalize(v_bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture2D(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture2D(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture2D(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture2D(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\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\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nvoid main () {\nStandardSurface s; surf(s);\ngl_FragData[0] = s.albedo;\ngl_FragData[1] = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\ngl_FragData[2] = vec4(s.emissive, s.occlusion);\n}\n#endif", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#endif\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\nuniform highp vec4 cc_lightingMapUVParam;\nuniform highp vec4 cc_localShadowBias;\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nvarying highp vec4 v_shadowPos;\nuniform highp mat4 cc_matLightViewProj;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nattribute vec4 a_color;\nvarying vec4 v_color;\n#endif\nvarying vec3 v_position;\nvarying vec3 v_normal;\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvarying vec3 v_tangent;\nvarying vec3 v_bitangent;\n#endif\n#if HAS_SECOND_UV || USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.zw;\nv_luv.z = cc_lightingMapUVParam.z;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.zw;\nv_luv.z = a_lightingMapUVParam.z;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_bitangent = cross(v_normal, v_tangent) * In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", + "frag": "\n#ifdef GL_EXT_draw_buffers\n#extension GL_EXT_draw_buffers: enable\n#endif\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\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\nuniform vec4 albedo;\nuniform vec4 albedoScaleAndCutoff;\nuniform vec4 pbrParams;\nuniform vec4 emissive;\nuniform vec4 emissiveScaleParam;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\n#if USE_BATCHING\n#endif\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nvarying highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nuniform sampler2D cc_lightingMap;\nvec3 UnpackLightingmap(vec4 color) {\nvec3 c;\nfloat e = 1.0 + color.a * (8.0 - 1.0);\nc.r = color.r * e;\nc.g = color.g * e;\nc.b = color.b * e;\nreturn c;\n}\n#endif\nvarying vec3 v_position;\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\nvarying vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nvarying vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nvarying vec3 v_tangent;\nvarying vec3 v_bitangent;\nuniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nuniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nuniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nuniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nuniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture2D(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture2D(cc_lightingMap, v_luv.xy);\ns.lightmap = UnpackLightingmap(lightColor);\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture2D(normalMap, NORMAL_UV).xyz - vec3(0.5);\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent) +\n(nmmp.y * emissiveScaleParam.w) * normalize(v_bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture2D(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture2D(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture2D(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture2D(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\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\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nvoid main () {\nStandardSurface s; surf(s);\ngl_FragData[0] = s.albedo;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\ngl_FragData[1] = vec4(position, s.roughness);\ngl_FragData[1] = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor3 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\nuniform highp mat4 cc_matLightViewProj;\n#if HAS_SECOND_UV || USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", - "frag": "\nprecision highp float;\nuniform vec4 albedo;\nuniform vec4 albedoScaleAndCutoff;\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nuniform highp mat4 cc_matLightView;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture2D(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nvoid main() { gl_FragColor = frag(); }", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#endif\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\nuniform highp mat4 cc_matLightViewProj;\n#if HAS_SECOND_UV || USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "frag": "\nprecision highp float;\nuniform vec4 albedo;\nuniform vec4 albedoScaleAndCutoff;\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nuniform highp mat4 cc_matLightView;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\n#if USE_BATCHING\n#endif\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\nvarying vec2 v_uv;\nvarying vec2 v_uv1;\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture2D(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision mediump float;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform highp mat4 cc_matWorld;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nvarying highp vec4 v_shadowPos;\nuniform highp mat4 cc_matLightViewProj;\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\n#endif\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\nvarying highp vec3 v_position;\nvarying mediump vec3 v_normal;\n#if USE_NORMALMAP\nvarying mediump vec3 v_tangent;\nvarying mediump vec3 v_binormal;\n#endif\nvarying mediump vec2 uvw;\nvarying mediump vec2 uv0;\nvarying mediump vec2 uv1;\nvarying mediump vec2 uv2;\nvarying mediump vec2 uv3;\nvarying mediump vec3 luv;\nvarying mediump vec3 diffuse;\nuniform vec4 UVScale;\nuniform vec4 lightMapUVParam;\nvoid main () {\nvec3 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nvec4 pos = vec4(worldPos, 1.0);\npos = cc_matViewProj * pos;\nuvw = a_texCoord;\nuv0 = a_position.xz * UVScale.x;\nuv1 = a_position.xz * UVScale.y;\nuv2 = a_position.xz * UVScale.z;\nuv3 = a_position.xz * UVScale.w;\n#if USE_LIGHTMAP\nluv.xy = lightMapUVParam.xy + a_texCoord * lightMapUVParam.z;\nluv.z = lightMapUVParam.w;\n#endif\nv_position = worldPos;\nv_normal = a_normal;\nCC_TRANSFER_FOG(vec4(worldPos, 1.0));\n#if CC_RECEIVE_SHADOW\nv_shadowBias = vec2(0.0, 0.0);\n#endif\n#if USE_NORMALMAP\nv_tangent = vec3(1.0, 0.0, 0.0);\nv_binormal = vec3(0.0, 0.0, 1.0);\nv_binormal = cross(v_tangent, a_normal);\nv_tangent = cross(a_normal, v_binormal);\n#endif\nv_shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0);\ngl_Position = pos;\n}", - "frag": "\n#ifdef GL_EXT_draw_buffers\n#extension GL_EXT_draw_buffers: enable\n#endif\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\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\nvarying highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nuniform sampler2D cc_lightingMap;\n#endif\nvarying highp vec3 v_position;\nvarying mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\n#if USE_NORMALMAP\nvarying mediump vec3 v_tangent;\nvarying mediump vec3 v_binormal;\n#endif\nvarying mediump vec2 uvw;\nvarying mediump vec2 uv0;\nvarying mediump vec2 uv1;\nvarying mediump vec2 uv2;\nvarying mediump vec2 uv3;\nvarying mediump vec3 diffuse;\nvarying mediump vec3 luv;\nuniform vec4 metallic;\nuniform vec4 roughness;\nuniform sampler2D weightMap;\nuniform sampler2D detailMap0;\nuniform sampler2D detailMap1;\nuniform sampler2D detailMap2;\nuniform sampler2D detailMap3;\nuniform sampler2D normalMap0;\nuniform sampler2D normalMap1;\nuniform sampler2D normalMap2;\nuniform sampler2D normalMap3;\nuniform sampler2D lightMap;\nvoid surf (out StandardSurface s) {\n#if LAYERS > 1\nvec4 w = texture2D(weightMap, uvw);\n#endif\nvec4 baseColor = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseColor = texture2D(detailMap0, uv0);\n#elif LAYERS == 2\nbaseColor += texture2D(detailMap0, uv0) * w.r;\nbaseColor += texture2D(detailMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseColor += texture2D(detailMap0, uv0) * w.r;\nbaseColor += texture2D(detailMap1, uv1) * w.g;\nbaseColor += texture2D(detailMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseColor += texture2D(detailMap0, uv0) * w.r;\nbaseColor += texture2D(detailMap1, uv1) * w.g;\nbaseColor += texture2D(detailMap2, uv2) * w.b;\nbaseColor += texture2D(detailMap3, uv3) * w.a;\n#else\nbaseColor = texture2D(detailMap0, uv0);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\n#if USE_NORMALMAP\nvec4 baseNormal = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseNormal = texture2D(normalMap0, uv0);\n#elif LAYERS == 2\nbaseNormal += texture2D(normalMap0, uv0) * w.r;\nbaseNormal += texture2D(normalMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseNormal += texture2D(normalMap0, uv0) * w.r;\nbaseNormal += texture2D(normalMap1, uv1) * w.g;\nbaseNormal += texture2D(normalMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseNormal += texture2D(normalMap0, uv0) * w.r;\nbaseNormal += texture2D(normalMap1, uv1) * w.g;\nbaseNormal += texture2D(normalMap2, uv2) * w.b;\nbaseNormal += texture2D(normalMap3, uv3) * w.a;\n#else\nbaseNormal = texture2D(normalMap0, uv0);\n#endif\nvec3 nmmp = baseNormal.xyz - vec3(0.5);\ns.normal =\nnmmp.x * normalize(v_tangent) +\nnmmp.y * normalize(v_binormal) +\nnmmp.z * normalize(v_normal);\n#else\ns.normal = v_normal;\n#endif\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\ns.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0);\ns.occlusion = 1.0;\n#if USE_PBR\ns.roughness = 0.0;\n#if LAYERS == 1\ns.roughness = roughness.x;\n#elif LAYERS == 2\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\n#elif LAYERS == 3\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\n#elif LAYERS == 4\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\ns.roughness += roughness.w * w.a;\n#else\ns.roughness = 1.0;\n#endif\ns.metallic = 0.0;\n#if LAYERS == 1\ns.metallic = metallic.x;\n#elif LAYERS == 2\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\n#elif LAYERS == 3\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\n#elif LAYERS == 4\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\ns.metallic += metallic.w * w.a;\n#else\ns.metallic = 0.0;\n#endif\n#else\ns.roughness = 1.0;\ns.metallic = 0.0;\n#endif\ns.emissive = vec3(0.0, 0.0, 0.0);\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture2D(lightMap, luv.xy);\ns.lightmap = lightColor.xyz * luv.z;\ns.lightmap_test = luv.z;\n#endif\n}\n#if CC_FORWARD_ADD\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\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nvoid main () {\nStandardSurface s; surf(s);\ngl_FragData[0] = s.albedo;\ngl_FragData[1] = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\ngl_FragData[2] = vec4(s.emissive, s.occlusion);\n}\n#endif", + "vert": "\nprecision mediump float;\nuniform highp mat4 cc_matViewProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nvarying highp vec4 v_shadowPos;\nuniform highp mat4 cc_matLightViewProj;\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\n#endif\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\nvarying highp vec3 v_position;\nvarying mediump vec3 v_normal;\n#if USE_NORMALMAP\nvarying mediump vec3 v_tangent;\nvarying mediump vec3 v_binormal;\n#endif\nvarying mediump vec2 uvw;\nvarying mediump vec2 uv0;\nvarying mediump vec2 uv1;\nvarying mediump vec2 uv2;\nvarying mediump vec2 uv3;\nvarying mediump vec3 luv;\nvarying mediump vec3 diffuse;\nuniform vec4 UVScale;\nuniform vec4 lightMapUVParam;\nvoid main () {\nvec3 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nvec4 pos = vec4(worldPos, 1.0);\npos = cc_matViewProj * pos;\nuvw = a_texCoord;\nuv0 = a_position.xz * UVScale.x;\nuv1 = a_position.xz * UVScale.y;\nuv2 = a_position.xz * UVScale.z;\nuv3 = a_position.xz * UVScale.w;\n#if USE_LIGHTMAP\nluv.xy = lightMapUVParam.xy + a_texCoord * lightMapUVParam.zw;\nluv.z = lightMapUVParam.z;\n#endif\nv_position = worldPos;\nv_normal = a_normal;\nCC_TRANSFER_FOG(vec4(worldPos, 1.0));\n#if CC_RECEIVE_SHADOW\nv_shadowBias = vec2(0.0, 0.0);\n#endif\n#if USE_NORMALMAP\nv_tangent = vec3(1.0, 0.0, 0.0);\nv_binormal = vec3(0.0, 0.0, 1.0);\nv_binormal = cross(v_tangent, a_normal);\nv_tangent = cross(a_normal, v_binormal);\n#endif\nv_shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0);\ngl_Position = pos;\n}", + "frag": "\n#ifdef GL_EXT_draw_buffers\n#extension GL_EXT_draw_buffers: enable\n#endif\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\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\n#if USE_BATCHING\n#endif\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\nvarying highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nuniform sampler2D cc_lightingMap;\nvec3 UnpackLightingmap(vec4 color) {\nvec3 c;\nfloat e = 1.0 + color.a * (8.0 - 1.0);\nc.r = color.r * e;\nc.g = color.g * e;\nc.b = color.b * e;\nreturn c;\n}\n#endif\nvarying highp vec3 v_position;\nvarying mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nvarying vec2 v_shadowBias;\n#endif\n#if USE_NORMALMAP\nvarying mediump vec3 v_tangent;\nvarying mediump vec3 v_binormal;\n#endif\nvarying mediump vec2 uvw;\nvarying mediump vec2 uv0;\nvarying mediump vec2 uv1;\nvarying mediump vec2 uv2;\nvarying mediump vec2 uv3;\nvarying mediump vec3 diffuse;\nvarying mediump vec3 luv;\nuniform vec4 metallic;\nuniform vec4 roughness;\nuniform sampler2D weightMap;\nuniform sampler2D detailMap0;\nuniform sampler2D detailMap1;\nuniform sampler2D detailMap2;\nuniform sampler2D detailMap3;\nuniform sampler2D normalMap0;\nuniform sampler2D normalMap1;\nuniform sampler2D normalMap2;\nuniform sampler2D normalMap3;\nuniform sampler2D lightMap;\nvoid surf (out StandardSurface s) {\n#if LAYERS > 1\nvec4 w = texture2D(weightMap, uvw);\n#endif\nvec4 baseColor = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseColor = texture2D(detailMap0, uv0);\n#elif LAYERS == 2\nbaseColor += texture2D(detailMap0, uv0) * w.r;\nbaseColor += texture2D(detailMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseColor += texture2D(detailMap0, uv0) * w.r;\nbaseColor += texture2D(detailMap1, uv1) * w.g;\nbaseColor += texture2D(detailMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseColor += texture2D(detailMap0, uv0) * w.r;\nbaseColor += texture2D(detailMap1, uv1) * w.g;\nbaseColor += texture2D(detailMap2, uv2) * w.b;\nbaseColor += texture2D(detailMap3, uv3) * w.a;\n#else\nbaseColor = texture2D(detailMap0, uv0);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\n#if USE_NORMALMAP\nvec4 baseNormal = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseNormal = texture2D(normalMap0, uv0);\n#elif LAYERS == 2\nbaseNormal += texture2D(normalMap0, uv0) * w.r;\nbaseNormal += texture2D(normalMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseNormal += texture2D(normalMap0, uv0) * w.r;\nbaseNormal += texture2D(normalMap1, uv1) * w.g;\nbaseNormal += texture2D(normalMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseNormal += texture2D(normalMap0, uv0) * w.r;\nbaseNormal += texture2D(normalMap1, uv1) * w.g;\nbaseNormal += texture2D(normalMap2, uv2) * w.b;\nbaseNormal += texture2D(normalMap3, uv3) * w.a;\n#else\nbaseNormal = texture2D(normalMap0, uv0);\n#endif\nvec3 nmmp = baseNormal.xyz - vec3(0.5);\ns.normal =\nnmmp.x * normalize(v_tangent) +\nnmmp.y * normalize(v_binormal) +\nnmmp.z * normalize(v_normal);\n#else\ns.normal = v_normal;\n#endif\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\ns.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0);\ns.occlusion = 1.0;\n#if USE_PBR\ns.roughness = 0.0;\n#if LAYERS == 1\ns.roughness = roughness.x;\n#elif LAYERS == 2\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\n#elif LAYERS == 3\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\n#elif LAYERS == 4\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\ns.roughness += roughness.w * w.a;\n#else\ns.roughness = 1.0;\n#endif\ns.metallic = 0.0;\n#if LAYERS == 1\ns.metallic = metallic.x;\n#elif LAYERS == 2\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\n#elif LAYERS == 3\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\n#elif LAYERS == 4\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\ns.metallic += metallic.w * w.a;\n#else\ns.metallic = 0.0;\n#endif\n#else\ns.roughness = 1.0;\ns.metallic = 0.0;\n#endif\ns.emissive = vec3(0.0, 0.0, 0.0);\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture2D(lightMap, luv.xy);\ns.lightmap = UnpackLightingmap(lightColor);\ns.lightmap_test = luv.z;\n#endif\n}\n#if CC_FORWARD_ADD\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\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nvoid main () {\nStandardSurface s; surf(s);\ngl_FragData[0] = s.albedo;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\ngl_FragData[1] = vec4(position, s.roughness);\ngl_FragData[1] = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor3 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matLightViewProj;\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nvarying vec2 v_clip_depth;\nvec4 vert () {\nvec4 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nworldPos.w = 1.0;\nvec4 clipPos = cc_matLightViewProj * worldPos;\nv_clip_depth = clipPos.zw;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#if USE_BATCHING\n#endif\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matLightViewProj;\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nvarying vec2 v_clip_depth;\nvec4 vert () {\nvec4 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nworldPos.w = 1.0;\nvec4 clipPos = cc_matLightViewProj * worldPos;\nv_clip_depth = clipPos.zw;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nvarying vec2 v_clip_depth;\nvec4 frag () {\nreturn packDepthToRGBA(v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5);\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nattribute lowp vec4 a_color;\nvarying lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nvarying vec2 v_uv;\nuniform vec4 tilingOffset;\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#endif\nuniform highp mat4 cc_matWorld;\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nattribute lowp vec4 a_color;\nvarying lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nvarying vec2 v_uv;\nuniform vec4 tilingOffset;\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#if USE_ALPHA_TEST\n#endif\n#if USE_TEXTURE\nvarying vec2 v_uv;\nuniform sampler2D mainTexture;\n#endif\nuniform vec4 mainColor;\nuniform vec4 colorScaleAndCutoff;\n#if USE_VERTEX_COLOR\nvarying lowp vec4 v_color;\n#endif\nvec4 frag () {\nvec4 o = mainColor;\no.rgb *= colorScaleAndCutoff.xyz;\n#if USE_VERTEX_COLOR\no.rgb *= SRGBToLinear(v_color.rgb);\no.a *= v_color.a;\n#endif\n#if USE_TEXTURE\nvec4 texColor = texture2D(mainTexture, v_uv);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\no *= texColor;\n#endif\n#if USE_ALPHA_TEST\nif (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;\n#endif\nCC_APPLY_FOG(o);\nreturn CCFragOutput(o);\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D outputResultMap;\nfloat luminance(vec3 color) {\nreturn dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\nvoid main() {\nvec3 color = texture2D(outputResultMap, v_uv).xyz;\nif (luminance(SRGBToLinear(color)) > texSize.z) {\ngl_FragColor = vec4(color, 1.0);\n} else {\ngl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n}", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D bloomTexture;\nvec3 downsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture2D(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main()\n{\nvec3 result = downsample4taps(v_uv, 1.0 / texSize.xy).rgb;\ngl_FragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D bloomTexture;\nvec3 upsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture2D(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main() {\nvec3 result = upsample4taps(v_uv, 0.5 / texSize.xy).rgb;\ngl_FragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D outputResultMap;\nuniform sampler2D bloomTexture;\nvoid main() {\nvec4 hdrColor = texture2D(outputResultMap, v_uv);\nvec3 bloomColor = texture2D(bloomTexture, v_uv).rgb;\nvec3 result = hdrColor.rgb + bloomColor * texSize.w * hdrColor.a;\ngl_FragColor = vec4(result, hdrColor.a);\n}", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nvec4 position;\nposition = vec4(a_position, 1.0);\nposition.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\ngl_Position = vec4(position.x, position.y, 1.0, 1.0);\nv_uv = a_texCoord;\n}", - "frag": "\n#ifdef GL_EXT_shader_framebuffer_fetch\n#extension GL_EXT_shader_framebuffer_fetch: enable\n#endif\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\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewProjInv;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp mat4 cc_matLightViewProj;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn 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\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec3 oct_to_float32x3(vec2 e) {\nvec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\nif (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\nreturn normalize(v);\n}\nvec4 screen2WS(vec3 coord) {\nvec3 ndc = vec3(\n2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n2.0 * coord.z - 1.0);\nvec4 world = ((cc_matViewProjInv) * (vec4(ndc, 1.0)));\nworld = world / world.w;\nreturn world;\n}\nvarying vec2 v_uv;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\n#else\nuniform sampler2D gbuffer_albedoMap;\nuniform sampler2D gbuffer_normalMap;\nuniform sampler2D gbuffer_emissiveMap;\n#endif\nuniform sampler2D depth_stencil;\n#if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450\n#endif\nvoid main () {\nStandardSurface s;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nvec4 albedoMap = gl_LastFragData[0];\nvec4 normalMap = gl_LastFragData[1];\nvec4 emissiveMap = gl_LastFragDat[2];\n#else\nvec4 albedoMap = texture2D(gbuffer_albedoMap,v_uv);\nvec4 normalMap = texture2D(gbuffer_normalMap,v_uv);\nvec4 emissiveMap = texture2D(gbuffer_emissiveMap,v_uv);\n#endif\nfloat depth = texture2D(depth_stencil, v_uv).x;\ns.albedo = albedoMap;\nvec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\ns.position = position;\ns.roughness = normalMap.z;\ns.normal = oct_to_float32x3(normalMap.xy);\ns.metallic = normalMap.w;\ns.emissive = emissiveMap.xyz;\ns.occlusion = emissiveMap.w;\nfloat fogFactor;\nCC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\nvec4 shadowPos;\nshadowPos = cc_matLightViewProj * vec4(position, 1);\nvec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nCCClusterShadingAdditive(s, shadowPos);\n#else\nCCStandardShadingAdditive(s, shadowPos);\n#endif\nCC_APPLY_FOG_BASE(color, fogFactor);\ncolor = CCFragOutput(color);\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\ngl_FragData[2] = color;\n#else\ngl_FragColor = color;\n#endif\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nvec4 position;\nposition = vec4(a_position, 1.0);\nposition.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\ngl_Position = vec4(position.x, position.y, 1.0, 1.0);\nv_uv = a_texCoord;\n}", + "frag": "\n#ifdef GL_EXT_shader_framebuffer_fetch\n#extension GL_EXT_shader_framebuffer_fetch: enable\n#endif\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\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matViewProjInv;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp mat4 cc_matLightViewProj;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\n#if USE_BATCHING\n#endif\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture2D(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture2D(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture2D(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture2D(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn 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\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec3 oct_to_float32x3(vec2 e) {\nvec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\nif (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\nreturn normalize(v);\n}\nvec4 screen2WS(vec3 coord) {\nvec3 ndc = vec3(\n2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n2.0 * coord.z - 1.0);\nvec4 world = ((cc_matViewProjInv) * (vec4(ndc, 1.0)));\nworld = world / world.w;\nreturn world;\n}\nvarying vec2 v_uv;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\n#else\nuniform sampler2D gbuffer_albedoMap;\nuniform sampler2D gbuffer_normalMap;\nuniform sampler2D gbuffer_emissiveMap;\n#endif\nuniform sampler2D depth_stencil;\n#if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450\n#endif\nvoid main () {\nStandardSurface s;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nvec4 albedoMap = gl_LastFragData[0];\nvec4 normalMap = gl_LastFragData[1];\nvec4 emissiveMap = gl_LastFragDat[2];\n#else\nvec4 albedoMap = texture2D(gbuffer_albedoMap,v_uv);\nvec4 normalMap = texture2D(gbuffer_normalMap,v_uv);\nvec4 emissiveMap = texture2D(gbuffer_emissiveMap,v_uv);\n#endif\nfloat depth = texture2D(depth_stencil, v_uv).x;\ns.albedo = albedoMap;\nvec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\ns.position = position;\ns.roughness = normalMap.z;\ns.normal = oct_to_float32x3(normalMap.xy);\ns.metallic = normalMap.w;\ns.emissive = emissiveMap.xyz;\ns.occlusion = emissiveMap.w;\nfloat fogFactor;\nCC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\nvec4 shadowPos;\nshadowPos = cc_matLightViewProj * vec4(position, 1);\nvec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nCCClusterShadingAdditive(s, shadowPos);\n#else\nCCStandardShadingAdditive(s, shadowPos);\n#endif\nCC_APPLY_FOG_BASE(color, fogFactor);\ncolor = CCFragOutput(color);\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\ngl_FragData[2] = color;\n#else\ngl_FragColor = color;\n#endif\n}", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nuniform mediump vec4 cc_planarNDInfo;\nvarying float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#endif\nuniform highp mat4 cc_matWorld;\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nuniform mediump vec4 cc_planarNDInfo;\nvarying float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nuniform lowp vec4 cc_shadowColor;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying float v_dist;\nvec4 frag () {\nif(v_dist < 0.0)\ndiscard;\nreturn CCFragOutput(cc_shadowColor);\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nattribute highp vec4 a_jointAnimInfo;\n#endif\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nuniform mediump vec4 cc_screenSize;\n#if ANTIALIAS_TYPE == 1\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\nvec2 v_rgbNW, vec2 v_rgbNE,\nvec2 v_rgbSW, vec2 v_rgbSE,\nvec2 v_rgbM) {\nvec4 color;\nmediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\nvec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\nvec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\nvec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\nvec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\nvec4 texColor = texture2D(tex, v_rgbM);\nvec3 rgbM = texColor.xyz;\nvec3 luma = vec3(0.299, 0.587, 0.114);\nfloat lumaNW = dot(rgbNW, luma);\nfloat lumaNE = dot(rgbNE, luma);\nfloat lumaSW = dot(rgbSW, luma);\nfloat lumaSE = dot(rgbSE, luma);\nfloat lumaM = dot(rgbM, luma);\nfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\nfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\nmediump vec2 dir;\ndir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\ndir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\nfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n(0.25 * (1.0 / 8.0)), (1.0/ 128.0));\nfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\ndir = min(vec2(8.0, 8.0),\nmax(vec2(-8.0, -8.0),\ndir * rcpDirMin)) * inverseVP;\nvec3 rgbA = 0.5 * (\ntexture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\ntexture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\nvec3 rgbB = rgbA * 0.5 + 0.25 * (\ntexture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\ntexture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\nfloat lumaB = dot(rgbB, luma);\nif ((lumaB < lumaMin) || (lumaB > lumaMax))\ncolor = vec4(rgbA, texColor.a);\nelse\ncolor = vec4(rgbB, texColor.a);\nreturn color;\n}\n#endif\nvarying vec2 v_uv;\nuniform sampler2D outputResultMap;\nvoid texcoords(vec2 fragCoord, vec2 resolution,\nout vec2 v_rgbNW, out vec2 v_rgbNE,\nout vec2 v_rgbSW, out vec2 v_rgbSE,\nout vec2 v_rgbM) {\nvec2 inverseVP = 1.0 / resolution.xy;\nv_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\nv_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\nv_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\nv_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\nv_rgbM = vec2(fragCoord * inverseVP);\n}\nvoid main () {\nmediump vec2 v_rgbNW;\nmediump vec2 v_rgbNE;\nmediump vec2 v_rgbSW;\nmediump vec2 v_rgbSE;\nmediump vec2 v_rgbM;\n#if ANTIALIAS_TYPE == 1\nvec2 resolution = cc_screenSize.xy;\nvec2 fragCoord = v_uv * resolution;\ntexcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\ngl_FragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n#else\ngl_FragColor = texture2D(outputResultMap, v_uv);\n#endif\n}", } ], [ { - "vert": "\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\nvarying mediump vec4 viewDir;\nvec4 vert () {\nviewDir = vec4(a_position, 1.0);\nmat4 matViewRotOnly = mat4(mat3(cc_matView));\nvec4 pos = matViewRotOnly * viewDir;\nif (cc_matProj[3].w > 0.0) {\nmat4 matProj = cc_matProj;\nmatProj[0].x = 5.2;\nmatProj[1].y = 2.6;\nmatProj[2].zw = vec2(-1.0);\nmatProj[3].zw = vec2(0.0);\npos = matProj * pos;\n} else {\npos = cc_matProj * pos;\n}\npos.z = 0.99999 * pos.w;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if USE_INSTANCING\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\nvarying mediump vec4 viewDir;\nvec4 vert () {\nviewDir = vec4(a_position, 1.0);\nmat4 matViewRotOnly = mat4(mat3(cc_matView));\nvec4 pos = matViewRotOnly * viewDir;\nif (cc_matProj[3].w > 0.0) {\nmat4 matProj = cc_matProj;\nmatProj[0].x = 5.2;\nmatProj[1].y = 2.6;\nmatProj[2].zw = vec2(-1.0);\nmatProj[3].zw = vec2(0.0);\npos = matProj * pos;\n} else {\npos = cc_matProj * pos;\n}\npos.z = 0.99999 * pos.w;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nuniform mediump vec4 cc_ambientSky;\nuniform samplerCube cc_environment;\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nvarying mediump vec4 viewDir;\nvec4 frag () {\n#if USE_RGBE_CUBEMAP\nvec3 c = unpackRGBE(textureCube(cc_environment, viewDir.xyz));\n#else\nvec3 c = SRGBToLinear(textureCube(cc_environment, viewDir.xyz).rgb);\n#endif\nreturn CCFragOutput(vec4(c * cc_ambientSky.w, 1.0));\n}\nvoid main() { gl_FragColor = frag(); }", } ], diff --git a/cocos/core/builtin/shader-sources/glsl3.ts b/cocos/core/builtin/shader-sources/glsl3.ts index 584595d346c..f5daac73714 100644 --- a/cocos/core/builtin/shader-sources/glsl3.ts +++ b/cocos/core/builtin/shader-sources/glsl3.ts @@ -2,7 +2,7 @@ export const glsl3 = [ [ { - "vert": "\nprecision mediump float;\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n, mat4 viewInv\n) {\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n}\nin vec3 a_position;\nin vec2 a_texCoord;\nin vec4 a_color;\nlayout(std140) uniform builtin {\nvec4 cc_size_rotation;\n};\nvec4 vs_main() {\nvec4 pos = vec4(a_position, 1);\npos = cc_matWorld * pos;\nvec2 vertOffset = a_texCoord.xy - 0.5;\ncomputeVertPos(pos, vertOffset, quaternionFromEuler(vec3(0., 0., cc_size_rotation.z)), vec3(cc_size_rotation.xy, 0.), cc_matViewInv);\npos = cc_matViewProj * pos;\nuv = a_texCoord.xy;\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", + "vert": "\nprecision mediump float;\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n, mat4 viewInv\n) {\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n}\nin vec3 a_position;\nin vec2 a_texCoord;\nin vec4 a_color;\nlayout(std140) uniform builtin {\nvec4 cc_size_rotation;\n};\nvec4 vs_main() {\nvec4 pos = vec4(a_position, 1);\npos = cc_matWorld * pos;\nvec2 vertOffset = a_texCoord.xy - 0.5;\ncomputeVertPos(pos, vertOffset, quaternionFromEuler(vec3(0., 0., cc_size_rotation.z)), vec3(cc_size_rotation.xy, 0.), cc_matViewInv);\npos = cc_matViewProj * pos;\nuv = a_texCoord.xy;\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nin vec2 uv;\nin vec4 color;\nuniform sampler2D mainTexture;\nlayout(std140) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], @@ -40,7 +40,7 @@ export const glsl3 = [ ], [ { - "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\nin float a_dist;\nout float v_dist;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\npos = cc_matViewProj * cc_matWorld * pos;\nv_color = a_color;\nv_dist = a_dist;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\nin float a_dist;\nout float v_dist;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\npos = cc_matViewProj * cc_matWorld * pos;\nv_color = a_color;\nv_dist = a_dist;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nin vec4 v_color;\nin float v_dist;\nvec4 frag () {\nvec4 o = v_color;\nfloat aa = fwidth(v_dist);\nfloat alpha = 1. - smoothstep(-aa, 0., abs(v_dist) - 1.0);\no.rgb *= o.a;\no *= alpha;\nreturn o;\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], @@ -52,99 +52,99 @@ export const glsl3 = [ ], [ { - "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(std140) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(std140) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nin vec4 a_position_starttime;\nin vec4 a_size_uv;\nin vec4 a_rotation_uv;\nin vec4 a_color;\nin vec4 a_dir_life;\nin float a_rndSeed;\n#if CC_RENDER_MODE == 4\nin vec3 a_texCoord;\nin vec3 a_texCoord3;\nin vec3 a_normal;\nin vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nlayout(std140) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nlayout(std140) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nlayout(std140) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nlayout(std140) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nlayout(std140) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nlayout(std140) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", + "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(std140) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(std140) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nin vec4 a_position_starttime;\nin vec4 a_size_uv;\nin vec4 a_rotation_uv;\nin vec4 a_color;\nin vec4 a_dir_life;\nin float a_rndSeed;\n#if CC_RENDER_MODE == 4\nin vec3 a_texCoord;\nin vec3 a_texCoord3;\nin vec3 a_normal;\nin vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nuniform sampler2D color_over_time_tex0;\nlayout(std140) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nuniform sampler2D rotation_over_time_tex0;\nlayout(std140) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D size_over_time_tex0;\nlayout(std140) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nuniform sampler2D force_over_time_tex0;\nlayout(std140) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nuniform sampler2D velocity_over_time_tex0;\nlayout(std140) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nuniform sampler2D texture_animation_tex0;\nlayout(std140) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nin vec2 uv;\nin vec4 color;\nuniform sampler2D mainTexture;\nlayout(std140) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], [ { - "vert": "\nprecision mediump float;\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nin vec3 a_position;\nin vec4 a_texCoord;\nin vec3 a_texCoord1;\nin vec3 a_texCoord2;\nin vec4 a_color;\n#if CC_DRAW_WIRE_FRAME\nout vec3 vBarycentric;\n#endif\nvec4 vs_main() {\nhighp vec4 pos = vec4(a_position, 1);\nvec4 velocity = vec4(a_texCoord1.xyz, 0);\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\nvelocity = cc_matWorld * velocity;\n#endif\nfloat vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;\nvec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));\npos.xyz += camUp * vertOffset;\npos = cc_matViewProj * pos;\nuv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;\ncolor = a_color;\n#if CC_DRAW_WIRE_FRAME\nvBarycentric = a_texCoord2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", + "vert": "\nprecision mediump float;\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nin vec3 a_position;\nin vec4 a_texCoord;\nin vec3 a_texCoord1;\nin vec3 a_texCoord2;\nin vec4 a_color;\n#if CC_DRAW_WIRE_FRAME\nout vec3 vBarycentric;\n#endif\nvec4 vs_main() {\nhighp vec4 pos = vec4(a_position, 1);\nvec4 velocity = vec4(a_texCoord1.xyz, 0);\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\nvelocity = cc_matWorld * velocity;\n#endif\nfloat vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;\nvec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));\npos.xyz += camUp * vertOffset;\npos = cc_matViewProj * pos;\nuv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;\ncolor = a_color;\n#if CC_DRAW_WIRE_FRAME\nvBarycentric = a_texCoord2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nin vec2 uv;\nin vec4 color;\n#if CC_DRAW_WIRE_FRAME\nin vec3 vBarycentric;\n#endif\nuniform sampler2D mainTexture;\nlayout(std140) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\n#if CC_DRAW_WIRE_FRAME\nif (any(lessThan(vBarycentric, vec3(0.02)))) {\ncol = vec4(0., 1., 1., 1.);\n}\n#endif\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], [ { - "vert": "\nprecision highp float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nin vec3 a_position;\nin vec3 a_texCoord;\nin vec3 a_texCoord1;\nin vec3 a_texCoord2;\nin vec4 a_color;\n#if CC_RENDER_MODE == 1\nin vec3 a_color1;\n#endif\n#if CC_RENDER_MODE == 4\nin vec3 a_texCoord3;\nin vec3 a_normal;\nin vec4 a_color1;\n#endif\nvec4 lpvs_main () {\nvec3 compScale = scale.xyz * a_texCoord1;\nvec4 pos = vec4(a_position, 1);\n#if CC_RENDER_MODE == 1\nvec4 velocity = vec4(a_color1.xyz, 0);\n#endif\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = cc_matWorld * velocity;\n#endif\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nvec3 rotTmp = a_texCoord2;\nfloat mulFactor = 1.0;\nif (rotTmp.x > 10.0 * 0.5) {\nrotTmp.x -= 10.0;\nmulFactor = -1.0;\n}\nvec4 rot = vec4(rotTmp, 0.0);\nrot.w = mulFactor * sqrt(abs(1.0 - rot.x * rot.x - rot.y * rot.y - rot.z * rot.z));\n#else\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = a_texCoord2;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., a_texCoord2.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(a_texCoord2);\n#endif\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((a_texCoord.xy - 0.5));\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_matViewInv);\n#elif CC_RENDER_MODE == 1\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_cameraPos.xyz, velocity, frameTile_velLenScale.z, frameTile_velLenScale.w, a_texCoord.x);\n#elif 2\ncomputeVertPos(pos, cornerOffset, rot, compScale);\n#endif\ncolor = a_color;\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor = a_color * a_color1;\n#endif\nuv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\npos = cc_matViewProj * pos;\nreturn pos;\n}\nvoid main() { gl_Position = lpvs_main(); }", + "vert": "\nprecision highp float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nlayout(std140) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nout mediump vec2 uv;\nout mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nin vec3 a_position;\nin vec3 a_texCoord;\nin vec3 a_texCoord1;\nin vec3 a_texCoord2;\nin vec4 a_color;\n#if CC_RENDER_MODE == 1\nin vec3 a_color1;\n#endif\n#if CC_RENDER_MODE == 4\nin vec3 a_texCoord3;\nin vec3 a_normal;\nin vec4 a_color1;\n#endif\nvec4 lpvs_main () {\nvec3 compScale = scale.xyz * a_texCoord1;\nvec4 pos = vec4(a_position, 1);\n#if CC_RENDER_MODE == 1\nvec4 velocity = vec4(a_color1.xyz, 0);\n#endif\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = cc_matWorld * velocity;\n#endif\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nvec3 rotTmp = a_texCoord2;\nfloat mulFactor = 1.0;\nif (rotTmp.x > 10.0 * 0.5) {\nrotTmp.x -= 10.0;\nmulFactor = -1.0;\n}\nvec4 rot = vec4(rotTmp, 0.0);\nrot.w = mulFactor * sqrt(abs(1.0 - rot.x * rot.x - rot.y * rot.y - rot.z * rot.z));\n#else\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = a_texCoord2;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., a_texCoord2.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(a_texCoord2);\n#endif\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((a_texCoord.xy - 0.5));\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_matViewInv);\n#elif CC_RENDER_MODE == 1\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_cameraPos.xyz, velocity, frameTile_velLenScale.z, frameTile_velLenScale.w, a_texCoord.x);\n#elif 2\ncomputeVertPos(pos, cornerOffset, rot, compScale);\n#endif\ncolor = a_color;\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor = a_color * a_color1;\n#endif\nuv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\npos = cc_matViewProj * pos;\nreturn pos;\n}\nvoid main() { gl_Position = lpvs_main(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nin vec2 uv;\nin vec4 color;\nuniform sampler2D mainTexture;\nlayout(std140) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], [ { - "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\nin vec3 a_position;\nin vec2 a_texCoord;\nin vec4 a_color;\nout vec4 v_light;\nout vec2 uv0;\n#if TWO_COLORED\nin vec4 a_color2;\nout vec4 v_dark;\n#endif\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\npos = cc_matViewProj * pos;\nuv0 = a_texCoord;\nv_light = a_color;\n#if TWO_COLORED\nv_dark = a_color2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\nin vec3 a_position;\nin vec2 a_texCoord;\nin vec4 a_color;\nout vec4 v_light;\nout vec2 uv0;\n#if TWO_COLORED\nin vec4 a_color2;\nout vec4 v_dark;\n#endif\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\npos = cc_matViewProj * pos;\nuv0 = a_texCoord;\nv_light = a_color;\n#if TWO_COLORED\nv_dark = a_color2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\n#if USE_ALPHA_TEST\nlayout(std140) uniform ALPHA_TEST_DATA {\nfloat alphaThreshold;\n};\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n#if USE_ALPHA_TEST\nif (color.a < alphaThreshold) discard;\n#endif\n}\nvoid ALPHA_TEST (in float alpha) {\n#if USE_ALPHA_TEST\nif (alpha < alphaThreshold) discard;\n#endif\n}\nin vec4 v_light;\n#if TWO_COLORED\nin vec4 v_dark;\n#endif\nin vec2 uv0;\nuniform sampler2D cc_spriteTexture;\nvec4 frag () {\nvec4 o = vec4(1, 1, 1, 1);\n#if TWO_COLORED\nvec4 texColor = vec4(1, 1, 1, 1);\ntexColor *= texture(cc_spriteTexture, uv0);\no.a = texColor.a * v_light.a;\no.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n#else\no *= texture(cc_spriteTexture, uv0);\no *= v_light;\n#endif\nALPHA_TEST(o);\nreturn o;\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#if SAMPLE_FROM_RT\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#endif\nin vec3 a_position;\nin vec2 a_texCoord;\nin vec4 a_color;\nout vec4 color;\nout vec2 uv0;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\n#if USE_PIXEL_ALIGNMENT\npos = cc_matView * pos;\npos.xyz = floor(pos.xyz);\npos = cc_matProj * pos;\n#else\npos = cc_matViewProj * pos;\n#endif\nuv0 = a_texCoord;\n#if SAMPLE_FROM_RT\nuv0 = cc_cameraPos.w > 1.0 ? vec2(uv0.x, 1.0 - uv0.y) : uv0;\n#endif\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#if SAMPLE_FROM_RT\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#endif\nin vec3 a_position;\nin vec2 a_texCoord;\nin vec4 a_color;\nout vec4 color;\nout vec2 uv0;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\n#if USE_PIXEL_ALIGNMENT\npos = cc_matView * pos;\npos.xyz = floor(pos.xyz);\npos = cc_matProj * pos;\n#else\npos = cc_matViewProj * pos;\n#endif\nuv0 = a_texCoord;\n#if SAMPLE_FROM_RT\nuv0 = cc_cameraPos.w > 1.0 ? vec2(uv0.x, 1.0 - uv0.y) : uv0;\n#endif\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec4 CCSampleWithAlphaSeparated(sampler2D tex, vec2 uv) {\n#if CC_USE_EMBEDDED_ALPHA\nreturn vec4(texture(tex, uv).rgb, texture(tex, uv + vec2(0.0, 0.5)).r);\n#else\nreturn texture(tex, uv);\n#endif\n}\n#if USE_ALPHA_TEST\nlayout(std140) uniform ALPHA_TEST_DATA {\nfloat alphaThreshold;\n};\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n#if USE_ALPHA_TEST\nif (color.a < alphaThreshold) discard;\n#endif\n}\nvoid ALPHA_TEST (in float alpha) {\n#if USE_ALPHA_TEST\nif (alpha < alphaThreshold) discard;\n#endif\n}\nin vec4 color;\n#if USE_TEXTURE\nin vec2 uv0;\nuniform sampler2D cc_spriteTexture;\n#endif\nvec4 frag () {\nvec4 o = vec4(1, 1, 1, 1);\n#if USE_TEXTURE\no *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);\n#if IS_GRAY\nfloat gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;\no.r = o.g = o.b = gray;\n#endif\n#endif\no *= color;\nALPHA_TEST(o);\nreturn o;\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nout highp vec4 v_shadowPos;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nin vec4 a_color;\nout vec4 v_color;\n#endif\nout vec3 v_position;\nout vec3 v_normal;\nout vec2 v_uv;\nout vec2 v_uv1;\n#if CC_RECEIVE_SHADOW\nout vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nout vec3 v_tangent;\nout vec3 v_bitangent;\n#endif\n#if HAS_SECOND_UV || USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nout vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_bitangent = cross(v_normal, v_tangent) * In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", - "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nin highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nin vec3 v_luv;\nuniform sampler2D cc_lightingMap;\n#endif\nin vec3 v_position;\nin vec2 v_uv;\nin vec2 v_uv1;\nin vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nin vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nin vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nin vec3 v_tangent;\nin vec3 v_bitangent;\nuniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nuniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nuniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nuniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nuniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(cc_lightingMap, v_luv.xy);\ns.lightmap = lightColor.xyz * v_luv.z;\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5);\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent) +\n(nmmp.y * emissiveScaleParam.w) * normalize(v_bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor2 = vec4(s.emissive, s.occlusion);\n}\n#endif", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nout highp vec4 v_shadowPos;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nin vec4 a_color;\nout vec4 v_color;\n#endif\nout vec3 v_position;\nout vec3 v_normal;\nout vec2 v_uv;\nout vec2 v_uv1;\n#if CC_RECEIVE_SHADOW\nout vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nout vec3 v_tangent;\nout vec3 v_bitangent;\n#endif\n#if HAS_SECOND_UV || USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nout vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.zw;\nv_luv.z = cc_lightingMapUVParam.z;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.zw;\nv_luv.z = a_lightingMapUVParam.z;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_bitangent = cross(v_normal, v_tangent) * In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", + "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nin highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nin vec3 v_luv;\nuniform sampler2D cc_lightingMap;\nvec3 UnpackLightingmap(vec4 color) {\nvec3 c;\nfloat e = 1.0 + color.a * (8.0 - 1.0);\nc.r = color.r * e;\nc.g = color.g * e;\nc.b = color.b * e;\nreturn c;\n}\n#endif\nin vec3 v_position;\nin vec2 v_uv;\nin vec2 v_uv1;\nin vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nin vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nin vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nin vec3 v_tangent;\nin vec3 v_bitangent;\nuniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nuniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nuniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nuniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nuniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(cc_lightingMap, v_luv.xy);\ns.lightmap = UnpackLightingmap(lightColor);\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5);\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent) +\n(nmmp.y * emissiveScaleParam.w) * normalize(v_bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nfragColor1 = vec4(position, s.roughness);\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor3 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if HAS_SECOND_UV || USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\nout vec2 v_uv;\nout vec2 v_uv1;\nout vec4 v_worldPos;\nout float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", - "frag": "\nprecision highp float;\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\nin vec2 v_uv;\nin vec2 v_uv1;\nin vec4 v_worldPos;\nin float v_clip_depth;\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if HAS_SECOND_UV || USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\nout vec2 v_uv;\nout vec2 v_uv1;\nout vec4 v_worldPos;\nout float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "frag": "\nprecision highp float;\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\nin vec2 v_uv;\nin vec2 v_uv1;\nin vec4 v_worldPos;\nin float v_clip_depth;\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nout highp vec4 v_shadowPos;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\n#endif\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\n#if CC_RECEIVE_SHADOW\nout vec2 v_shadowBias;\n#endif\nout highp vec3 v_position;\nout mediump vec3 v_normal;\n#if USE_NORMALMAP\nout mediump vec3 v_tangent;\nout mediump vec3 v_binormal;\n#endif\nout mediump vec2 uvw;\nout mediump vec2 uv0;\nout mediump vec2 uv1;\nout mediump vec2 uv2;\nout mediump vec2 uv3;\nout mediump vec3 luv;\nout mediump vec3 diffuse;\nlayout(std140) uniform TexCoords {\nvec4 UVScale;\nvec4 lightMapUVParam;\n};\nvoid main () {\nvec3 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nvec4 pos = vec4(worldPos, 1.0);\npos = cc_matViewProj * pos;\nuvw = a_texCoord;\nuv0 = a_position.xz * UVScale.x;\nuv1 = a_position.xz * UVScale.y;\nuv2 = a_position.xz * UVScale.z;\nuv3 = a_position.xz * UVScale.w;\n#if USE_LIGHTMAP\nluv.xy = lightMapUVParam.xy + a_texCoord * lightMapUVParam.z;\nluv.z = lightMapUVParam.w;\n#endif\nv_position = worldPos;\nv_normal = a_normal;\nCC_TRANSFER_FOG(vec4(worldPos, 1.0));\n#if CC_RECEIVE_SHADOW\nv_shadowBias = vec2(0.0, 0.0);\n#endif\n#if USE_NORMALMAP\nv_tangent = vec3(1.0, 0.0, 0.0);\nv_binormal = vec3(0.0, 0.0, 1.0);\nv_binormal = cross(v_tangent, a_normal);\nv_tangent = cross(a_normal, v_binormal);\n#endif\nv_shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0);\ngl_Position = pos;\n}", - "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\nin highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nin vec3 v_luv;\nuniform sampler2D cc_lightingMap;\n#endif\nin highp vec3 v_position;\nin mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nin vec2 v_shadowBias;\n#endif\n#if USE_NORMALMAP\nin mediump vec3 v_tangent;\nin mediump vec3 v_binormal;\n#endif\nin mediump vec2 uvw;\nin mediump vec2 uv0;\nin mediump vec2 uv1;\nin mediump vec2 uv2;\nin mediump vec2 uv3;\nin mediump vec3 diffuse;\nin mediump vec3 luv;\nlayout(std140) uniform PbrParams {\nvec4 metallic;\nvec4 roughness;\n};\nuniform sampler2D weightMap;\nuniform sampler2D detailMap0;\nuniform sampler2D detailMap1;\nuniform sampler2D detailMap2;\nuniform sampler2D detailMap3;\nuniform sampler2D normalMap0;\nuniform sampler2D normalMap1;\nuniform sampler2D normalMap2;\nuniform sampler2D normalMap3;\nuniform sampler2D lightMap;\nvoid surf (out StandardSurface s) {\n#if LAYERS > 1\nvec4 w = texture(weightMap, uvw);\n#endif\nvec4 baseColor = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseColor = texture(detailMap0, uv0);\n#elif LAYERS == 2\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\nbaseColor += texture(detailMap3, uv3) * w.a;\n#else\nbaseColor = texture(detailMap0, uv0);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\n#if USE_NORMALMAP\nvec4 baseNormal = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseNormal = texture(normalMap0, uv0);\n#elif LAYERS == 2\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\nbaseNormal += texture(normalMap3, uv3) * w.a;\n#else\nbaseNormal = texture(normalMap0, uv0);\n#endif\nvec3 nmmp = baseNormal.xyz - vec3(0.5);\ns.normal =\nnmmp.x * normalize(v_tangent) +\nnmmp.y * normalize(v_binormal) +\nnmmp.z * normalize(v_normal);\n#else\ns.normal = v_normal;\n#endif\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\ns.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0);\ns.occlusion = 1.0;\n#if USE_PBR\ns.roughness = 0.0;\n#if LAYERS == 1\ns.roughness = roughness.x;\n#elif LAYERS == 2\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\n#elif LAYERS == 3\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\n#elif LAYERS == 4\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\ns.roughness += roughness.w * w.a;\n#else\ns.roughness = 1.0;\n#endif\ns.metallic = 0.0;\n#if LAYERS == 1\ns.metallic = metallic.x;\n#elif LAYERS == 2\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\n#elif LAYERS == 3\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\n#elif LAYERS == 4\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\ns.metallic += metallic.w * w.a;\n#else\ns.metallic = 0.0;\n#endif\n#else\ns.roughness = 1.0;\ns.metallic = 0.0;\n#endif\ns.emissive = vec3(0.0, 0.0, 0.0);\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(lightMap, luv.xy);\ns.lightmap = lightColor.xyz * luv.z;\ns.lightmap_test = luv.z;\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor2 = vec4(s.emissive, s.occlusion);\n}\n#endif", + "vert": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nout highp vec4 v_shadowPos;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\n#endif\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\n#if CC_RECEIVE_SHADOW\nout vec2 v_shadowBias;\n#endif\nout highp vec3 v_position;\nout mediump vec3 v_normal;\n#if USE_NORMALMAP\nout mediump vec3 v_tangent;\nout mediump vec3 v_binormal;\n#endif\nout mediump vec2 uvw;\nout mediump vec2 uv0;\nout mediump vec2 uv1;\nout mediump vec2 uv2;\nout mediump vec2 uv3;\nout mediump vec3 luv;\nout mediump vec3 diffuse;\nlayout(std140) uniform TexCoords {\nvec4 UVScale;\nvec4 lightMapUVParam;\n};\nvoid main () {\nvec3 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nvec4 pos = vec4(worldPos, 1.0);\npos = cc_matViewProj * pos;\nuvw = a_texCoord;\nuv0 = a_position.xz * UVScale.x;\nuv1 = a_position.xz * UVScale.y;\nuv2 = a_position.xz * UVScale.z;\nuv3 = a_position.xz * UVScale.w;\n#if USE_LIGHTMAP\nluv.xy = lightMapUVParam.xy + a_texCoord * lightMapUVParam.zw;\nluv.z = lightMapUVParam.z;\n#endif\nv_position = worldPos;\nv_normal = a_normal;\nCC_TRANSFER_FOG(vec4(worldPos, 1.0));\n#if CC_RECEIVE_SHADOW\nv_shadowBias = vec2(0.0, 0.0);\n#endif\n#if USE_NORMALMAP\nv_tangent = vec3(1.0, 0.0, 0.0);\nv_binormal = vec3(0.0, 0.0, 1.0);\nv_binormal = cross(v_tangent, a_normal);\nv_tangent = cross(a_normal, v_binormal);\n#endif\nv_shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0);\ngl_Position = pos;\n}", + "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\nin highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nin vec3 v_luv;\nuniform sampler2D cc_lightingMap;\nvec3 UnpackLightingmap(vec4 color) {\nvec3 c;\nfloat e = 1.0 + color.a * (8.0 - 1.0);\nc.r = color.r * e;\nc.g = color.g * e;\nc.b = color.b * e;\nreturn c;\n}\n#endif\nin highp vec3 v_position;\nin mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nin vec2 v_shadowBias;\n#endif\n#if USE_NORMALMAP\nin mediump vec3 v_tangent;\nin mediump vec3 v_binormal;\n#endif\nin mediump vec2 uvw;\nin mediump vec2 uv0;\nin mediump vec2 uv1;\nin mediump vec2 uv2;\nin mediump vec2 uv3;\nin mediump vec3 diffuse;\nin mediump vec3 luv;\nlayout(std140) uniform PbrParams {\nvec4 metallic;\nvec4 roughness;\n};\nuniform sampler2D weightMap;\nuniform sampler2D detailMap0;\nuniform sampler2D detailMap1;\nuniform sampler2D detailMap2;\nuniform sampler2D detailMap3;\nuniform sampler2D normalMap0;\nuniform sampler2D normalMap1;\nuniform sampler2D normalMap2;\nuniform sampler2D normalMap3;\nuniform sampler2D lightMap;\nvoid surf (out StandardSurface s) {\n#if LAYERS > 1\nvec4 w = texture(weightMap, uvw);\n#endif\nvec4 baseColor = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseColor = texture(detailMap0, uv0);\n#elif LAYERS == 2\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\nbaseColor += texture(detailMap3, uv3) * w.a;\n#else\nbaseColor = texture(detailMap0, uv0);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\n#if USE_NORMALMAP\nvec4 baseNormal = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseNormal = texture(normalMap0, uv0);\n#elif LAYERS == 2\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\nbaseNormal += texture(normalMap3, uv3) * w.a;\n#else\nbaseNormal = texture(normalMap0, uv0);\n#endif\nvec3 nmmp = baseNormal.xyz - vec3(0.5);\ns.normal =\nnmmp.x * normalize(v_tangent) +\nnmmp.y * normalize(v_binormal) +\nnmmp.z * normalize(v_normal);\n#else\ns.normal = v_normal;\n#endif\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\ns.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0);\ns.occlusion = 1.0;\n#if USE_PBR\ns.roughness = 0.0;\n#if LAYERS == 1\ns.roughness = roughness.x;\n#elif LAYERS == 2\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\n#elif LAYERS == 3\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\n#elif LAYERS == 4\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\ns.roughness += roughness.w * w.a;\n#else\ns.roughness = 1.0;\n#endif\ns.metallic = 0.0;\n#if LAYERS == 1\ns.metallic = metallic.x;\n#elif LAYERS == 2\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\n#elif LAYERS == 3\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\n#elif LAYERS == 4\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\ns.metallic += metallic.w * w.a;\n#else\ns.metallic = 0.0;\n#endif\n#else\ns.roughness = 1.0;\ns.metallic = 0.0;\n#endif\ns.emissive = vec3(0.0, 0.0, 0.0);\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(lightMap, luv.xy);\ns.lightmap = UnpackLightingmap(lightColor);\ns.lightmap_test = luv.z;\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nfragColor1 = vec4(position, s.roughness);\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor3 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nout vec2 v_clip_depth;\nvec4 vert () {\nvec4 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nworldPos.w = 1.0;\nvec4 clipPos = cc_matLightViewProj * worldPos;\nv_clip_depth = clipPos.zw;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nout vec2 v_clip_depth;\nvec4 vert () {\nvec4 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nworldPos.w = 1.0;\nvec4 clipPos = cc_matLightViewProj * worldPos;\nv_clip_depth = clipPos.zw;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nin vec2 v_clip_depth;\nvec4 frag () {\nreturn packDepthToRGBA(v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nin lowp vec4 a_color;\nout lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nout vec2 v_uv;\nlayout(std140) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nin lowp vec4 a_color;\nout lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nout vec2 v_uv;\nlayout(std140) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#if USE_ALPHA_TEST\n#endif\n#if USE_TEXTURE\nin vec2 v_uv;\nuniform sampler2D mainTexture;\n#endif\nlayout(std140) uniform Constant {\nvec4 mainColor;\nvec4 colorScaleAndCutoff;\n};\n#if USE_VERTEX_COLOR\nin lowp vec4 v_color;\n#endif\nvec4 frag () {\nvec4 o = mainColor;\no.rgb *= colorScaleAndCutoff.xyz;\n#if USE_VERTEX_COLOR\no.rgb *= SRGBToLinear(v_color.rgb);\no.a *= v_color.a;\n#endif\n#if USE_TEXTURE\nvec4 texColor = texture(mainTexture, v_uv);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\no *= texColor;\n#endif\n#if USE_ALPHA_TEST\nif (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;\n#endif\nCC_APPLY_FOG(o);\nreturn CCFragOutput(o);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nfloat luminance(vec3 color) {\nreturn dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\nvoid main() {\nvec3 color = texture(outputResultMap, v_uv).xyz;\nif (luminance(SRGBToLinear(color)) > texSize.z) {\nfragColor = vec4(color, 1.0);\n} else {\nfragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n}", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 downsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main()\n{\nvec3 result = downsample4taps(v_uv, 1.0 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 upsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main() {\nvec3 result = upsample4taps(v_uv, 0.5 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D outputResultMap;\nuniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvoid main() {\nvec4 hdrColor = texture(outputResultMap, v_uv);\nvec3 bloomColor = texture(bloomTexture, v_uv).rgb;\nvec3 result = hdrColor.rgb + bloomColor * texSize.w * hdrColor.a;\nfragColor = vec4(result, hdrColor.a);\n}", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nvec4 position;\nposition = vec4(a_position, 1.0);\nposition.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\ngl_Position = vec4(position.x, position.y, 1.0, 1.0);\nv_uv = a_texCoord;\n}", - "frag": "\n#ifdef GL_EXT_shader_framebuffer_fetch\n#extension GL_EXT_shader_framebuffer_fetch: enable\n#endif\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn 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\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec3 oct_to_float32x3(vec2 e) {\nvec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\nif (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\nreturn normalize(v);\n}\nvec4 screen2WS(vec3 coord) {\nvec3 ndc = vec3(\n2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n2.0 * coord.z - 1.0);\nvec4 world = ((cc_matViewProjInv) * (vec4(ndc, 1.0)));\nworld = world / world.w;\nreturn world;\n}\nin vec2 v_uv;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nlayout(location = 0) inout vec4 gbuffer_albedoMap;\nlayout(location = 1) inout vec4 gbuffer_normalMap;\nlayout(location = 2) inout vec4 gbuffer_emissiveMap;\n#else\nuniform sampler2D gbuffer_albedoMap;\nuniform sampler2D gbuffer_normalMap;\nuniform sampler2D gbuffer_emissiveMap;\n#endif\nuniform sampler2D depth_stencil;\n#if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450\nlayout(location = 0) out vec4 fragColor;\n#endif\nvoid main () {\nStandardSurface s;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nvec4 albedoMap = gbuffer_albedoMap;\nvec4 normalMap = gbuffer_normalMap;\nvec4 emissiveMap = gbuffer_emissiveMap;\n#else\nvec4 albedoMap = texture(gbuffer_albedoMap,v_uv);\nvec4 normalMap = texture(gbuffer_normalMap,v_uv);\nvec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv);\n#endif\nfloat depth = texture(depth_stencil, v_uv).x;\ns.albedo = albedoMap;\nvec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\ns.position = position;\ns.roughness = normalMap.z;\ns.normal = oct_to_float32x3(normalMap.xy);\ns.metallic = normalMap.w;\ns.emissive = emissiveMap.xyz;\ns.occlusion = emissiveMap.w;\nfloat fogFactor;\nCC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\nvec4 shadowPos;\nshadowPos = cc_matLightViewProj * vec4(position, 1);\nvec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nCCClusterShadingAdditive(s, shadowPos);\n#else\nCCStandardShadingAdditive(s, shadowPos);\n#endif\nCC_APPLY_FOG_BASE(color, fogFactor);\ncolor = CCFragOutput(color);\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\ngbuffer_emissiveMap = color;\n#else\nfragColor = color;\n#endif\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nvec4 position;\nposition = vec4(a_position, 1.0);\nposition.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\ngl_Position = vec4(position.x, position.y, 1.0, 1.0);\nv_uv = a_texCoord;\n}", + "frag": "\n#ifdef GL_EXT_shader_framebuffer_fetch\n#extension GL_EXT_shader_framebuffer_fetch: enable\n#endif\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn 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\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec3 oct_to_float32x3(vec2 e) {\nvec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\nif (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\nreturn normalize(v);\n}\nvec4 screen2WS(vec3 coord) {\nvec3 ndc = vec3(\n2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\n2.0 * coord.z - 1.0);\nvec4 world = ((cc_matViewProjInv) * (vec4(ndc, 1.0)));\nworld = world / world.w;\nreturn world;\n}\nin vec2 v_uv;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nlayout(location = 0) inout vec4 gbuffer_albedoMap;\nlayout(location = 1) inout vec4 gbuffer_normalMap;\nlayout(location = 2) inout vec4 gbuffer_emissiveMap;\n#else\nuniform sampler2D gbuffer_albedoMap;\nuniform sampler2D gbuffer_normalMap;\nuniform sampler2D gbuffer_emissiveMap;\n#endif\nuniform sampler2D depth_stencil;\n#if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450\nlayout(location = 0) out vec4 fragColor;\n#endif\nvoid main () {\nStandardSurface s;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nvec4 albedoMap = gbuffer_albedoMap;\nvec4 normalMap = gbuffer_normalMap;\nvec4 emissiveMap = gbuffer_emissiveMap;\n#else\nvec4 albedoMap = texture(gbuffer_albedoMap,v_uv);\nvec4 normalMap = texture(gbuffer_normalMap,v_uv);\nvec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv);\n#endif\nfloat depth = texture(depth_stencil, v_uv).x;\ns.albedo = albedoMap;\nvec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\ns.position = position;\ns.roughness = normalMap.z;\ns.normal = oct_to_float32x3(normalMap.xy);\ns.metallic = normalMap.w;\ns.emissive = emissiveMap.xyz;\ns.occlusion = emissiveMap.w;\nfloat fogFactor;\nCC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\nvec4 shadowPos;\nshadowPos = cc_matLightViewProj * vec4(position, 1);\nvec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nCCClusterShadingAdditive(s, shadowPos);\n#else\nCCStandardShadingAdditive(s, shadowPos);\n#endif\nCC_APPLY_FOG_BASE(color, fogFactor);\ncolor = CCFragOutput(color);\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\ngbuffer_emissiveMap = color;\n#else\nfragColor = color;\n#endif\n}", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nout float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nout float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nin float v_dist;\nvec4 frag () {\nif(v_dist < 0.0)\ndiscard;\nreturn CCFragOutput(cc_shadowColor);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nin highp vec4 a_jointAnimInfo;\n#endif\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if ANTIALIAS_TYPE == 1\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\nvec2 v_rgbNW, vec2 v_rgbNE,\nvec2 v_rgbSW, vec2 v_rgbSE,\nvec2 v_rgbM) {\nvec4 color;\nmediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\nvec3 rgbNW = texture(tex, v_rgbNW).xyz;\nvec3 rgbNE = texture(tex, v_rgbNE).xyz;\nvec3 rgbSW = texture(tex, v_rgbSW).xyz;\nvec3 rgbSE = texture(tex, v_rgbSE).xyz;\nvec4 texColor = texture(tex, v_rgbM);\nvec3 rgbM = texColor.xyz;\nvec3 luma = vec3(0.299, 0.587, 0.114);\nfloat lumaNW = dot(rgbNW, luma);\nfloat lumaNE = dot(rgbNE, luma);\nfloat lumaSW = dot(rgbSW, luma);\nfloat lumaSE = dot(rgbSE, luma);\nfloat lumaM = dot(rgbM, luma);\nfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\nfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\nmediump vec2 dir;\ndir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\ndir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\nfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n(0.25 * (1.0 / 8.0)), (1.0/ 128.0));\nfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\ndir = min(vec2(8.0, 8.0),\nmax(vec2(-8.0, -8.0),\ndir * rcpDirMin)) * inverseVP;\nvec3 rgbA = 0.5 * (\ntexture(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\ntexture(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\nvec3 rgbB = rgbA * 0.5 + 0.25 * (\ntexture(tex, fragCoord * inverseVP + dir * -0.5).xyz +\ntexture(tex, fragCoord * inverseVP + dir * 0.5).xyz);\nfloat lumaB = dot(rgbB, luma);\nif ((lumaB < lumaMin) || (lumaB > lumaMax))\ncolor = vec4(rgbA, texColor.a);\nelse\ncolor = vec4(rgbB, texColor.a);\nreturn color;\n}\n#endif\nin vec2 v_uv;\nuniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nvoid texcoords(vec2 fragCoord, vec2 resolution,\nout vec2 v_rgbNW, out vec2 v_rgbNE,\nout vec2 v_rgbSW, out vec2 v_rgbSE,\nout vec2 v_rgbM) {\nvec2 inverseVP = 1.0 / resolution.xy;\nv_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\nv_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\nv_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\nv_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\nv_rgbM = vec2(fragCoord * inverseVP);\n}\nvoid main () {\nmediump vec2 v_rgbNW;\nmediump vec2 v_rgbNE;\nmediump vec2 v_rgbSW;\nmediump vec2 v_rgbSE;\nmediump vec2 v_rgbM;\n#if ANTIALIAS_TYPE == 1\nvec2 resolution = cc_screenSize.xy;\nvec2 fragCoord = v_uv * resolution;\ntexcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\nfragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n#else\nfragColor = texture(outputResultMap, v_uv);\n#endif\n}", } ], [ { - "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\nout mediump vec4 viewDir;\nvec4 vert () {\nviewDir = vec4(a_position, 1.0);\nmat4 matViewRotOnly = mat4(mat3(cc_matView));\nvec4 pos = matViewRotOnly * viewDir;\nif (cc_matProj[3].w > 0.0) {\nmat4 matProj = cc_matProj;\nmatProj[0].x = 5.2;\nmatProj[1].y = 2.6;\nmatProj[2].zw = vec2(-1.0);\nmatProj[3].zw = vec2(0.0);\npos = matProj * pos;\n} else {\npos = cc_matProj * pos;\n}\npos.z = 0.99999 * pos.w;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if USE_INSTANCING\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\n#endif\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\nout mediump vec4 viewDir;\nvec4 vert () {\nviewDir = vec4(a_position, 1.0);\nmat4 matViewRotOnly = mat4(mat3(cc_matView));\nvec4 pos = matViewRotOnly * viewDir;\nif (cc_matProj[3].w > 0.0) {\nmat4 matProj = cc_matProj;\nmatProj[0].x = 5.2;\nmatProj[1].y = 2.6;\nmatProj[2].zw = vec2(-1.0);\nmatProj[3].zw = vec2(0.0);\npos = matProj * pos;\n} else {\npos = cc_matProj * pos;\n}\npos.z = 0.99999 * pos.w;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(std140) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nuniform samplerCube cc_environment;\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nin mediump vec4 viewDir;\nvec4 frag () {\n#if USE_RGBE_CUBEMAP\nvec3 c = unpackRGBE(texture(cc_environment, viewDir.xyz));\n#else\nvec3 c = SRGBToLinear(texture(cc_environment, viewDir.xyz).rgb);\n#endif\nreturn CCFragOutput(vec4(c * cc_ambientSky.w, 1.0));\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], diff --git a/cocos/core/builtin/shader-sources/glsl4.ts b/cocos/core/builtin/shader-sources/glsl4.ts index b396da4ac25..c93a325fb4b 100644 --- a/cocos/core/builtin/shader-sources/glsl4.ts +++ b/cocos/core/builtin/shader-sources/glsl4.ts @@ -2,7 +2,7 @@ export const glsl4 = [ [ { - "vert": "\nprecision mediump float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n, mat4 viewInv\n) {\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n}\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nlayout(set = 1, binding = 1) uniform builtin {\nvec4 cc_size_rotation;\n};\nvec4 vs_main() {\nvec4 pos = vec4(a_position, 1);\npos = cc_matWorld * pos;\nvec2 vertOffset = a_texCoord.xy - 0.5;\ncomputeVertPos(pos, vertOffset, quaternionFromEuler(vec3(0., 0., cc_size_rotation.z)), vec3(cc_size_rotation.xy, 0.), cc_matViewInv);\npos = cc_matViewProj * pos;\nuv = a_texCoord.xy;\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", + "vert": "\nprecision mediump float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n, mat4 viewInv\n) {\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n}\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nlayout(set = 1, binding = 1) uniform builtin {\nvec4 cc_size_rotation;\n};\nvec4 vs_main() {\nvec4 pos = vec4(a_position, 1);\npos = cc_matWorld * pos;\nvec2 vertOffset = a_texCoord.xy - 0.5;\ncomputeVertPos(pos, vertOffset, quaternionFromEuler(vec3(0., 0., cc_size_rotation.z)), vec3(cc_size_rotation.xy, 0.), cc_matViewInv);\npos = cc_matViewProj * pos;\nuv = a_texCoord.xy;\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nlayout(location = 0) in vec2 uv;\nlayout(location = 1) in vec4 color;\nlayout(set = 1, binding = 3) uniform sampler2D mainTexture;\nlayout(set = 1, binding = 2) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], @@ -40,7 +40,7 @@ export const glsl4 = [ ], [ { - "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec4 a_color;\nlayout(location = 0) out vec4 v_color;\nlayout(location = 2) in float a_dist;\nlayout(location = 1) out float v_dist;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\npos = cc_matViewProj * cc_matWorld * pos;\nv_color = a_color;\nv_dist = a_dist;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec4 a_color;\nlayout(location = 0) out vec4 v_color;\nlayout(location = 2) in float a_dist;\nlayout(location = 1) out float v_dist;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\npos = cc_matViewProj * cc_matWorld * pos;\nv_color = a_color;\nv_dist = a_dist;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nlayout(location = 0) in vec4 v_color;\nlayout(location = 1) in float v_dist;\nvec4 frag () {\nvec4 o = v_color;\nfloat aa = fwidth(v_dist);\nfloat alpha = 1. - smoothstep(-aa, 0., abs(v_dist) - 1.0);\no.rgb *= o.a;\no *= alpha;\nreturn o;\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], @@ -52,99 +52,99 @@ export const glsl4 = [ ], [ { - "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(set = 1, binding = 1) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(set = 1, binding = 2) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nlayout(location = 0) in vec4 a_position_starttime;\nlayout(location = 1) in vec4 a_size_uv;\nlayout(location = 2) in vec4 a_rotation_uv;\nlayout(location = 3) in vec4 a_color;\nlayout(location = 4) in vec4 a_dir_life;\nlayout(location = 5) in float a_rndSeed;\n#if CC_RENDER_MODE == 4\nlayout(location = 6) in vec3 a_texCoord;\nlayout(location = 7) in vec3 a_texCoord3;\nlayout(location = 8) in vec3 a_normal;\nlayout(location = 9) in vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 10) uniform sampler2D color_over_time_tex0;\nlayout(set = 1, binding = 3) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 11) uniform sampler2D rotation_over_time_tex0;\nlayout(set = 1, binding = 4) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 12) uniform sampler2D size_over_time_tex0;\nlayout(set = 1, binding = 5) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 13) uniform sampler2D force_over_time_tex0;\nlayout(set = 1, binding = 6) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 14) uniform sampler2D velocity_over_time_tex0;\nlayout(set = 1, binding = 7) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nlayout(set = 1, binding = 15) uniform sampler2D texture_animation_tex0;\nlayout(set = 1, binding = 8) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", + "vert": "\nprecision mediump float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nvec4 eulerToQuat(vec3 euler) {\nvec3 er = euler * 0.5;\nfloat x = er.x, y = er.y, z = er.z;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat;\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(set = 1, binding = 1) uniform SampleConstants {\nvec4 u_sampleInfo;\n};\nlayout(set = 1, binding = 2) uniform TickConstants {\nvec4 u_worldRot;\nvec4 u_timeDelta;\n};\nlayout(location = 0) in vec4 a_position_starttime;\nlayout(location = 1) in vec4 a_size_uv;\nlayout(location = 2) in vec4 a_rotation_uv;\nlayout(location = 3) in vec4 a_color;\nlayout(location = 4) in vec4 a_dir_life;\nlayout(location = 5) in float a_rndSeed;\n#if CC_RENDER_MODE == 4\nlayout(location = 6) in vec3 a_texCoord;\nlayout(location = 7) in vec3 a_texCoord3;\nlayout(location = 8) in vec3 a_normal;\nlayout(location = 9) in vec4 a_color1;\n#endif\nvec3 unpackCurveData (sampler2D tex, vec2 coord) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nreturn mix(a.xyz, b.xyz, c);\n}\nvec3 unpackCurveData (sampler2D tex, vec2 coord, out float w) {\nvec4 a = texture(tex, coord);\nvec4 b = texture(tex, coord + u_sampleInfo.y);\nfloat c = fract(coord.x * u_sampleInfo.x);\nw = mix(a.w, b.w, c);\nreturn mix(a.xyz, b.xyz, c);\n}\nfloat pseudoRandom(float x) {\n#if USE_VK_SHADER\nfloat o = x;\nx = mod(x - 1.0, 2.0) - 1.0;\nfloat freqVar = 10.16640753482;\nfloat y = sin(freqVar * floor(o * 0.5 - 0.5));\nfloat v = max(0.0, 1.0-abs(x));\nv *= 0.7071067812;\nv = y < 0.0 ? -v : v;\nreturn v;\n#else\nfloat seed = mod(x, 233280.);\nfloat q = (seed * 9301. + 49297.) / 233280.;\nreturn fract(q);\n#endif\n}\n#if COLOR_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 10) uniform sampler2D color_over_time_tex0;\nlayout(set = 1, binding = 3) uniform ColorConstant {\nint u_color_mode;\n};\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 11) uniform sampler2D rotation_over_time_tex0;\nlayout(set = 1, binding = 4) uniform RotationConstant {\nint u_rotation_mode;\n};\n#endif\n#if SIZE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 12) uniform sampler2D size_over_time_tex0;\nlayout(set = 1, binding = 5) uniform SizeConstant {\nint u_size_mode;\n};\n#endif\n#if FORCE_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 13) uniform sampler2D force_over_time_tex0;\nlayout(set = 1, binding = 6) uniform ForceConstant {\nint u_force_mode;\nint u_force_space;\n};\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nlayout(set = 1, binding = 14) uniform sampler2D velocity_over_time_tex0;\nlayout(set = 1, binding = 7) uniform VelocityConstant {\nint u_velocity_mode;\nint u_velocity_space;\n};\n#endif\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nlayout(set = 1, binding = 15) uniform sampler2D texture_animation_tex0;\nlayout(set = 1, binding = 8) uniform AnimationConstant {\nvec4 u_anim_info;\n};\n#endif\nfloat repeat (float t, float length) {\nreturn t - floor(t / length) * length;\n}\nvec4 rotateQuat (vec4 p, vec4 q) {\nvec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;\nvec3 res = p.xyz + 2.0 * cross(q.xyz, iv);\nreturn vec4(res.xyz, p.w);\n}\nvec4 gpvs_main () {\nfloat activeTime = u_timeDelta.x - a_position_starttime.w;\nfloat normalizedTime = clamp(activeTime / a_dir_life.w, 0.0, 1.0);\nvec2 timeCoord0 = vec2(normalizedTime, 0.);\nvec2 timeCoord1 = vec2(normalizedTime, 1.);\n#if CC_RENDER_MODE == 4\nvec2 vertIdx = vec2(a_texCoord.x, a_texCoord.y);\n#else\nvec2 vertIdx = vec2(a_size_uv.w, a_rotation_uv.w);\n#endif\nvec4 velocity = vec4(a_dir_life.xyz, 0.);\nvec4 pos = vec4(a_position_starttime.xyz, 1.);\nvec3 size = a_size_uv.xyz;\n#if SIZE_OVER_TIME_MODULE_ENABLE\nif (u_size_mode == 1) {\nsize *= unpackCurveData(size_over_time_tex0, timeCoord0);\n} else {\nvec3 size_0 = unpackCurveData(size_over_time_tex0, timeCoord0);\nvec3 size_1 = unpackCurveData(size_over_time_tex0, timeCoord1);\nfloat factor_s = pseudoRandom(a_rndSeed + 39825.);\nsize *= mix(size_0, size_1, factor_s);\n}\n#endif\nvec3 compScale = scale.xyz * size;\n#if FORCE_OVER_TIME_MODULE_ENABLE\nvec3 forceAnim = vec3(0.);\nif (u_force_mode == 1) {\nforceAnim = unpackCurveData(force_over_time_tex0, timeCoord0);\n} else {\nvec3 force_0 = unpackCurveData(force_over_time_tex0, timeCoord0);\nvec3 force_1 = unpackCurveData(force_over_time_tex0, timeCoord1);\nfloat factor_f = pseudoRandom(a_rndSeed + 212165.);\nforceAnim = mix(force_0, force_1, factor_f);\n}\nvec4 forceTrack = vec4(forceAnim, 0.);\nif (u_force_space == 0) {\nforceTrack = rotateQuat(forceTrack, u_worldRot);\n}\nvelocity.xyz += forceTrack.xyz;\n#endif\n#if VELOCITY_OVER_TIME_MODULE_ENABLE\nfloat speedModifier0 = 1.;\nfloat speedModifier1 = 1.;\nvec3 velocityAnim = vec3(0.);\nif (u_velocity_mode == 1) {\nvelocityAnim = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\n} else {\nvec3 vectory_0 = unpackCurveData(velocity_over_time_tex0, timeCoord0, speedModifier0);\nvec3 vectory_1 = unpackCurveData(velocity_over_time_tex0, timeCoord1, speedModifier1);\nfloat factor_v = pseudoRandom(a_rndSeed + 197866.);\nvelocityAnim = mix(vectory_0, vectory_1, factor_v);\nspeedModifier0 = mix(speedModifier0, speedModifier1, factor_v);\n}\nvec4 velocityTrack = vec4(velocityAnim, 0.);\nif (u_velocity_space == 0) {\nvelocityTrack = rotateQuat(velocityTrack, u_worldRot);\n}\nvelocity.xyz += velocityTrack.xyz;\nvelocity.xyz *= speedModifier0;\n#endif\npos.xyz += velocity.xyz * normalizedTime * a_dir_life.w;\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = rotateQuat(velocity, u_worldRot);\n#endif\n#endif\nvec3 startRotation = a_rotation_uv.xyz;\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = startRotation.xyz;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., startRotation.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(startRotation);\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nif (u_rotation_mode == 1) {\nvec3 euler = unpackCurveData(rotation_over_time_tex0, timeCoord0) * normalizedTime * a_dir_life.w;\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n} else {\nvec3 rotation_0 = unpackCurveData(rotation_over_time_tex0, timeCoord0);\nvec3 rotation_1 = unpackCurveData(rotation_over_time_tex0, timeCoord1);\nfloat factor_r = pseudoRandom(a_rndSeed + 125292.);\nvec3 euler = mix(rotation_0, rotation_1, factor_r) * normalizedTime * a_dir_life.w;\n#if CC_RENDER_MODE == 3 || CC_RENDER_MODE == 2\neuler = vec3(0.0, 0.0, euler.z);\n#endif\nvec4 quat = eulerToQuat(euler);\nmat3 mLocal = quatToMat3(quat);\nmat3 mStart = quatToMat3(rot);\nrot = mat3ToQuat(mStart * mLocal);\n}\n#endif\n#if COLOR_OVER_TIME_MODULE_ENABLE\nif (u_color_mode == 1) {\ncolor = a_color * texture(color_over_time_tex0, timeCoord0);\n} else {\nvec4 color_0 = texture(color_over_time_tex0, timeCoord0);\nvec4 color_1 = texture(color_over_time_tex0, timeCoord1);\nfloat factor_c = pseudoRandom(a_rndSeed + 91041.);\ncolor = a_color * mix(color_0, color_1, factor_c);\n}\n#else\ncolor = a_color;\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((vertIdx - 0.5));\n#if CC_RENDER_MODE == 1\nrot = vec4(0.0, 0.0, 0.0, 1.0);\n#endif\ncomputeVertPos(pos, cornerOffset, rot, compScale\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, cc_matViewInv\n#endif\n#if CC_RENDER_MODE == 1\n, cc_cameraPos.xyz\n, velocity\n, frameTile_velLenScale.z\n, frameTile_velLenScale.w\n, a_size_uv.w\n#endif\n);\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor *= a_color1;\n#endif\npos = cc_matViewProj * pos;\nfloat frameIndex = 0.;\n#if TEXTURE_ANIMATION_MODULE_ENABLE\nfloat startFrame = 0.;\nvec3 frameInfo = vec3(0.);\nif (int(u_anim_info.x) == 1) {\nframeInfo = unpackCurveData(texture_animation_tex0, timeCoord0);\n} else {\nvec3 frameInfo0 = unpackCurveData(texture_animation_tex0, timeCoord0);\nvec3 frameInfo1 = unpackCurveData(texture_animation_tex0, timeCoord1);\nfloat factor_t = pseudoRandom(a_rndSeed + 90794.);\nframeInfo = mix(frameInfo0, frameInfo1, factor_t);\n}\nstartFrame = frameInfo.x / u_anim_info.y;\nframeIndex = repeat(u_anim_info.z * (frameInfo.y + startFrame), 1.);\n#endif\nuv = computeUV(frameIndex, vertIdx, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\nreturn pos;\n}\nvoid main() { gl_Position = gpvs_main(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nlayout(location = 0) in vec2 uv;\nlayout(location = 1) in vec4 color;\nlayout(set = 1, binding = 16) uniform sampler2D mainTexture;\nlayout(set = 1, binding = 9) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], [ { - "vert": "\nprecision mediump float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec4 a_texCoord;\nlayout(location = 2) in vec3 a_texCoord1;\nlayout(location = 3) in vec3 a_texCoord2;\nlayout(location = 4) in vec4 a_color;\n#if CC_DRAW_WIRE_FRAME\nlayout(location = 2) out vec3 vBarycentric;\n#endif\nvec4 vs_main() {\nhighp vec4 pos = vec4(a_position, 1);\nvec4 velocity = vec4(a_texCoord1.xyz, 0);\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\nvelocity = cc_matWorld * velocity;\n#endif\nfloat vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;\nvec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));\npos.xyz += camUp * vertOffset;\npos = cc_matViewProj * pos;\nuv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;\ncolor = a_color;\n#if CC_DRAW_WIRE_FRAME\nvBarycentric = a_texCoord2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", + "vert": "\nprecision mediump float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec4 a_texCoord;\nlayout(location = 2) in vec3 a_texCoord1;\nlayout(location = 3) in vec3 a_texCoord2;\nlayout(location = 4) in vec4 a_color;\n#if CC_DRAW_WIRE_FRAME\nlayout(location = 2) out vec3 vBarycentric;\n#endif\nvec4 vs_main() {\nhighp vec4 pos = vec4(a_position, 1);\nvec4 velocity = vec4(a_texCoord1.xyz, 0);\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\nvelocity = cc_matWorld * velocity;\n#endif\nfloat vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;\nvec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));\npos.xyz += camUp * vertOffset;\npos = cc_matViewProj * pos;\nuv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;\ncolor = a_color;\n#if CC_DRAW_WIRE_FRAME\nvBarycentric = a_texCoord2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vs_main(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nlayout(location = 0) in vec2 uv;\nlayout(location = 1) in vec4 color;\n#if CC_DRAW_WIRE_FRAME\nlayout(location = 2) in vec3 vBarycentric;\n#endif\nlayout(set = 1, binding = 2) uniform sampler2D mainTexture;\nlayout(set = 1, binding = 1) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\n#if CC_DRAW_WIRE_FRAME\nif (any(lessThan(vBarycentric, vec3(0.02)))) {\ncol = vec4(0., 1., 1., 1.);\n}\n#endif\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], [ { - "vert": "\nprecision highp float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_texCoord;\nlayout(location = 2) in vec3 a_texCoord1;\nlayout(location = 3) in vec3 a_texCoord2;\nlayout(location = 4) in vec4 a_color;\n#if CC_RENDER_MODE == 1\nlayout(location = 8) in vec3 a_color1;\n#endif\n#if CC_RENDER_MODE == 4\nlayout(location = 6) in vec3 a_texCoord3;\nlayout(location = 7) in vec3 a_normal;\nlayout(location = 8) in vec4 a_color1;\n#endif\nvec4 lpvs_main () {\nvec3 compScale = scale.xyz * a_texCoord1;\nvec4 pos = vec4(a_position, 1);\n#if CC_RENDER_MODE == 1\nvec4 velocity = vec4(a_color1.xyz, 0);\n#endif\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = cc_matWorld * velocity;\n#endif\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nvec3 rotTmp = a_texCoord2;\nfloat mulFactor = 1.0;\nif (rotTmp.x > 10.0 * 0.5) {\nrotTmp.x -= 10.0;\nmulFactor = -1.0;\n}\nvec4 rot = vec4(rotTmp, 0.0);\nrot.w = mulFactor * sqrt(abs(1.0 - rot.x * rot.x - rot.y * rot.y - rot.z * rot.z));\n#else\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = a_texCoord2;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., a_texCoord2.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(a_texCoord2);\n#endif\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((a_texCoord.xy - 0.5));\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_matViewInv);\n#elif CC_RENDER_MODE == 1\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_cameraPos.xyz, velocity, frameTile_velLenScale.z, frameTile_velLenScale.w, a_texCoord.x);\n#elif 2\ncomputeVertPos(pos, cornerOffset, rot, compScale);\n#endif\ncolor = a_color;\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor = a_color * a_color1;\n#endif\nuv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\npos = cc_matViewProj * pos;\nreturn pos;\n}\nvoid main() { gl_Position = lpvs_main(); }", + "vert": "\nprecision highp float;\nvec4 quaternionFromAxis (vec3 xAxis,vec3 yAxis,vec3 zAxis){\nmat3 m = mat3(xAxis,yAxis,zAxis);\nfloat trace = m[0][0] + m[1][1] + m[2][2];\nvec4 quat;\nif (trace > 0.) {\nfloat s = 0.5 / sqrt(trace + 1.0);\nquat.w = 0.25 / s;\nquat.x = (m[2][1] - m[1][2]) * s;\nquat.y = (m[0][2] - m[2][0]) * s;\nquat.z = (m[1][0] - m[0][1]) * s;\n} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {\nfloat s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);\nquat.w = (m[2][1] - m[1][2]) / s;\nquat.x = 0.25 * s;\nquat.y = (m[0][1] + m[1][0]) / s;\nquat.z = (m[0][2] + m[2][0]) / s;\n} else if (m[1][1] > m[2][2]) {\nfloat s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);\nquat.w = (m[0][2] - m[2][0]) / s;\nquat.x = (m[0][1] + m[1][0]) / s;\nquat.y = 0.25 * s;\nquat.z = (m[1][2] + m[2][1]) / s;\n} else {\nfloat s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);\nquat.w = (m[1][0] - m[0][1]) / s;\nquat.x = (m[0][2] + m[2][0]) / s;\nquat.y = (m[1][2] + m[2][1]) / s;\nquat.z = 0.25 * s;\n}\nfloat len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;\nif (len > 0.) {\nlen = 1. / sqrt(len);\nquat.x = quat.x * len;\nquat.y = quat.y * len;\nquat.z = quat.z * len;\nquat.w = quat.w * len;\n}\nreturn quat;\n}\nvec4 quaternionFromEuler (vec3 angle){\nfloat x = angle.x / 2.;\nfloat y = angle.y / 2.;\nfloat z = angle.z / 2.;\nfloat sx = sin(x);\nfloat cx = cos(x);\nfloat sy = sin(y);\nfloat cy = cos(y);\nfloat sz = sin(z);\nfloat cz = cos(z);\nvec4 quat = vec4(0);\nquat.x = sx * cy * cz + cx * sy * sz;\nquat.y = cx * sy * cz + sx * cy * sz;\nquat.z = cx * cy * sz - sx * sy * cz;\nquat.w = cx * cy * cz - sx * sy * sz;\nreturn quat;\n}\nmat4 matrixFromRT (vec4 q, vec3 p){\nfloat x2 = q.x + q.x;\nfloat y2 = q.y + q.y;\nfloat z2 = q.z + q.z;\nfloat xx = q.x * x2;\nfloat xy = q.x * y2;\nfloat xz = q.x * z2;\nfloat yy = q.y * y2;\nfloat yz = q.y * z2;\nfloat zz = q.z * z2;\nfloat wx = q.w * x2;\nfloat wy = q.w * y2;\nfloat wz = q.w * z2;\nreturn mat4(\n1. - (yy + zz), xy + wz, xz - wy, 0,\nxy - wz, 1. - (xx + zz), yz + wx, 0,\nxz + wy, yz - wx, 1. - (xx + yy), 0,\np.x, p.y, p.z, 1\n);\n}\nmat4 matFromRTS (vec4 q, vec3 t, vec3 s){\nfloat x = q.x, y = q.y, z = q.z, w = q.w;\nfloat x2 = x + x;\nfloat y2 = y + y;\nfloat z2 = z + z;\nfloat xx = x * x2;\nfloat xy = x * y2;\nfloat xz = x * z2;\nfloat yy = y * y2;\nfloat yz = y * z2;\nfloat zz = z * z2;\nfloat wx = w * x2;\nfloat wy = w * y2;\nfloat wz = w * z2;\nfloat sx = s.x;\nfloat sy = s.y;\nfloat sz = s.z;\nreturn mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,\n(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,\n(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,\nt.x, t.y, t.z, 1);\n}\nvec4 quatMultiply (vec4 a, vec4 b){\nvec4 quat;\nquat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;\nquat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;\nquat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;\nquat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;\nreturn quat;\n}\nvoid rotateVecFromQuat (inout vec3 v, vec4 q){\nfloat ix = q.w * v.x + q.y * v.z - q.z * v.y;\nfloat iy = q.w * v.y + q.z * v.x - q.x * v.z;\nfloat iz = q.w * v.z + q.x * v.y - q.y * v.x;\nfloat iw = -q.x * v.x - q.y * v.y - q.z * v.z;\nv.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;\nv.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;\nv.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;\n}\nvec3 rotateInLocalSpace (vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){\nvec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);\nvec4 rotQuat = quatMultiply(viewQuat, q);\nrotateVecFromQuat(pos, rotQuat);\nreturn pos;\n}\nmat3 quatToMat3(vec4 q) {\nvec3 m0 = vec3(\n1.0 - 2.0 * q.y * q.y - 2.0 * q.z * q.z,\n2.0 * q.x * q.y + 2.0 * q.w * q.z,\n2.0 * q.x * q.z - 2.0 * q.w * q.y);\nvec3 m1 = vec3(\n2.0 * q.x * q.y - 2.0 * q.w * q.z,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.z * q.z,\n2.0 * q.y * q.z + 2.0 * q.w * q.x);\nvec3 m2 = vec3(\n2.0 * q.x * q.z + 2.0 * q.w * q.y,\n2.0 * q.y * q.z - 2.0 * q.w * q.x,\n1.0 - 2.0 * q.x * q.x - 2.0 * q.y * q.y);\nreturn mat3(m0, m1, m2);\n}\nvec4 mat3ToQuat(mat3 mat) {\nfloat tr = mat[0][0] + mat[1][1] + mat[2][2];\nfloat qw, qx, qy, qz;\nif (tr > 0.0) {\nfloat S = sqrt(tr + 1.0) * 2.0;\nfloat invS = 1.0 / S;\nqw = 0.25 * S;\nqx = (mat[1][2] - mat[2][1]) * invS;\nqy = (mat[2][0] - mat[0][2]) * invS;\nqz = (mat[0][1] - mat[1][0]) * invS;\n} else if ((mat[0][0] > mat[1][1])&&(mat[0][0] > mat[2][2])) {\nfloat S = sqrt(1.0 + mat[0][0] - mat[1][1] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[1][2] - mat[2][1]) * invS;\nqx = 0.25 * S;\nqy = (mat[1][0] + mat[0][1]) * invS;\nqz = (mat[2][0] + mat[0][2]) * invS;\n} else if (mat[1][1] > mat[2][2]) {\nfloat S = sqrt(1.0 + mat[1][1] - mat[0][0] - mat[2][2]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[2][0] - mat[0][2]) * invS;\nqx = (mat[1][0] + mat[0][1]) * invS;\nqy = 0.25 * S;\nqz = (mat[2][1] + mat[1][2]) * invS;\n} else {\nfloat S = sqrt(1.0 + mat[2][2] - mat[0][0] - mat[1][1]) * 2.0;\nfloat invS = 1.0 / S;\nqw = (mat[0][1] - mat[1][0]) * invS;\nqx = (mat[2][0] + mat[0][2]) * invS;\nqy = (mat[2][1] + mat[1][2]) * invS;\nqz = 0.25 * S;\n}\nreturn vec4(qx, qy, qz, qw);\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 mainTiling_Offset;\nvec4 frameTile_velLenScale;\nvec4 scale;\nvec4 nodeRotation;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(location = 0) out mediump vec2 uv;\nlayout(location = 1) out mediump vec4 color;\nvoid computeVertPos (inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\n, mat4 viewInv\n#endif\n#if CC_RENDER_MODE == 1\n, vec3 eye\n, vec4 velocity\n, float velocityScale\n, float lengthScale\n, float xIndex\n#endif\n) {\n#if CC_RENDER_MODE == 0\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));\nvec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));\nvec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);\n#elif CC_RENDER_MODE == 1\nvec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;\nvec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;\npos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;\n#elif CC_RENDER_MODE == 2\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nvec3 camX = vec3(1, 0, 0);\nvec3 camY = vec3(0, 0, -1);\npos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);\n#elif CC_RENDER_MODE == 3\nvec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);\nrotateVecFromQuat(viewSpaceVert, q);\nvec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));\nvec3 camY = vec3(0, 1, 0);\nvec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;\npos.xyz += offset;\n#else\npos.x += vertOffset.x;\npos.y += vertOffset.y;\n#endif\n}\nvec2 computeUV (float frameIndex, vec2 vertIndex, vec2 frameTile){\nvec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));\naniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);\n#if CC_RENDER_MODE != 4\nvertIndex.y = 1. - vertIndex.y;\n#endif\nreturn (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);\n}\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_texCoord;\nlayout(location = 2) in vec3 a_texCoord1;\nlayout(location = 3) in vec3 a_texCoord2;\nlayout(location = 4) in vec4 a_color;\n#if CC_RENDER_MODE == 1\nlayout(location = 8) in vec3 a_color1;\n#endif\n#if CC_RENDER_MODE == 4\nlayout(location = 6) in vec3 a_texCoord3;\nlayout(location = 7) in vec3 a_normal;\nlayout(location = 8) in vec4 a_color1;\n#endif\nvec4 lpvs_main () {\nvec3 compScale = scale.xyz * a_texCoord1;\nvec4 pos = vec4(a_position, 1);\n#if CC_RENDER_MODE == 1\nvec4 velocity = vec4(a_color1.xyz, 0);\n#endif\n#if !CC_USE_WORLD_SPACE\npos = cc_matWorld * pos;\n#if CC_RENDER_MODE == 1\nvelocity = cc_matWorld * velocity;\n#endif\n#endif\n#if ROTATION_OVER_TIME_MODULE_ENABLE\nvec3 rotTmp = a_texCoord2;\nfloat mulFactor = 1.0;\nif (rotTmp.x > 10.0 * 0.5) {\nrotTmp.x -= 10.0;\nmulFactor = -1.0;\n}\nvec4 rot = vec4(rotTmp, 0.0);\nrot.w = mulFactor * sqrt(abs(1.0 - rot.x * rot.x - rot.y * rot.y - rot.z * rot.z));\n#else\n#if CC_RENDER_MODE != 4\n#if CC_RENDER_MODE == 0\nvec3 rotEuler = a_texCoord2;\n#elif CC_RENDER_MODE == 1\nvec3 rotEuler = vec3(0.);\n#else\nvec3 rotEuler = vec3(0., 0., a_texCoord2.z);\n#endif\nvec4 rot = quaternionFromEuler(rotEuler);\n#else\nvec4 rot = quaternionFromEuler(a_texCoord2);\n#endif\n#endif\n#if CC_RENDER_MODE != 4\nvec2 cornerOffset = vec2((a_texCoord.xy - 0.5));\n#if CC_RENDER_MODE == 0 || CC_RENDER_MODE == 3\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_matViewInv);\n#elif CC_RENDER_MODE == 1\ncomputeVertPos(pos, cornerOffset, rot, compScale, cc_cameraPos.xyz, velocity, frameTile_velLenScale.z, frameTile_velLenScale.w, a_texCoord.x);\n#elif 2\ncomputeVertPos(pos, cornerOffset, rot, compScale);\n#endif\ncolor = a_color;\n#else\nmat3 rotMat = quatToMat3(rot);\nmat3 nodeMat = quatToMat3(nodeRotation);\nrotMat = nodeMat * rotMat;\nrot = mat3ToQuat(rotMat);\nmat4 xformNoScale = matrixFromRT(rot, pos.xyz);\nmat4 xform = matFromRTS(rot, pos.xyz, compScale);\npos = xform * vec4(a_texCoord3, 1);\nvec4 normal = xformNoScale * vec4(a_normal, 0);\ncolor = a_color * a_color1;\n#endif\nuv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;\npos = cc_matViewProj * pos;\nreturn pos;\n}\nvoid main() { gl_Position = lpvs_main(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nlayout(location = 0) in vec2 uv;\nlayout(location = 1) in vec4 color;\nlayout(set = 1, binding = 2) uniform sampler2D mainTexture;\nlayout(set = 1, binding = 1) uniform FragConstants {\nvec4 tintColor;\n};\nvec4 add () {\nvec4 col = 2.0 * color * tintColor * texture(mainTexture, uv);\nreturn CCFragOutput(col);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = add(); }", } ], [ { - "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nlayout(location = 0) out vec4 v_light;\nlayout(location = 1) out vec2 uv0;\n#if TWO_COLORED\nlayout(location = 3) in vec4 a_color2;\nlayout(location = 2) out vec4 v_dark;\n#endif\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\npos = cc_matViewProj * pos;\nuv0 = a_texCoord;\nv_light = a_color;\n#if TWO_COLORED\nv_dark = a_color2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nlayout(location = 0) out vec4 v_light;\nlayout(location = 1) out vec2 uv0;\n#if TWO_COLORED\nlayout(location = 3) in vec4 a_color2;\nlayout(location = 2) out vec4 v_dark;\n#endif\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\npos = cc_matViewProj * pos;\nuv0 = a_texCoord;\nv_light = a_color;\n#if TWO_COLORED\nv_dark = a_color2;\n#endif\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\n#if USE_ALPHA_TEST\nlayout(set = 1, binding = 0) uniform ALPHA_TEST_DATA {\nfloat alphaThreshold;\n};\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n#if USE_ALPHA_TEST\nif (color.a < alphaThreshold) discard;\n#endif\n}\nvoid ALPHA_TEST (in float alpha) {\n#if USE_ALPHA_TEST\nif (alpha < alphaThreshold) discard;\n#endif\n}\nlayout(location = 0) in vec4 v_light;\n#if TWO_COLORED\nlayout(location = 2) in vec4 v_dark;\n#endif\nlayout(location = 1) in vec2 uv0;\nlayout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;\nvec4 frag () {\nvec4 o = vec4(1, 1, 1, 1);\n#if TWO_COLORED\nvec4 texColor = vec4(1, 1, 1, 1);\ntexColor *= texture(cc_spriteTexture, uv0);\no.a = texColor.a * v_light.a;\no.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;\n#else\no *= texture(cc_spriteTexture, uv0);\no *= v_light;\n#endif\nALPHA_TEST(o);\nreturn o;\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#if SAMPLE_FROM_RT\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#endif\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nlayout(location = 0) out vec4 color;\nlayout(location = 1) out vec2 uv0;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\n#if USE_PIXEL_ALIGNMENT\npos = cc_matView * pos;\npos.xyz = floor(pos.xyz);\npos = cc_matProj * pos;\n#else\npos = cc_matViewProj * pos;\n#endif\nuv0 = a_texCoord;\n#if SAMPLE_FROM_RT\nuv0 = cc_cameraPos.w > 1.0 ? vec2(uv0.x, 1.0 - uv0.y) : uv0;\n#endif\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_LOCAL\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#if SAMPLE_FROM_RT\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#endif\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nlayout(location = 0) out vec4 color;\nlayout(location = 1) out vec2 uv0;\nvec4 vert () {\nvec4 pos = vec4(a_position, 1);\n#if USE_LOCAL\npos = cc_matWorld * pos;\n#endif\n#if USE_PIXEL_ALIGNMENT\npos = cc_matView * pos;\npos.xyz = floor(pos.xyz);\npos = cc_matProj * pos;\n#else\npos = cc_matViewProj * pos;\n#endif\nuv0 = a_texCoord;\n#if SAMPLE_FROM_RT\nuv0 = cc_cameraPos.w > 1.0 ? vec2(uv0.x, 1.0 - uv0.y) : uv0;\n#endif\ncolor = a_color;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec4 CCSampleWithAlphaSeparated(sampler2D tex, vec2 uv) {\n#if CC_USE_EMBEDDED_ALPHA\nreturn vec4(texture(tex, uv).rgb, texture(tex, uv + vec2(0.0, 0.5)).r);\n#else\nreturn texture(tex, uv);\n#endif\n}\n#if USE_ALPHA_TEST\nlayout(set = 1, binding = 0) uniform ALPHA_TEST_DATA {\nfloat alphaThreshold;\n};\n#endif\nvoid ALPHA_TEST (in vec4 color) {\n#if USE_ALPHA_TEST\nif (color.a < alphaThreshold) discard;\n#endif\n}\nvoid ALPHA_TEST (in float alpha) {\n#if USE_ALPHA_TEST\nif (alpha < alphaThreshold) discard;\n#endif\n}\nlayout(location = 0) in vec4 color;\n#if USE_TEXTURE\nlayout(location = 1) in vec2 uv0;\nlayout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;\n#endif\nvec4 frag () {\nvec4 o = vec4(1, 1, 1, 1);\n#if USE_TEXTURE\no *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);\n#if IS_GRAY\nfloat gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;\no.r = o.g = o.b = gray;\n#endif\n#endif\no *= color;\nALPHA_TEST(o);\nreturn o;\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nlayout(location = 1) out highp vec4 v_shadowPos;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 14) in vec4 a_color;\nlayout(location = 2) out vec4 v_color;\n#endif\nlayout(location = 3) out vec3 v_position;\nlayout(location = 4) out vec3 v_normal;\nlayout(location = 5) out vec2 v_uv;\nlayout(location = 6) out vec2 v_uv1;\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) out vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) out vec3 v_tangent;\nlayout(location = 9) out vec3 v_bitangent;\n#endif\n#if HAS_SECOND_UV || USE_LIGHTMAP\nlayout(location = 15) in vec2 a_texCoord1;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 10) out vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_bitangent = cross(v_normal, v_tangent) * In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", - "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(location = 1) in highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 10) in vec3 v_luv;\nlayout(set = 2, binding = 10) uniform sampler2D cc_lightingMap;\n#endif\nlayout(location = 3) in vec3 v_position;\nlayout(location = 5) in vec2 v_uv;\nlayout(location = 6) in vec2 v_uv1;\nlayout(location = 4) in vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) in vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 2) in vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nlayout(set = 1, binding = 1) uniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) in vec3 v_tangent;\nlayout(location = 9) in vec3 v_bitangent;\nlayout(set = 1, binding = 2) uniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nlayout(set = 1, binding = 3) uniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nlayout(set = 1, binding = 4) uniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nlayout(set = 1, binding = 5) uniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nlayout(set = 1, binding = 6) uniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(cc_lightingMap, v_luv.xy);\ns.lightmap = lightColor.xyz * v_luv.z;\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5);\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent) +\n(nmmp.y * emissiveScaleParam.w) * normalize(v_bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 7) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 8) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 9) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor2 = vec4(s.emissive, s.occlusion);\n}\n#endif", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nlayout(location = 1) out highp vec4 v_shadowPos;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 14) in vec4 a_color;\nlayout(location = 2) out vec4 v_color;\n#endif\nlayout(location = 3) out vec3 v_position;\nlayout(location = 4) out vec3 v_normal;\nlayout(location = 5) out vec2 v_uv;\nlayout(location = 6) out vec2 v_uv1;\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) out vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) out vec3 v_tangent;\nlayout(location = 9) out vec3 v_bitangent;\n#endif\n#if HAS_SECOND_UV || USE_LIGHTMAP\nlayout(location = 15) in vec2 a_texCoord1;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 10) out vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.zw;\nv_luv.z = cc_lightingMapUVParam.z;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.zw;\nv_luv.z = a_lightingMapUVParam.z;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_bitangent = cross(v_normal, v_tangent) * In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", + "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(location = 1) in highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 10) in vec3 v_luv;\nlayout(set = 2, binding = 10) uniform sampler2D cc_lightingMap;\nvec3 UnpackLightingmap(vec4 color) {\nvec3 c;\nfloat e = 1.0 + color.a * (8.0 - 1.0);\nc.r = color.r * e;\nc.g = color.g * e;\nc.b = color.b * e;\nreturn c;\n}\n#endif\nlayout(location = 3) in vec3 v_position;\nlayout(location = 5) in vec2 v_uv;\nlayout(location = 6) in vec2 v_uv1;\nlayout(location = 4) in vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) in vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 2) in vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nlayout(set = 1, binding = 1) uniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) in vec3 v_tangent;\nlayout(location = 9) in vec3 v_bitangent;\nlayout(set = 1, binding = 2) uniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nlayout(set = 1, binding = 3) uniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nlayout(set = 1, binding = 4) uniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nlayout(set = 1, binding = 5) uniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nlayout(set = 1, binding = 6) uniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(cc_lightingMap, v_luv.xy);\ns.lightmap = UnpackLightingmap(lightColor);\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5);\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent) +\n(nmmp.y * emissiveScaleParam.w) * normalize(v_bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 7) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 8) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 9) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nfragColor1 = vec4(position, s.roughness);\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor3 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if HAS_SECOND_UV || USE_LIGHTMAP\nlayout(location = 14) in vec2 a_texCoord1;\n#endif\nlayout(location = 0) out vec2 v_uv;\nlayout(location = 1) out vec2 v_uv1;\nlayout(location = 2) out vec4 v_worldPos;\nlayout(location = 3) out float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", - "frag": "\nprecision highp float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\nlayout(location = 0) in vec2 v_uv;\nlayout(location = 1) in vec2 v_uv1;\nlayout(location = 2) in vec4 v_worldPos;\nlayout(location = 3) in float v_clip_depth;\n#if USE_ALBEDO_MAP\nlayout(set = 1, binding = 1) uniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if HAS_SECOND_UV || USE_LIGHTMAP\nlayout(location = 14) in vec2 a_texCoord1;\n#endif\nlayout(location = 0) out vec2 v_uv;\nlayout(location = 1) out vec2 v_uv1;\nlayout(location = 2) out vec4 v_worldPos;\nlayout(location = 3) out float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "frag": "\nprecision highp float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\nlayout(location = 0) in vec2 v_uv;\nlayout(location = 1) in vec2 v_uv1;\nlayout(location = 2) in vec4 v_worldPos;\nlayout(location = 3) in float v_clip_depth;\n#if USE_ALBEDO_MAP\nlayout(set = 1, binding = 1) uniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nlayout(location = 1) out highp vec4 v_shadowPos;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\n#endif\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\n#if CC_RECEIVE_SHADOW\nlayout(location = 2) out vec2 v_shadowBias;\n#endif\nlayout(location = 3) out highp vec3 v_position;\nlayout(location = 4) out mediump vec3 v_normal;\n#if USE_NORMALMAP\nlayout(location = 5) out mediump vec3 v_tangent;\nlayout(location = 6) out mediump vec3 v_binormal;\n#endif\nlayout(location = 7) out mediump vec2 uvw;\nlayout(location = 8) out mediump vec2 uv0;\nlayout(location = 9) out mediump vec2 uv1;\nlayout(location = 10) out mediump vec2 uv2;\nlayout(location = 11) out mediump vec2 uv3;\nlayout(location = 12) out mediump vec3 luv;\nlayout(location = 13) out mediump vec3 diffuse;\nlayout(set = 1, binding = 0) uniform TexCoords {\nvec4 UVScale;\nvec4 lightMapUVParam;\n};\nvoid main () {\nvec3 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nvec4 pos = vec4(worldPos, 1.0);\npos = cc_matViewProj * pos;\nuvw = a_texCoord;\nuv0 = a_position.xz * UVScale.x;\nuv1 = a_position.xz * UVScale.y;\nuv2 = a_position.xz * UVScale.z;\nuv3 = a_position.xz * UVScale.w;\n#if USE_LIGHTMAP\nluv.xy = lightMapUVParam.xy + a_texCoord * lightMapUVParam.z;\nluv.z = lightMapUVParam.w;\n#endif\nv_position = worldPos;\nv_normal = a_normal;\nCC_TRANSFER_FOG(vec4(worldPos, 1.0));\n#if CC_RECEIVE_SHADOW\nv_shadowBias = vec2(0.0, 0.0);\n#endif\n#if USE_NORMALMAP\nv_tangent = vec3(1.0, 0.0, 0.0);\nv_binormal = vec3(0.0, 0.0, 1.0);\nv_binormal = cross(v_tangent, a_normal);\nv_tangent = cross(a_normal, v_binormal);\n#endif\nv_shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0);\ngl_Position = pos;\n}", - "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\nlayout(location = 1) in highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 14) in vec3 v_luv;\nlayout(set = 2, binding = 10) uniform sampler2D cc_lightingMap;\n#endif\nlayout(location = 3) in highp vec3 v_position;\nlayout(location = 4) in mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nlayout(location = 2) in vec2 v_shadowBias;\n#endif\n#if USE_NORMALMAP\nlayout(location = 5) in mediump vec3 v_tangent;\nlayout(location = 6) in mediump vec3 v_binormal;\n#endif\nlayout(location = 7) in mediump vec2 uvw;\nlayout(location = 8) in mediump vec2 uv0;\nlayout(location = 9) in mediump vec2 uv1;\nlayout(location = 10) in mediump vec2 uv2;\nlayout(location = 11) in mediump vec2 uv3;\nlayout(location = 13) in mediump vec3 diffuse;\nlayout(location = 12) in mediump vec3 luv;\nlayout(set = 1, binding = 1) uniform PbrParams {\nvec4 metallic;\nvec4 roughness;\n};\nlayout(set = 1, binding = 2) uniform sampler2D weightMap;\nlayout(set = 1, binding = 3) uniform sampler2D detailMap0;\nlayout(set = 1, binding = 4) uniform sampler2D detailMap1;\nlayout(set = 1, binding = 5) uniform sampler2D detailMap2;\nlayout(set = 1, binding = 6) uniform sampler2D detailMap3;\nlayout(set = 1, binding = 7) uniform sampler2D normalMap0;\nlayout(set = 1, binding = 8) uniform sampler2D normalMap1;\nlayout(set = 1, binding = 9) uniform sampler2D normalMap2;\nlayout(set = 1, binding = 10) uniform sampler2D normalMap3;\nlayout(set = 1, binding = 11) uniform sampler2D lightMap;\nvoid surf (out StandardSurface s) {\n#if LAYERS > 1\nvec4 w = texture(weightMap, uvw);\n#endif\nvec4 baseColor = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseColor = texture(detailMap0, uv0);\n#elif LAYERS == 2\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\nbaseColor += texture(detailMap3, uv3) * w.a;\n#else\nbaseColor = texture(detailMap0, uv0);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\n#if USE_NORMALMAP\nvec4 baseNormal = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseNormal = texture(normalMap0, uv0);\n#elif LAYERS == 2\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\nbaseNormal += texture(normalMap3, uv3) * w.a;\n#else\nbaseNormal = texture(normalMap0, uv0);\n#endif\nvec3 nmmp = baseNormal.xyz - vec3(0.5);\ns.normal =\nnmmp.x * normalize(v_tangent) +\nnmmp.y * normalize(v_binormal) +\nnmmp.z * normalize(v_normal);\n#else\ns.normal = v_normal;\n#endif\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\ns.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0);\ns.occlusion = 1.0;\n#if USE_PBR\ns.roughness = 0.0;\n#if LAYERS == 1\ns.roughness = roughness.x;\n#elif LAYERS == 2\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\n#elif LAYERS == 3\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\n#elif LAYERS == 4\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\ns.roughness += roughness.w * w.a;\n#else\ns.roughness = 1.0;\n#endif\ns.metallic = 0.0;\n#if LAYERS == 1\ns.metallic = metallic.x;\n#elif LAYERS == 2\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\n#elif LAYERS == 3\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\n#elif LAYERS == 4\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\ns.metallic += metallic.w * w.a;\n#else\ns.metallic = 0.0;\n#endif\n#else\ns.roughness = 1.0;\ns.metallic = 0.0;\n#endif\ns.emissive = vec3(0.0, 0.0, 0.0);\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(lightMap, luv.xy);\ns.lightmap = lightColor.xyz * luv.z;\ns.lightmap_test = luv.z;\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 12) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 13) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 14) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor2 = vec4(s.emissive, s.occlusion);\n}\n#endif", + "vert": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nlayout(location = 1) out highp vec4 v_shadowPos;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\n#endif\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\n#if CC_RECEIVE_SHADOW\nlayout(location = 2) out vec2 v_shadowBias;\n#endif\nlayout(location = 3) out highp vec3 v_position;\nlayout(location = 4) out mediump vec3 v_normal;\n#if USE_NORMALMAP\nlayout(location = 5) out mediump vec3 v_tangent;\nlayout(location = 6) out mediump vec3 v_binormal;\n#endif\nlayout(location = 7) out mediump vec2 uvw;\nlayout(location = 8) out mediump vec2 uv0;\nlayout(location = 9) out mediump vec2 uv1;\nlayout(location = 10) out mediump vec2 uv2;\nlayout(location = 11) out mediump vec2 uv3;\nlayout(location = 12) out mediump vec3 luv;\nlayout(location = 13) out mediump vec3 diffuse;\nlayout(set = 1, binding = 0) uniform TexCoords {\nvec4 UVScale;\nvec4 lightMapUVParam;\n};\nvoid main () {\nvec3 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nvec4 pos = vec4(worldPos, 1.0);\npos = cc_matViewProj * pos;\nuvw = a_texCoord;\nuv0 = a_position.xz * UVScale.x;\nuv1 = a_position.xz * UVScale.y;\nuv2 = a_position.xz * UVScale.z;\nuv3 = a_position.xz * UVScale.w;\n#if USE_LIGHTMAP\nluv.xy = lightMapUVParam.xy + a_texCoord * lightMapUVParam.zw;\nluv.z = lightMapUVParam.z;\n#endif\nv_position = worldPos;\nv_normal = a_normal;\nCC_TRANSFER_FOG(vec4(worldPos, 1.0));\n#if CC_RECEIVE_SHADOW\nv_shadowBias = vec2(0.0, 0.0);\n#endif\n#if USE_NORMALMAP\nv_tangent = vec3(1.0, 0.0, 0.0);\nv_binormal = vec3(0.0, 0.0, 1.0);\nv_binormal = cross(v_tangent, a_normal);\nv_tangent = cross(a_normal, v_binormal);\n#endif\nv_shadowPos = cc_matLightViewProj * vec4(worldPos, 1.0);\ngl_Position = pos;\n}", + "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\nlayout(location = 1) in highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 14) in vec3 v_luv;\nlayout(set = 2, binding = 10) uniform sampler2D cc_lightingMap;\nvec3 UnpackLightingmap(vec4 color) {\nvec3 c;\nfloat e = 1.0 + color.a * (8.0 - 1.0);\nc.r = color.r * e;\nc.g = color.g * e;\nc.b = color.b * e;\nreturn c;\n}\n#endif\nlayout(location = 3) in highp vec3 v_position;\nlayout(location = 4) in mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nlayout(location = 2) in vec2 v_shadowBias;\n#endif\n#if USE_NORMALMAP\nlayout(location = 5) in mediump vec3 v_tangent;\nlayout(location = 6) in mediump vec3 v_binormal;\n#endif\nlayout(location = 7) in mediump vec2 uvw;\nlayout(location = 8) in mediump vec2 uv0;\nlayout(location = 9) in mediump vec2 uv1;\nlayout(location = 10) in mediump vec2 uv2;\nlayout(location = 11) in mediump vec2 uv3;\nlayout(location = 13) in mediump vec3 diffuse;\nlayout(location = 12) in mediump vec3 luv;\nlayout(set = 1, binding = 1) uniform PbrParams {\nvec4 metallic;\nvec4 roughness;\n};\nlayout(set = 1, binding = 2) uniform sampler2D weightMap;\nlayout(set = 1, binding = 3) uniform sampler2D detailMap0;\nlayout(set = 1, binding = 4) uniform sampler2D detailMap1;\nlayout(set = 1, binding = 5) uniform sampler2D detailMap2;\nlayout(set = 1, binding = 6) uniform sampler2D detailMap3;\nlayout(set = 1, binding = 7) uniform sampler2D normalMap0;\nlayout(set = 1, binding = 8) uniform sampler2D normalMap1;\nlayout(set = 1, binding = 9) uniform sampler2D normalMap2;\nlayout(set = 1, binding = 10) uniform sampler2D normalMap3;\nlayout(set = 1, binding = 11) uniform sampler2D lightMap;\nvoid surf (out StandardSurface s) {\n#if LAYERS > 1\nvec4 w = texture(weightMap, uvw);\n#endif\nvec4 baseColor = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseColor = texture(detailMap0, uv0);\n#elif LAYERS == 2\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseColor += texture(detailMap0, uv0) * w.r;\nbaseColor += texture(detailMap1, uv1) * w.g;\nbaseColor += texture(detailMap2, uv2) * w.b;\nbaseColor += texture(detailMap3, uv3) * w.a;\n#else\nbaseColor = texture(detailMap0, uv0);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\n#if USE_NORMALMAP\nvec4 baseNormal = vec4(0, 0, 0, 0);\n#if LAYERS == 1\nbaseNormal = texture(normalMap0, uv0);\n#elif LAYERS == 2\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\n#elif LAYERS == 3\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\n#elif LAYERS == 4\nbaseNormal += texture(normalMap0, uv0) * w.r;\nbaseNormal += texture(normalMap1, uv1) * w.g;\nbaseNormal += texture(normalMap2, uv2) * w.b;\nbaseNormal += texture(normalMap3, uv3) * w.a;\n#else\nbaseNormal = texture(normalMap0, uv0);\n#endif\nvec3 nmmp = baseNormal.xyz - vec3(0.5);\ns.normal =\nnmmp.x * normalize(v_tangent) +\nnmmp.y * normalize(v_binormal) +\nnmmp.z * normalize(v_normal);\n#else\ns.normal = v_normal;\n#endif\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\ns.albedo = vec4(SRGBToLinear(baseColor.rgb), 1.0);\ns.occlusion = 1.0;\n#if USE_PBR\ns.roughness = 0.0;\n#if LAYERS == 1\ns.roughness = roughness.x;\n#elif LAYERS == 2\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\n#elif LAYERS == 3\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\n#elif LAYERS == 4\ns.roughness += roughness.x * w.r;\ns.roughness += roughness.y * w.g;\ns.roughness += roughness.z * w.b;\ns.roughness += roughness.w * w.a;\n#else\ns.roughness = 1.0;\n#endif\ns.metallic = 0.0;\n#if LAYERS == 1\ns.metallic = metallic.x;\n#elif LAYERS == 2\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\n#elif LAYERS == 3\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\n#elif LAYERS == 4\ns.metallic += metallic.x * w.r;\ns.metallic += metallic.y * w.g;\ns.metallic += metallic.z * w.b;\ns.metallic += metallic.w * w.a;\n#else\ns.metallic = 0.0;\n#endif\n#else\ns.roughness = 1.0;\ns.metallic = 0.0;\n#endif\ns.emissive = vec3(0.0, 0.0, 0.0);\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(lightMap, luv.xy);\ns.lightmap = UnpackLightingmap(lightColor);\ns.lightmap_test = luv.z;\n#endif\n}\n#if CC_FORWARD_ADD\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\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 12) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 13) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 14) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nfragColor1 = vec4(position, s.roughness);\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor3 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 0) out vec2 v_clip_depth;\nvec4 vert () {\nvec4 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nworldPos.w = 1.0;\nvec4 clipPos = cc_matLightViewProj * worldPos;\nv_clip_depth = clipPos.zw;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 0) out vec2 v_clip_depth;\nvec4 vert () {\nvec4 worldPos;\nworldPos.x = cc_matWorld[3][0] + a_position.x;\nworldPos.y = cc_matWorld[3][1] + a_position.y;\nworldPos.z = cc_matWorld[3][2] + a_position.z;\nworldPos.w = 1.0;\nvec4 clipPos = cc_matLightViewProj * worldPos;\nv_clip_depth = clipPos.zw;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(location = 0) in vec2 v_clip_depth;\nvec4 frag () {\nreturn packDepthToRGBA(v_clip_depth.x / v_clip_depth.y * 0.5 + 0.5);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nlayout(location = 14) in lowp vec4 a_color;\nlayout(location = 1) out lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nlayout(location = 2) out vec2 v_uv;\nlayout(set = 1, binding = 0) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nlayout(location = 14) in lowp vec4 a_color;\nlayout(location = 1) out lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nlayout(location = 2) out vec2 v_uv;\nlayout(set = 1, binding = 0) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#if USE_ALPHA_TEST\n#endif\n#if USE_TEXTURE\nlayout(location = 2) in vec2 v_uv;\nlayout(set = 1, binding = 2) uniform sampler2D mainTexture;\n#endif\nlayout(set = 1, binding = 1) uniform Constant {\nvec4 mainColor;\nvec4 colorScaleAndCutoff;\n};\n#if USE_VERTEX_COLOR\nlayout(location = 1) in lowp vec4 v_color;\n#endif\nvec4 frag () {\nvec4 o = mainColor;\no.rgb *= colorScaleAndCutoff.xyz;\n#if USE_VERTEX_COLOR\no.rgb *= SRGBToLinear(v_color.rgb);\no.a *= v_color.a;\n#endif\n#if USE_TEXTURE\nvec4 texColor = texture(mainTexture, v_uv);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\no *= texColor;\n#endif\n#if USE_ALPHA_TEST\nif (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;\n#endif\nCC_APPLY_FOG(o);\nreturn CCFragOutput(o);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nfloat luminance(vec3 color) {\nreturn dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\nvoid main() {\nvec3 color = texture(outputResultMap, v_uv).xyz;\nif (luminance(SRGBToLinear(color)) > texSize.z) {\nfragColor = vec4(color, 1.0);\n} else {\nfragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n}", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 downsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main()\n{\nvec3 result = downsample4taps(v_uv, 1.0 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 upsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main() {\nvec3 result = upsample4taps(v_uv, 0.5 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D outputResultMap;\nlayout(set = 1, binding = 2) uniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvoid main() {\nvec4 hdrColor = texture(outputResultMap, v_uv);\nvec3 bloomColor = texture(bloomTexture, v_uv).rgb;\nvec3 result = hdrColor.rgb + bloomColor * texSize.w * hdrColor.a;\nfragColor = vec4(result, hdrColor.a);\n}", } ], [ { - "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nvec4 position;\nposition = vec4(a_position, 1.0);\nposition.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\ngl_Position = vec4(position.x, position.y, 1.0, 1.0);\nv_uv = a_texCoord;\n}", - "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn 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\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec3 oct_to_float32x3(vec2 e) {\nvec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\nif (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\nreturn normalize(v);\n}\nvec4 screen2WS(vec3 coord) {\nvec3 ndc = vec3(\n2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\ncoord.z);\nvec4 world = ((cc_matViewProjInv) * (vec4(ndc, 1.0)));\nworld = world / world.w;\nreturn world;\n}\nlayout(location = 0) in vec2 v_uv;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nlayout(set = 1, binding = 0, input_attachment_index = 0) uniform subpassInput gbuffer_albedoMap;\nlayout(set = 1, binding = 1, input_attachment_index = 1) uniform subpassInput gbuffer_normalMap;\nlayout(set = 1, binding = 2, input_attachment_index = 2) uniform subpassInput gbuffer_emissiveMap;\n#else\nlayout(set = 1, binding = 0) uniform sampler2D gbuffer_albedoMap;\nlayout(set = 1, binding = 1) uniform sampler2D gbuffer_normalMap;\nlayout(set = 1, binding = 2) uniform sampler2D gbuffer_emissiveMap;\n#endif\nlayout(set = 1, binding = 3) uniform sampler2D depth_stencil;\n#if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450\nlayout(location = 0) out vec4 fragColor;\n#endif\nvoid main () {\nStandardSurface s;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nvec4 albedoMap = subpassLoad(gbuffer_albedoMap);\nvec4 normalMap = subpassLoad(gbuffer_normalMap);\nvec4 emissiveMap = subpassLoad(gbuffer_emissiveMap);\n#else\nvec4 albedoMap = texture(gbuffer_albedoMap,v_uv);\nvec4 normalMap = texture(gbuffer_normalMap,v_uv);\nvec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv);\n#endif\nfloat depth = texture(depth_stencil, v_uv).x;\ns.albedo = albedoMap;\nvec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\ns.position = position;\ns.roughness = normalMap.z;\ns.normal = oct_to_float32x3(normalMap.xy);\ns.metallic = normalMap.w;\ns.emissive = emissiveMap.xyz;\ns.occlusion = emissiveMap.w;\nfloat fogFactor;\nCC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\nvec4 shadowPos;\nshadowPos = cc_matLightViewProj * vec4(position, 1);\nvec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nCCClusterShadingAdditive(s, shadowPos);\n#else\nCCStandardShadingAdditive(s, shadowPos);\n#endif\nCC_APPLY_FOG_BASE(color, fogFactor);\ncolor = CCFragOutput(color);\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nfragColor = color;\n#else\nfragColor = color;\n#endif\n}", + "vert": "\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nvec4 position;\nposition = vec4(a_position, 1.0);\nposition.xy = cc_cameraPos.w == 0.0 ? vec2(position.xy.x, -position.xy.y) : position.xy;\ngl_Position = vec4(position.x, position.y, 1.0, 1.0);\nv_uv = a_texCoord;\n}", + "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nfloat CCGetLinearDepthFromViewSpace(vec3 viewPos) {\nfloat dist = length(viewPos);\nreturn (dist - cc_shadowNFLSInfo.x) / (cc_shadowNFLSInfo.y - cc_shadowNFLSInfo.x);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn CCGetLinearDepthFromViewSpace(viewStartPos.xyz);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias)\n{\nvec4 newShadowPos = shadowPos;\nif(normalBias > 0.0001)\n{\nvec4 viewNormal = cc_matLightView * vec4(worldNormal, 0.0);\nif(viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * cc_shadowProjInfo.xy * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > 0.000001) {\nclipSpacePos.z = CCGetLinearDepthFromViewSpace(viewSpacePos.xyz);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias)\n{\nfloat coeffA = cc_shadowProjDepthInfo.x;\nfloat coeffB = cc_shadowProjDepthInfo.y;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetShadowFactorHard (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_shadowMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_shadowMap, clipPos.xy).x;\n}\nshadow = step(clipPos.z, closestDepth);\nreturn shadow;\n}\nfloat CCGetShadowFactorSoft (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetShadowFactorSoft2X (vec4 shadowPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Orthographic(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat offsetDepth = clipPos.z;\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(offsetDepth, dot(texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(offsetDepth, texture(cc_shadowMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat shadow = 0.0;\nfloat closestDepth = 0.0;\nfloat depth = clipPos.z;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nclosestDepth = dot(texture(cc_spotLightingMap, clipPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0));\n} else {\nclosestDepth = texture(cc_spotLightingMap, clipPos.xy).x;\n}\nshadow = step(depth, closestDepth);\nreturn shadow;\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 oneTap = 1.0 / cc_shadowWHPBInfo.xy;\nvec2 clipPos_offset = clipPos.xy + oneTap;\nfloat block0, block1, block2, block3;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos.y)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset.y)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset.x, clipPos_offset.y)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * cc_shadowWHPBInfo.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(clipPos.y, oneTap.y) * cc_shadowWHPBInfo.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat CCGetSpotLightShadowFactorSoft2X (vec4 shadowPos, vec3 worldPos, float bias) {\nvec4 clipPosNew = ApplyShadowDepthBias_Perspective(shadowPos, bias);\nvec3 clipPos = clipPosNew.xyz / clipPosNew.w * 0.5 + 0.5;\nif (clipPos.x < 0.0 || clipPos.x > 1.0 ||\nclipPos.y < 0.0 || clipPos.y > 1.0 ||\nclipPos.z < 0.0 || clipPos.z > 1.0) { return 1.0; }\nclipPos.xy = cc_cameraPos.w == 1.0 ? vec2(clipPos.xy.x, 1.0 - clipPos.xy.y) : clipPos.xy;\nfloat depth = 0.0;\nif (cc_shadowNFLSInfo.z > 0.000001) {\ndepth = CCGetLinearDepth(worldPos);\n} else {\ndepth = clipPos.z;\n}\nvec2 mapSize = cc_shadowWHPBInfo.xy;\nvec2 oneTap = 1.0 / mapSize;\nfloat clipPos_offset_L = clipPos.x - oneTap.x;\nfloat clipPos_offset_R = clipPos.x + oneTap.x;\nfloat clipPos_offset_U = clipPos.y - oneTap.y;\nfloat clipPos_offset_D = clipPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\nif (cc_shadowLPNNInfo.y > 0.000001) {\nblock0 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(depth, dot(texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n} else {\nblock0 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_U)).x);\nblock1 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_U)).x);\nblock2 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_U)).x);\nblock3 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos.y)).x);\nblock4 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos.y)).x);\nblock5 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos.y)).x);\nblock6 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_L, clipPos_offset_D)).x);\nblock7 = step(depth, texture(cc_spotLightingMap, vec2(clipPos.x, clipPos_offset_D)).x);\nblock8 = step(depth, texture(cc_spotLightingMap, vec2(clipPos_offset_R, clipPos_offset_D)).x);\n}\nfloat coefX = mod(clipPos.x, oneTap.x) * mapSize.x;\nfloat coefY = mod(clipPos.y, oneTap.y) * mapSize.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft2X(shadowPos, worldPos, shadowBias.x);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(shadowPos, worldPos, shadowBias.x);\n}else {\nreturn CCGetSpotLightShadowFactorHard(shadowPos, worldPos, shadowBias.x);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 1.9) {\nrealtimeShadow = CCGetShadowFactorSoft2X(pos, shadowBias.x);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetShadowFactorSoft(pos, shadowBias.x);\n}else {\nrealtimeShadow = CCGetShadowFactorHard(pos, shadowBias.x);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse;\n#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > 0.0001) {\nfinalColor = s.lightmap.rgb;\n}\n#else\ndiffuseContrib /= PI;\n#endif\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn 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\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nfloat LinearFog(vec4 pos) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cc_cameraPos, wPos);\nfloat fogStart = cc_fogBase.x;\nfloat fogEnd = cc_fogBase.y;\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat fogStart = cc_fogBase.x;\nfloat fogDensity = cc_fogBase.z;\nfloat cam_dis = max(distance(cc_cameraPos, wPos) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos) {\nvec4 wPos = pos;\nfloat fogAtten = cc_fogAdd.z;\nfloat _FogTop = cc_fogAdd.x;\nfloat _FogRange = cc_fogAdd.y;\nvec3 camWorldProj = cc_cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cc_cameraPos.y > _FogTop) {\nif (wPos.y < _FogTop) {\nfDeltaY = (_FogTop - wPos.y) / _FogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n} else {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n} else {\nif (wPos.y < _FogTop) {\nfloat fDeltaA = (_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfloat fDeltaB = (_FogTop - wPos.y) / _FogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n} else {\nfDeltaY = abs(_FogTop - cc_cameraPos.y) / _FogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n} else {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec3 oct_to_float32x3(vec2 e) {\nvec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));\nif (v.z < 0.0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);\nreturn normalize(v);\n}\nvec4 screen2WS(vec3 coord) {\nvec3 ndc = vec3(\n2.0 * (coord.x - cc_viewPort.x) / cc_viewPort.z - 1.0,\n2.0 * (coord.y - cc_viewPort.y) / cc_viewPort.w - 1.0,\ncoord.z);\nvec4 world = ((cc_matViewProjInv) * (vec4(ndc, 1.0)));\nworld = world / world.w;\nreturn world;\n}\nlayout(location = 0) in vec2 v_uv;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nlayout(set = 1, binding = 0, input_attachment_index = 0) uniform subpassInput gbuffer_albedoMap;\nlayout(set = 1, binding = 1, input_attachment_index = 1) uniform subpassInput gbuffer_normalMap;\nlayout(set = 1, binding = 2, input_attachment_index = 2) uniform subpassInput gbuffer_emissiveMap;\n#else\nlayout(set = 1, binding = 0) uniform sampler2D gbuffer_albedoMap;\nlayout(set = 1, binding = 1) uniform sampler2D gbuffer_normalMap;\nlayout(set = 1, binding = 2) uniform sampler2D gbuffer_emissiveMap;\n#endif\nlayout(set = 1, binding = 3) uniform sampler2D depth_stencil;\n#if !CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT || __VERSION__ >= 450\nlayout(location = 0) out vec4 fragColor;\n#endif\nvoid main () {\nStandardSurface s;\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nvec4 albedoMap = subpassLoad(gbuffer_albedoMap);\nvec4 normalMap = subpassLoad(gbuffer_normalMap);\nvec4 emissiveMap = subpassLoad(gbuffer_emissiveMap);\n#else\nvec4 albedoMap = texture(gbuffer_albedoMap,v_uv);\nvec4 normalMap = texture(gbuffer_normalMap,v_uv);\nvec4 emissiveMap = texture(gbuffer_emissiveMap,v_uv);\n#endif\nfloat depth = texture(depth_stencil, v_uv).x;\ns.albedo = albedoMap;\nvec3 position = screen2WS(vec3(gl_FragCoord.xy, depth)).xyz;\ns.position = position;\ns.roughness = normalMap.z;\ns.normal = oct_to_float32x3(normalMap.xy);\ns.metallic = normalMap.w;\ns.emissive = emissiveMap.xyz;\ns.occlusion = emissiveMap.w;\nfloat fogFactor;\nCC_TRANSFER_FOG_BASE(vec4(position, 1), fogFactor);\nvec4 shadowPos;\nshadowPos = cc_matLightViewProj * vec4(position, 1);\nvec4 color = CCStandardShadingBase(s, shadowPos) +\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nCCClusterShadingAdditive(s, shadowPos);\n#else\nCCStandardShadingAdditive(s, shadowPos);\n#endif\nCC_APPLY_FOG_BASE(color, fogFactor);\ncolor = CCFragOutput(color);\n#if CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT\nfragColor = color;\n#else\nfragColor = color;\n#endif\n}", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(location = 0) out float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#endif\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(location = 0) out float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nlayout(location = 0) in float v_dist;\nvec4 frag () {\nif(v_dist < 0.0)\ndiscard;\nreturn CCFragOutput(cc_shadowColor);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\n#if USE_INSTANCING\nlayout(location = 13) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#if ANTIALIAS_TYPE == 1\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\nvec2 v_rgbNW, vec2 v_rgbNE,\nvec2 v_rgbSW, vec2 v_rgbSE,\nvec2 v_rgbM) {\nvec4 color;\nmediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\nvec3 rgbNW = texture(tex, v_rgbNW).xyz;\nvec3 rgbNE = texture(tex, v_rgbNE).xyz;\nvec3 rgbSW = texture(tex, v_rgbSW).xyz;\nvec3 rgbSE = texture(tex, v_rgbSE).xyz;\nvec4 texColor = texture(tex, v_rgbM);\nvec3 rgbM = texColor.xyz;\nvec3 luma = vec3(0.299, 0.587, 0.114);\nfloat lumaNW = dot(rgbNW, luma);\nfloat lumaNE = dot(rgbNE, luma);\nfloat lumaSW = dot(rgbSW, luma);\nfloat lumaSE = dot(rgbSE, luma);\nfloat lumaM = dot(rgbM, luma);\nfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\nfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\nmediump vec2 dir;\ndir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\ndir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\nfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n(0.25 * (1.0 / 8.0)), (1.0/ 128.0));\nfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\ndir = min(vec2(8.0, 8.0),\nmax(vec2(-8.0, -8.0),\ndir * rcpDirMin)) * inverseVP;\nvec3 rgbA = 0.5 * (\ntexture(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\ntexture(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\nvec3 rgbB = rgbA * 0.5 + 0.25 * (\ntexture(tex, fragCoord * inverseVP + dir * -0.5).xyz +\ntexture(tex, fragCoord * inverseVP + dir * 0.5).xyz);\nfloat lumaB = dot(rgbB, luma);\nif ((lumaB < lumaMin) || (lumaB > lumaMax))\ncolor = vec4(rgbA, texColor.a);\nelse\ncolor = vec4(rgbB, texColor.a);\nreturn color;\n}\n#endif\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nvoid texcoords(vec2 fragCoord, vec2 resolution,\nout vec2 v_rgbNW, out vec2 v_rgbNE,\nout vec2 v_rgbSW, out vec2 v_rgbSE,\nout vec2 v_rgbM) {\nvec2 inverseVP = 1.0 / resolution.xy;\nv_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\nv_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\nv_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\nv_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\nv_rgbM = vec2(fragCoord * inverseVP);\n}\nvoid main () {\nmediump vec2 v_rgbNW;\nmediump vec2 v_rgbNE;\nmediump vec2 v_rgbSW;\nmediump vec2 v_rgbSE;\nmediump vec2 v_rgbM;\n#if ANTIALIAS_TYPE == 1\nvec2 resolution = cc_screenSize.xy;\nvec2 fragCoord = v_uv * resolution;\ntexcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\nfragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n#else\nfragColor = texture(outputResultMap, v_uv);\n#endif\n}", } ], [ { - "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define INV_PI 0.31830988618\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\n#endif\n#if CC_USE_SKINNING\n#if !CC_PLATFORM_NX\nlayout(location = 4) in u32vec4 a_joints;\n#else\nlayout(location = 4) in vec4 a_joints;\n#endif\nlayout(location = 5) in vec4 a_weights;\n#endif\nlayout(location = 0) out mediump vec4 viewDir;\nvec4 vert () {\nviewDir = vec4(a_position, 1.0);\nmat4 matViewRotOnly = mat4(mat3(cc_matView));\nvec4 pos = matViewRotOnly * viewDir;\nif (cc_matProj[3].w > 0.0) {\nmat4 matProj = cc_matProj;\nmatProj[0].x = 5.2;\nmatProj[1].y = 2.6;\nmatProj[2].zw = vec2(-1.0);\nmatProj[3].zw = vec2(0.0);\npos = matProj * pos;\n} else {\npos = cc_matProj * pos;\n}\npos.z = 0.99999 * pos.w;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define EPSILON 1e-6\n#define LOG2 1.442695\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 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 USE_INSTANCING\nlayout(location = 6) in vec4 a_matWorld0;\nlayout(location = 7) in vec4 a_matWorld1;\nlayout(location = 8) in vec4 a_matWorld2;\n#if USE_LIGHTMAP\nlayout(location = 9) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 10) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 11) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\n#endif\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\nlayout(location = 0) out mediump vec4 viewDir;\nvec4 vert () {\nviewDir = vec4(a_position, 1.0);\nmat4 matViewRotOnly = mat4(mat3(cc_matView));\nvec4 pos = matViewRotOnly * viewDir;\nif (cc_matProj[3].w > 0.0) {\nmat4 matProj = cc_matProj;\nmatProj[0].x = 5.2;\nmatProj[1].y = 2.6;\nmatProj[2].zw = vec2(-1.0);\nmatProj[3].zw = vec2(0.0);\npos = matProj * pos;\n} else {\npos = cc_matProj * pos;\n}\npos.z = 0.99999 * pos.w;\nreturn pos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\n};\nlayout(set = 0, binding = 1) uniform CCCamera {\nhighp mat4 cc_matView;\nhighp mat4 cc_matViewInv;\nhighp mat4 cc_matProj;\nhighp mat4 cc_matProjInv;\nhighp mat4 cc_matViewProj;\nhighp mat4 cc_matViewProjInv;\nhighp vec4 cc_cameraPos;\nmediump vec4 cc_screenScale;\nmediump vec4 cc_exposure;\nmediump vec4 cc_mainLitDir;\nmediump vec4 cc_mainLitColor;\nmediump vec4 cc_ambientSky;\nmediump vec4 cc_ambientGround;\nmediump vec4 cc_fogColor;\nmediump vec4 cc_fogBase;\nmediump vec4 cc_fogAdd;\nmediump vec4 cc_nearFar;\nmediump vec4 cc_viewPort;\n};\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(location = 0) in mediump vec4 viewDir;\nvec4 frag () {\n#if USE_RGBE_CUBEMAP\nvec3 c = unpackRGBE(texture(cc_environment, viewDir.xyz));\n#else\nvec3 c = SRGBToLinear(texture(cc_environment, viewDir.xyz).rgb);\n#endif\nreturn CCFragOutput(vec4(c * cc_ambientSky.w, 1.0));\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ],