diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ecb4049 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# ChangeLog + +## 0.1.0 (2020-01-01) + +- 加入马赛克特效 +- 加入老照片特效 +- 加入内发光特效 +- 加入外发光特效(未完善) +- 加入描边特效(未完善) \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..18e4ba7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Zhitao Cai + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 09b0019..8a7ef47 100755 --- a/README.md +++ b/README.md @@ -1,2 +1,80 @@ -# hello-world -Hello world new project template. +# Cocos Creator Shader Effect Demo + +[![](https://img.shields.io/badge/Release-0.1.0-green.svg)](CHANGELOG.md) +[![](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) +[![](https://img.shields.io/badge/Support-Cocos%20Creator%20v2.2.1-orange.svg)](http://www.cocos.com/creator) + +## 项目说明 + +1. 此项目为我在学习过程中的一些分享和实现,因此项目名字以 **`Demo`** 为后缀。 +2. 项目重点在于 **「渔」**,不在于 **「鱼」** 。 +3. 如果你有意将此Demo中的效果加入到你的项目中,**请认真评估是否适合你的项目使用!** + +## 系列文章 + +* [Cocos Creator Shader Effect 系列 - 0 - 前言](https://www.jianshu.com/p/20b906d7269c) +* [Cocos Creator Shader Effect 系列 - 1 - 材质,Effect,Inspector,纹理之间的关系](https://www.jianshu.com/p/ca28666d25d2) +* 编写中... + + +## 特效预览 + +那么现在,我们先来轻松地看下有哪些特效效果吧~ + +### 内发光([实现原理及使用说明]() 编写中... ,催更麻烦移步一下到文末 **激活作者** 😜) + +![](static/effects/2d-sprite-glow-inner.gif) + +### 马赛克([实现原理及使用说明]() 编写中... ,催更麻烦移步一下到文末 **激活作者** 😜) + +![](static/effects/2d-sprite-mosaic.gif) + +### 老照片([实现原理及使用说明]() 编写中... ,催更麻烦移步一下到文末 **激活作者** 😜) + +![](static/effects/2d-sprite-old-photo.gif) + +### 外发光(完善中...) + +### 外描边(完善中...) + +## TODO + +* [ ] 图像裁剪 +* [ ] 图像模糊 +* [ ] 闪光 +* [ ] 波浪 +* [ ] 雨滴 +* [ ] ... + +## 支持一下作者吧 + +如果此项目对你学习和理解Shader有帮助,不妨支持一下我吧~ + +ps:支持扫码催更哦🤣🤣🤣👇👇👇👇 + +![](static/PAY.png) + + +## LICENSE + + MIT License + + Copyright (c) 2020 Zhitao Cai + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. diff --git a/assets/effects/sprite-example.effect b/assets/effects/builtin-2d-sprite-explain.effect similarity index 94% rename from assets/effects/sprite-example.effect rename to assets/effects/builtin-2d-sprite-explain.effect index 8e2009f..d7ef9b1 100644 --- a/assets/effects/sprite-example.effect +++ b/assets/effects/builtin-2d-sprite-explain.effect @@ -46,6 +46,7 @@ CCProgram vs %{ // in 用在函数的参数中,表示这个参数是输入的,在函数中改变这个值,并不会影响对调用的函数产生副作用。(相当于C语言的传值),这个是函数参数默认的修饰符 // 顶点坐标 + // a_position 是笛卡尔坐标右手系,也是OpenGL的坐标系,原点在左下角,X轴正方向往右,Y轴正方向往上,Z轴正方向往外 in vec3 a_position; // 顶点颜色,实际为对应节点的颜色 @@ -61,6 +62,7 @@ CCProgram vs %{ #if USE_TEXTURE // 输入的纹理坐标 + // a_uv0 是标准屏幕坐标系,即原点在左上角,X轴正方向往右,Y轴正方向往下 in vec2 a_uv0; // 输出的纹理坐标 diff --git a/assets/effects/sprite-example.effect.meta b/assets/effects/builtin-2d-sprite-explain.effect.meta similarity index 100% rename from assets/effects/sprite-example.effect.meta rename to assets/effects/builtin-2d-sprite-explain.effect.meta diff --git a/assets/effects/sprite-glow-inner.effect b/assets/effects/sprite-glow-inner.effect new file mode 100644 index 0000000..9023148 --- /dev/null +++ b/assets/effects/sprite-glow-inner.effect @@ -0,0 +1,261 @@ +// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. +// 内发光特效 +// 原理: 采样周边像素alpha取平均值,叠加发光效果 +CCEffect %{ + techniques: + - passes: + - vert: vs + frag: fs + blendState: + targets: + - blend: true + rasterizerState: + cullMode: none + properties: + texture: { value: white } + alphaThreshold: { value: 0.5 } + + # 自定义参数 + # 发光颜色 + glowColor: { + value: [1.0, 1.0, 0.0, 1.0], + inspector: { + type: color, + tooltip: "发光颜色" + } + } + # 发光宽度 + glowColorSize: { + value: 0.2, + inspector: { + tooltip: "发光宽度", + range: [0.0, 1.0], + } + } + # 发光透明度阈值 + # 只有超过这个透明度的点才会发光 + # 一般用于解决图像边缘存在渐变透明的时,决定超过这个透明度阈值的边缘点才点发光,具体可以操作一下 + glowThreshold: { + value: 0.1, + inspector: { + tooltip: "发光阈值", + range: [0.0, 1.0] + } + } +}% + + +CCProgram vs %{ + precision highp float; + + #include + #include + + in vec3 a_position; + in vec4 a_color; + out vec4 v_color; + + #if USE_TEXTURE + in vec2 a_uv0; + out vec2 v_uv0; + #endif + + void main () { + vec4 pos = vec4(a_position, 1); + + #if CC_USE_MODEL + pos = cc_matViewProj * cc_matWorld * pos; + #else + pos = cc_matViewProj * pos; + #endif + + #if USE_TEXTURE + v_uv0 = a_uv0; + #endif + + v_color = a_color; + + gl_Position = pos; + } +}% + + +CCProgram fs %{ + precision highp float; + + #include + + in vec4 v_color; + + #if USE_TEXTURE + in vec2 v_uv0; + uniform sampler2D texture; + #endif + + #if SHOW_INNER_GLOW + + uniform glow { + // 发光颜色 + vec4 glowColor; + // 发光范围 + float glowColorSize; + // 发光阈值 + float glowThreshold; + // 特别地,必须是 vec4 先于 float 声明 + }; + + /** + * 获取纹理uv颜色 + * + * 主要实现:超出边界的统一返回 vec4(0.0, 0.0, 0.0, 0.0) + * + * 在 Cocos Creator 2.2.1 的编辑器中,超出边界的uv并不是返回 vec4(0.0, 0.0, 0.0, 0.0),实际返回为 + * + * * 超出左边界的uv,返回 v_uv0.x = 0 的颜色 + * * 超出右边界的uv,返回 v_uv0.x = 1 的颜色 + * * 超出上边界的uv,返回 v_uv0.y = 1 的颜色 + * * 超出下边界的uv,返回 v_uv0.y = 0 的颜色 + * + * 和实际在浏览器上显示(超出边界即为透明)的有区别,为了统一,这里适配一下,这样子,在编辑器上预览的效果就能和实际浏览器的保持一致 + */ + vec4 getTextureColor(sampler2D texture, vec2 v_uv0) { + if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) { + return vec4(0.0, 0.0, 0.0, 0.0); + } + return texture(texture, v_uv0); + } + + + /** + * 获取指定角度方向,距离为xxx的像素的透明度 + * + * @param angle 角度 [0.0, 360.0] + * @param dist 距离 [0.0, 1.0] + * + * @return alpha [0.0, 1.0] + */ + float getColorAlpha(float angle, float dist) { + // 角度转弧度,公式为:弧度 = 角度 * (pi / 180) + float radian = angle * 0.01745329252; // 这个浮点数是 pi / 180 + vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian))); + return color.a; + } + + /** + * 获取指定距离的周边像素的透明度平均值 + * + * @param dist 距离 [0.0, 1.0] + * + * @return average alpha [0.0, 1.0] + */ + float getAverageAlpha(float dist) { + + + float totalAlpha = 0.0; + // 以30度为一个单位,那么「周边一圈」就由0到360度中共计12个点的组成 + totalAlpha += getColorAlpha(0.0, dist); + totalAlpha += getColorAlpha(30.0, dist); + totalAlpha += getColorAlpha(60.0, dist); + totalAlpha += getColorAlpha(90.0, dist); + totalAlpha += getColorAlpha(120.0, dist); + totalAlpha += getColorAlpha(150.0, dist); + totalAlpha += getColorAlpha(180.0, dist); + totalAlpha += getColorAlpha(210.0, dist); + totalAlpha += getColorAlpha(240.0, dist); + totalAlpha += getColorAlpha(270.0, dist); + totalAlpha += getColorAlpha(300.0, dist); + totalAlpha += getColorAlpha(330.0, dist); + return totalAlpha * 0.0833; // 1 / 12 = 0.08333 + } + + /** + * 获取发光的透明度 + */ + float getGlowAlpha() { + // 如果发光宽度为0,直接返回0.0透明度,减少计算量 + if (glowColorSize == 0.0) { + return 0.0; + } + + // 因为我们是要做内发光,所以如果点本来是透明的或者接近透明的 + // 那么就意味着这个点是图像外的透明点或者图像内透明点(如空洞)之类的 + // 内发光的话,这些透明点我们不用处理,让它保持原样,否则就是会有内描边或者一点扩边的效果 + // 同时也是提前直接结束,减少计算量 + vec4 srcColor = getTextureColor(texture, v_uv0); + if (srcColor.a <= glowThreshold) { + return srcColor.a; + } + + // 将传入的指定距离,平均分成10圈,求出每一圈的平均透明度, + // 然后求和取平均值,那么就可以得到该点的平均透明度 + float totalAlpha = 0.0; + totalAlpha += getAverageAlpha(glowColorSize * 0.1); + totalAlpha += getAverageAlpha(glowColorSize * 0.2); + totalAlpha += getAverageAlpha(glowColorSize * 0.3); + totalAlpha += getAverageAlpha(glowColorSize * 0.4); + totalAlpha += getAverageAlpha(glowColorSize * 0.5); + totalAlpha += getAverageAlpha(glowColorSize * 0.6); + totalAlpha += getAverageAlpha(glowColorSize * 0.7); + totalAlpha += getAverageAlpha(glowColorSize * 0.8); + totalAlpha += getAverageAlpha(glowColorSize * 0.9); + totalAlpha += getAverageAlpha(glowColorSize * 1.0); + return totalAlpha * 0.1; + } + + #endif + + void main () { + vec4 o = vec4(1, 1, 1, 1); + + #if USE_TEXTURE + o *= getTextureColor(texture, v_uv0); + #if CC_USE_ALPHA_ATLAS_TEXTURE + o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r; + #endif + #endif + + o *= v_color; + + ALPHA_TEST(o); + + gl_FragColor = o; + + #if SHOW_INNER_GLOW + // 目标颜色(图像) + vec4 color_dest = o; + + // 获取发光透明度 + // 此时我们得到的是内部透明度为1,靠近边缘的为接近0的透明度,其他位置为0的透明度 + float alpha = getGlowAlpha(); + + // 而内发光是从边缘开始的,那么什么算是边缘呢? + // 如果图像边缘有大量渐变,那么如果我们取大于 0.0 点就算是图像内的话,那么可能边缘会出现锯齿 + // 因此为了确定边缘,引入了发光阈值,我们只需要比较一下发光阈值就可以,大于发光阈值的点都是(图像内)发光点 + if (alpha > glowThreshold) { + + // 内发光是从边缘发光的,是需要内部透明度为0,靠近边缘的接近1的透明度 + // 因此我们需要翻转一下透明度 + alpha = 1.0 - alpha; + + // 给点调料,让靠近边缘的更加亮 + alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0; + } + // 源颜色(内发光) + vec4 color_src = glowColor * alpha; + + // 按照这个顺序,源颜色就是内发光颜色,目标颜色就是图案颜色色 + // 所以命名就是 color_src, color_dest + + // 按照混合颜色规则 http://docs.cocos.com/creator/manual/zh/advanced-topics/ui-auto-batch.html#blend-%E6%A8%A1%E5%BC%8F + // 要在图案上方,叠加一个内发光,将两者颜色混合起来,那么最终选择的混合模式如下: + // + // (内发光)color_src: GL_SRC_ALPHA + // (原图像)color_dest: GL_ONE + // + // 即最终颜色如下: + // color_src * GL_SRC_ALPHA + color_dest * GL_ONE + + gl_FragColor = color_src * color_src.a + color_dest; + #endif + } +}% diff --git a/assets/effects/sprite-glow-inner.effect.meta b/assets/effects/sprite-glow-inner.effect.meta new file mode 100644 index 0000000..7749874 --- /dev/null +++ b/assets/effects/sprite-glow-inner.effect.meta @@ -0,0 +1,17 @@ +{ + "ver": "1.0.23", + "uuid": "90211f16-c00e-4c37-a192-43ec50c9ea35", + "compiledShaders": [ + { + "glsl1": { + "vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\n\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if SHOW_INNER_GLOW\n\nuniform vec4 glowColor;\nuniform float glowColorSize;\nuniform float glowThreshold;\n\n/**\n * 获取纹理uv颜色 \n *\n * 主要实现:超出边界的统一返回 vec4(0.0, 0.0, 0.0, 0.0)\n * \n * 在 Cocos Creator 2.2.1 的编辑器中,超出边界的uv并不是返回 vec4(0.0, 0.0, 0.0, 0.0),实际返回为\n * \n * * 超出左边界的uv,返回 v_uv0.x = 0 的颜色\n * * 超出右边界的uv,返回 v_uv0.x = 1 的颜色\n * * 超出上边界的uv,返回 v_uv0.y = 1 的颜色\n * * 超出下边界的uv,返回 v_uv0.y = 0 的颜色\n *\n * 和实际在浏览器上显示(超出边界即为透明)的有区别,为了统一,这里适配一下,这样子,在编辑器上预览的效果就能和实际浏览器的保持一致\n */\nvec4 getTextureColor(sampler2D texture, vec2 v_uv0) {\n if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) {\n return vec4(0.0, 0.0, 0.0, 0.0);\n }\n return texture2D(texture, v_uv0);\n}\n\n/**\n * 获取指定角度方向,距离为xxx的像素的透明度\n *\n * @param angle 角度 [0.0, 360.0]\n * @param dist 距离 [0.0, 1.0]\n *\n * @return alpha [0.0, 1.0]\n */\nfloat getColorAlpha(float angle, float dist) {\n\n float radian = angle * 0.01745329252;\n\n vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian))); \n return color.a;\n}\n\n/**\n * 获取指定距离的周边像素的透明度平均值\n *\n * @param dist 距离 [0.0, 1.0]\n *\n * @return average alpha [0.0, 1.0]\n */\nfloat getAverageAlpha(float dist) {\n\n float totalAlpha = 0.0;\n\n totalAlpha += getColorAlpha(0.0, dist);\n totalAlpha += getColorAlpha(30.0, dist);\n totalAlpha += getColorAlpha(60.0, dist);\n totalAlpha += getColorAlpha(90.0, dist);\n totalAlpha += getColorAlpha(120.0, dist);\n totalAlpha += getColorAlpha(150.0, dist);\n totalAlpha += getColorAlpha(180.0, dist);\n totalAlpha += getColorAlpha(210.0, dist);\n totalAlpha += getColorAlpha(240.0, dist);\n totalAlpha += getColorAlpha(270.0, dist);\n totalAlpha += getColorAlpha(300.0, dist);\n totalAlpha += getColorAlpha(330.0, dist);\n return totalAlpha * 0.0833;\n\n}\n\n/**\n * 获取发光的透明度\n */\nfloat getGlowAlpha() {\n\n if (glowColorSize == 0.0) {\n return 0.0;\n }\n\n vec4 srcColor = getTextureColor(texture, v_uv0);\n if (srcColor.a <= glowThreshold) {\n return srcColor.a;\n }\n\n float totalAlpha = 0.0;\n totalAlpha += getAverageAlpha(glowColorSize * 0.1);\n totalAlpha += getAverageAlpha(glowColorSize * 0.2);\n totalAlpha += getAverageAlpha(glowColorSize * 0.3);\n totalAlpha += getAverageAlpha(glowColorSize * 0.4);\n totalAlpha += getAverageAlpha(glowColorSize * 0.5);\n totalAlpha += getAverageAlpha(glowColorSize * 0.6);\n totalAlpha += getAverageAlpha(glowColorSize * 0.7);\n totalAlpha += getAverageAlpha(glowColorSize * 0.8);\n totalAlpha += getAverageAlpha(glowColorSize * 0.9);\n totalAlpha += getAverageAlpha(glowColorSize * 1.0);\n return totalAlpha * 0.1;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= getTextureColor(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_INNER_GLOW\n\n vec4 color_dest = o;\n\n float alpha = getGlowAlpha();\n\n if (alpha > glowThreshold) {\n\n alpha = 1.0 - alpha;\n\n alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0;\n }\n\n vec4 color_src = glowColor * alpha;\n\n gl_FragColor = color_src * color_src.a + color_dest;\n #endif\n}\n" + }, + "glsl3": { + "vert": "\nprecision highp float;\nuniform CCGlobal {\n vec4 cc_time;\n\n vec4 cc_screenSize;\n\n vec4 cc_screenScale;\n\n vec4 cc_nativeSize;\n\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n\n vec4 cc_exposure;\n\n vec4 cc_mainLitDir;\n\n vec4 cc_mainLitColor;\n\n vec4 cc_ambientSky;\n vec4 cc_ambientGround;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\n\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 a_uv0;\nout vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if SHOW_INNER_GLOW\n\nuniform glow {\n\n vec4 glowColor;\n\n float glowColorSize;\n\n float glowThreshold;\n\n};\n\n/**\n * 获取纹理uv颜色 \n *\n * 主要实现:超出边界的统一返回 vec4(0.0, 0.0, 0.0, 0.0)\n * \n * 在 Cocos Creator 2.2.1 的编辑器中,超出边界的uv并不是返回 vec4(0.0, 0.0, 0.0, 0.0),实际返回为\n * \n * * 超出左边界的uv,返回 v_uv0.x = 0 的颜色\n * * 超出右边界的uv,返回 v_uv0.x = 1 的颜色\n * * 超出上边界的uv,返回 v_uv0.y = 1 的颜色\n * * 超出下边界的uv,返回 v_uv0.y = 0 的颜色\n *\n * 和实际在浏览器上显示(超出边界即为透明)的有区别,为了统一,这里适配一下,这样子,在编辑器上预览的效果就能和实际浏览器的保持一致\n */\nvec4 getTextureColor(sampler2D texture, vec2 v_uv0) {\n if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) {\n return vec4(0.0, 0.0, 0.0, 0.0);\n }\n return texture(texture, v_uv0);\n}\n\n/**\n * 获取指定角度方向,距离为xxx的像素的透明度\n *\n * @param angle 角度 [0.0, 360.0]\n * @param dist 距离 [0.0, 1.0]\n *\n * @return alpha [0.0, 1.0]\n */\nfloat getColorAlpha(float angle, float dist) {\n\n float radian = angle * 0.01745329252;\n\n vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian))); \n return color.a;\n}\n\n/**\n * 获取指定距离的周边像素的透明度平均值\n *\n * @param dist 距离 [0.0, 1.0]\n *\n * @return average alpha [0.0, 1.0]\n */\nfloat getAverageAlpha(float dist) {\n\n float totalAlpha = 0.0;\n\n totalAlpha += getColorAlpha(0.0, dist);\n totalAlpha += getColorAlpha(30.0, dist);\n totalAlpha += getColorAlpha(60.0, dist);\n totalAlpha += getColorAlpha(90.0, dist);\n totalAlpha += getColorAlpha(120.0, dist);\n totalAlpha += getColorAlpha(150.0, dist);\n totalAlpha += getColorAlpha(180.0, dist);\n totalAlpha += getColorAlpha(210.0, dist);\n totalAlpha += getColorAlpha(240.0, dist);\n totalAlpha += getColorAlpha(270.0, dist);\n totalAlpha += getColorAlpha(300.0, dist);\n totalAlpha += getColorAlpha(330.0, dist);\n return totalAlpha * 0.0833;\n\n}\n\n/**\n * 获取发光的透明度\n */\nfloat getGlowAlpha() {\n\n if (glowColorSize == 0.0) {\n return 0.0;\n }\n\n vec4 srcColor = getTextureColor(texture, v_uv0);\n if (srcColor.a <= glowThreshold) {\n return srcColor.a;\n }\n\n float totalAlpha = 0.0;\n totalAlpha += getAverageAlpha(glowColorSize * 0.1);\n totalAlpha += getAverageAlpha(glowColorSize * 0.2);\n totalAlpha += getAverageAlpha(glowColorSize * 0.3);\n totalAlpha += getAverageAlpha(glowColorSize * 0.4);\n totalAlpha += getAverageAlpha(glowColorSize * 0.5);\n totalAlpha += getAverageAlpha(glowColorSize * 0.6);\n totalAlpha += getAverageAlpha(glowColorSize * 0.7);\n totalAlpha += getAverageAlpha(glowColorSize * 0.8);\n totalAlpha += getAverageAlpha(glowColorSize * 0.9);\n totalAlpha += getAverageAlpha(glowColorSize * 1.0);\n return totalAlpha * 0.1;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= getTextureColor(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_INNER_GLOW\n\n vec4 color_dest = o;\n\n float alpha = getGlowAlpha();\n\n if (alpha > glowThreshold) {\n\n alpha = 1.0 - alpha;\n\n alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0;\n }\n\n vec4 color_src = glowColor * alpha;\n\n gl_FragColor = color_src * color_src.a + color_dest;\n #endif\n}\n" + } + } + ], + "subMetas": {} +} \ No newline at end of file diff --git a/assets/effects/sprite-glow-outter.effect b/assets/effects/sprite-glow-outter.effect new file mode 100644 index 0000000..6241f18 --- /dev/null +++ b/assets/effects/sprite-glow-outter.effect @@ -0,0 +1,296 @@ +// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. +// 外发光特效 +// 原理:采样周边像素alpha取平均值,给外部加发光效果(1-col.a可避免内部发光) +CCEffect %{ + techniques: + - passes: + - vert: vs + frag: fs + blendState: + targets: + - blend: true + rasterizerState: + cullMode: none + properties: + texture: { value: white } + alphaThreshold: { value: 0.5 } + + # 自定义参数 + # 发光颜色 + glowColor: { + value: [1.0, 1.0, 0.0, 1.0], + inspector: { + type: color, + tooltip: "发光颜色" + } + } + # 发光宽度 + glowColorSize: { + value: 0.15, + inspector: { + tooltip: "发光宽度", + range: [0.0, 1.0], + } + } + # 发光透明度阈值 + # 只有小于等于这个透明度的点才会发光 + glowThreshold: { + value: 1.0, + inspector: { + tooltip: "发光阈值", + range: [0.0, 1.0] + } + } +}% + + +CCProgram vs %{ + precision highp float; + + #include + #include + + // a_position 是笛卡尔坐标右手系,也是OpenGL的坐标系,原点在左下角,X轴正方向往右,Y轴正方向往上,Z轴正方向往外 + in vec3 a_position; + in vec4 a_color; + out vec4 v_color; + + #if USE_TEXTURE + // a_uv0 是标准屏幕坐标系,即原点在左上角,X轴正方向往右,Y轴正方向往下 + in vec2 a_uv0; + out vec2 v_uv0; + #endif + + void main () { + vec4 pos = vec4(a_position, 1); + // vec4 pos = vec4(a_position * vec3(1.0, 1.0, 1.0), 1); + + #if CC_USE_MODEL + pos = cc_matViewProj * cc_matWorld * pos; + #else + pos = cc_matViewProj * pos; + #endif + + #if USE_TEXTURE + v_uv0 = a_uv0; + + // // 左移 + // v_uv0 = a_uv0 + vec2(0.1, 0.0); + // // 右移 + // v_uv0 = a_uv0 + vec2(-0.1, 0.0); + // // 上移 + // v_uv0 = a_uv0 + vec2(0.0, 0.1); + // // 下移 + // v_uv0 = a_uv0 + vec2(0.0, -0.1); + + // // x轴拉伸 + // v_uv0 = a_uv0 * vec2(0.5, 1.0); + // // x轴压缩 + // v_uv0 = a_uv0 * vec2(2.0, 1.0); + // // y轴拉伸 + // v_uv0 = a_uv0 * vec2(1.0, 0.5); + // // y轴压缩 + // v_uv0 = a_uv0 * vec2(1.0, 2.0); + + // 先缩小一倍,然后在移动回去中间 + // v_uv0 = a_uv0 * 2.0 - 0.5; + #endif + + v_color = a_color; + + // pos *= vec4(2.0, 2.0, 1.0, 1.0); + gl_Position = pos; + } +}% + + +CCProgram fs %{ + precision highp float; + + #include + + in vec4 v_color; + + #if USE_TEXTURE + in vec2 v_uv0; + uniform sampler2D texture; + #endif + + /** + * 获取纹理uv颜色 + * + * 主要实现:超出边界的统一返回 vec4(0.0, 0.0, 0.0, 0.0) + * + * 在 Cocos Creator 2.2.1 的编辑器中,超出边界的uv并不是返回 vec4(0.0, 0.0, 0.0, 0.0),实际返回为 + * + * * 超出左边界的uv,返回 v_uv0.x = 0 的颜色 + * * 超出右边界的uv,返回 v_uv0.x = 1 的颜色 + * * 超出上边界的uv,返回 v_uv0.y = 1 的颜色 + * * 超出下边界的uv,返回 v_uv0.y = 0 的颜色 + * + * 和实际在浏览器上显示(超出边界即为透明)的有区别,为了统一,这里适配一下,这样子,在编辑器上预览的效果就能和实际浏览器的保持一致 + */ + vec4 getTextureColor(sampler2D texture, vec2 v_uv0) { + if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) { + return vec4(0.0, 0.0, 0.0, 0.0); + } + return texture(texture, v_uv0); + } + + #if SHOW_OUTTER_GLOW + + uniform glow { + // 发光颜色 + vec4 glowColor; + // 发光范围 + float glowColorSize; + // 发光阈值 + float glowThreshold; + // 特别地,必须是 vec4 先于 float 声明 + }; + + + /** + * 获取指定角度方向,距离为xxx的像素的透明度 + * + * @param angle 角度 [0.0, 360.0] + * @param dist 距离 [0.0, 1.0] + * + * @return alpha [0.0, 1.0] + */ + float getColorAlpha(float angle, float dist) { + // 角度转弧度,公式为:弧度 = 角度 * (pi / 180) + float radian = angle * 0.01745329252; // 这个浮点数是 pi / 180 + vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian))); + return color.a; + } + + /** + * 获取指定距离的周边像素的透明度平均值 + * + * @param dist 距离 [0.0, 1.0] + * + * @return average alpha [0.0, 1.0] + */ + float getAverageAlpha(float dist) { + float totalAlpha = 0.0; + // 以30度为一个单位,那么「周边一圈」就由0到360度中共计12个点的组成 + totalAlpha += getColorAlpha(0.0, dist); + totalAlpha += getColorAlpha(30.0, dist); + totalAlpha += getColorAlpha(60.0, dist); + totalAlpha += getColorAlpha(90.0, dist); + totalAlpha += getColorAlpha(120.0, dist); + totalAlpha += getColorAlpha(150.0, dist); + totalAlpha += getColorAlpha(180.0, dist); + totalAlpha += getColorAlpha(210.0, dist); + totalAlpha += getColorAlpha(240.0, dist); + totalAlpha += getColorAlpha(270.0, dist); + totalAlpha += getColorAlpha(300.0, dist); + totalAlpha += getColorAlpha(330.0, dist); + return totalAlpha * 0.0833; // 1 / 12 = 0.08333 + + // // for 循环写法据说耗性能 + // float totalAlpha = 0.0; + // const float count = 12.0; + // const float angle = 360.0 / count; + // for (float i = 0.0; i < count; i += 1.0) { + // totalAlpha += getColorAlpha(angle * i, dist) ; + // } + // return totalAlpha / count; + } + + /** + * 获取发光的透明度 + */ + float getGlowAlpha() { + // 如果发光宽度为0,直接返回0.0透明度,减少计算量 + if (glowColorSize == 0.0) { + return 0.0; + } + + // // 因为我们是要做内发光,所以如果点本来是透明的或者接近透明的 + // // 那么就意味着这个点是图像外的透明点或者图像内透明点(如空洞)之类的 + // // 内发光的话,这些透明点我们不用处理,让它保持原样,否则就是会有内描边或者一点扩边的效果 + // // 同时也是提前直接结束,减少计算量 + // vec4 srcColor = texture(texture, v_uv0); + // if (srcColor.a <= glowThreshold) { + // return srcColor.a; + // } + + // 将传入的指定距离,平均分成10圈,求出每一圈的平均透明度, + // 然后求和取平均值,那么就可以得到该点的平均透明度 + float totalAlpha = 0.0; + totalAlpha += getAverageAlpha(glowColorSize * 0.1); + totalAlpha += getAverageAlpha(glowColorSize * 0.2); + totalAlpha += getAverageAlpha(glowColorSize * 0.3); + totalAlpha += getAverageAlpha(glowColorSize * 0.4); + totalAlpha += getAverageAlpha(glowColorSize * 0.5); + totalAlpha += getAverageAlpha(glowColorSize * 0.6); + totalAlpha += getAverageAlpha(glowColorSize * 0.7); + totalAlpha += getAverageAlpha(glowColorSize * 0.8); + totalAlpha += getAverageAlpha(glowColorSize * 0.9); + totalAlpha += getAverageAlpha(glowColorSize * 1.0); + return totalAlpha * 0.1; + } + + #endif + + void main () { + vec4 o = vec4(1, 1, 1, 1); + + #if USE_TEXTURE + o *= getTextureColor(texture, v_uv0); + #if CC_USE_ALPHA_ATLAS_TEXTURE + o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r; + #endif + #endif + + o *= v_color; + + ALPHA_TEST(o); + + gl_FragColor = o; + + #if SHOW_OUTTER_GLOW + // 获取发光透明度 + // 此时我们得到的是内部透明度为1,靠近边缘的为接近0的透明度,其他位置为0的透明度 + float alpha = getGlowAlpha(); + + // 而外发光是从边缘开始的,那么什么算是边缘呢? + // 一般图像边缘是存在渐变,即从图像内 1.0-> 0.0 图像外,那么发光边缘我们可以这样子定义 + // 当该点的透明度小于一个阈值,那么我们就当该点为一个发光点 + if (alpha <= glowThreshold) { + // 然后以阈值作为标量,重新将透明度归一化 + alpha = alpha / glowThreshold; + + // 给点调料,让靠近边缘的更加亮 + alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0; + } else { + // 然后这里大于阈值的基本就是便是图像本身,不需要发光,那么将发光透明度置为0 + alpha = 0.0; + } + + // 忽略阈值,直接处理 + // // 给点调料,让靠近边缘的更加亮 + // alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0; + + // 外发光颜色 + vec4 color_dest = glowColor * alpha; + vec4 color_src = o; + + // 本次我们将先画外发光作为背景,然后在上方放图像 + // + // 按照混合颜色规则 http://docs.cocos.com/creator/manual/zh/advanced-topics/ui-auto-batch.html#blend-%E6%A8%A1%E5%BC%8F + // + // 最终选择的混合模式如下: + // + // (原图像)color_src: GL_SRC_ALPHA + // (外发光)color_dest: GL_ONE_MINUS_SRC_ALPHAA + // + // 即最终颜色如下: + // color_src * GL_SRC_ALPHA + color_dest * GL_ONE_MINUS_SRC_ALPHAA + + gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a); + #endif + } +}% diff --git a/assets/effects/sprite-glow-outter.effect.meta b/assets/effects/sprite-glow-outter.effect.meta new file mode 100644 index 0000000..f19e5af --- /dev/null +++ b/assets/effects/sprite-glow-outter.effect.meta @@ -0,0 +1,17 @@ +{ + "ver": "1.0.23", + "uuid": "89f30b2e-b75e-49b1-9dfc-cb341cadd30a", + "compiledShaders": [ + { + "glsl1": { + "vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\n\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n\n#if USE_TEXTURE\n\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n/**\n * 获取纹理uv颜色 \n *\n * 主要实现:超出边界的统一返回 vec4(0.0, 0.0, 0.0, 0.0)\n * \n * 在 Cocos Creator 2.2.1 的编辑器中,超出边界的uv并不是返回 vec4(0.0, 0.0, 0.0, 0.0),实际返回为\n * \n * * 超出左边界的uv,返回 v_uv0.x = 0 的颜色\n * * 超出右边界的uv,返回 v_uv0.x = 1 的颜色\n * * 超出上边界的uv,返回 v_uv0.y = 1 的颜色\n * * 超出下边界的uv,返回 v_uv0.y = 0 的颜色\n *\n * 和实际在浏览器上显示(超出边界即为透明)的有区别,为了统一,这里适配一下,这样子,在编辑器上预览的效果就能和实际浏览器的保持一致\n */\nvec4 getTextureColor(sampler2D texture, vec2 v_uv0) {\n if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) {\n return vec4(0.0, 0.0, 0.0, 0.0);\n }\n return texture2D(texture, v_uv0);\n}\n\n#if SHOW_OUTTER_GLOW\n\nuniform vec4 glowColor;\nuniform float glowColorSize;\nuniform float glowThreshold;\n\n/**\n * 获取指定角度方向,距离为xxx的像素的透明度\n *\n * @param angle 角度 [0.0, 360.0]\n * @param dist 距离 [0.0, 1.0]\n *\n * @return alpha [0.0, 1.0]\n */\nfloat getColorAlpha(float angle, float dist) {\n\n float radian = angle * 0.01745329252;\n\n vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian))); \n return color.a;\n}\n\n/**\n * 获取指定距离的周边像素的透明度平均值\n *\n * @param dist 距离 [0.0, 1.0]\n *\n * @return average alpha [0.0, 1.0]\n */\nfloat getAverageAlpha(float dist) {\n float totalAlpha = 0.0;\n\n totalAlpha += getColorAlpha(0.0, dist);\n totalAlpha += getColorAlpha(30.0, dist);\n totalAlpha += getColorAlpha(60.0, dist);\n totalAlpha += getColorAlpha(90.0, dist);\n totalAlpha += getColorAlpha(120.0, dist);\n totalAlpha += getColorAlpha(150.0, dist);\n totalAlpha += getColorAlpha(180.0, dist);\n totalAlpha += getColorAlpha(210.0, dist);\n totalAlpha += getColorAlpha(240.0, dist);\n totalAlpha += getColorAlpha(270.0, dist);\n totalAlpha += getColorAlpha(300.0, dist);\n totalAlpha += getColorAlpha(330.0, dist);\n return totalAlpha * 0.0833;\n\n}\n\n/**\n * 获取发光的透明度\n */\nfloat getGlowAlpha() {\n\n if (glowColorSize == 0.0) {\n return 0.0;\n }\n\n float totalAlpha = 0.0;\n totalAlpha += getAverageAlpha(glowColorSize * 0.1);\n totalAlpha += getAverageAlpha(glowColorSize * 0.2);\n totalAlpha += getAverageAlpha(glowColorSize * 0.3);\n totalAlpha += getAverageAlpha(glowColorSize * 0.4);\n totalAlpha += getAverageAlpha(glowColorSize * 0.5);\n totalAlpha += getAverageAlpha(glowColorSize * 0.6);\n totalAlpha += getAverageAlpha(glowColorSize * 0.7);\n totalAlpha += getAverageAlpha(glowColorSize * 0.8);\n totalAlpha += getAverageAlpha(glowColorSize * 0.9);\n totalAlpha += getAverageAlpha(glowColorSize * 1.0);\n return totalAlpha * 0.1;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= getTextureColor(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_OUTTER_GLOW\n\n float alpha = getGlowAlpha();\n\n if (alpha <= glowThreshold) {\n\n alpha = alpha / glowThreshold;\n\n alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0;\n } else {\n\n alpha = 0.0;\n }\n\n vec4 color_dest = glowColor * alpha;\n vec4 color_src = o;\n\n gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);\n #endif\n}\n" + }, + "glsl3": { + "vert": "\nprecision highp float;\nuniform CCGlobal {\n vec4 cc_time;\n\n vec4 cc_screenSize;\n\n vec4 cc_screenScale;\n\n vec4 cc_nativeSize;\n\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n\n vec4 cc_exposure;\n\n vec4 cc_mainLitDir;\n\n vec4 cc_mainLitColor;\n\n vec4 cc_ambientSky;\n vec4 cc_ambientGround;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\n\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n\n#if USE_TEXTURE\n\nin vec2 a_uv0;\nout vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n/**\n * 获取纹理uv颜色 \n *\n * 主要实现:超出边界的统一返回 vec4(0.0, 0.0, 0.0, 0.0)\n * \n * 在 Cocos Creator 2.2.1 的编辑器中,超出边界的uv并不是返回 vec4(0.0, 0.0, 0.0, 0.0),实际返回为\n * \n * * 超出左边界的uv,返回 v_uv0.x = 0 的颜色\n * * 超出右边界的uv,返回 v_uv0.x = 1 的颜色\n * * 超出上边界的uv,返回 v_uv0.y = 1 的颜色\n * * 超出下边界的uv,返回 v_uv0.y = 0 的颜色\n *\n * 和实际在浏览器上显示(超出边界即为透明)的有区别,为了统一,这里适配一下,这样子,在编辑器上预览的效果就能和实际浏览器的保持一致\n */\nvec4 getTextureColor(sampler2D texture, vec2 v_uv0) {\n if (v_uv0.x > 1.0 || v_uv0.x < 0.0 || v_uv0.y > 1.0 || v_uv0.y < 0.0) {\n return vec4(0.0, 0.0, 0.0, 0.0);\n }\n return texture(texture, v_uv0);\n}\n\n#if SHOW_OUTTER_GLOW\n\nuniform glow {\n\n vec4 glowColor;\n\n float glowColorSize;\n\n float glowThreshold;\n\n};\n\n/**\n * 获取指定角度方向,距离为xxx的像素的透明度\n *\n * @param angle 角度 [0.0, 360.0]\n * @param dist 距离 [0.0, 1.0]\n *\n * @return alpha [0.0, 1.0]\n */\nfloat getColorAlpha(float angle, float dist) {\n\n float radian = angle * 0.01745329252;\n\n vec4 color = getTextureColor(texture, v_uv0 + vec2(dist * cos(radian), dist * sin(radian))); \n return color.a;\n}\n\n/**\n * 获取指定距离的周边像素的透明度平均值\n *\n * @param dist 距离 [0.0, 1.0]\n *\n * @return average alpha [0.0, 1.0]\n */\nfloat getAverageAlpha(float dist) {\n float totalAlpha = 0.0;\n\n totalAlpha += getColorAlpha(0.0, dist);\n totalAlpha += getColorAlpha(30.0, dist);\n totalAlpha += getColorAlpha(60.0, dist);\n totalAlpha += getColorAlpha(90.0, dist);\n totalAlpha += getColorAlpha(120.0, dist);\n totalAlpha += getColorAlpha(150.0, dist);\n totalAlpha += getColorAlpha(180.0, dist);\n totalAlpha += getColorAlpha(210.0, dist);\n totalAlpha += getColorAlpha(240.0, dist);\n totalAlpha += getColorAlpha(270.0, dist);\n totalAlpha += getColorAlpha(300.0, dist);\n totalAlpha += getColorAlpha(330.0, dist);\n return totalAlpha * 0.0833;\n\n}\n\n/**\n * 获取发光的透明度\n */\nfloat getGlowAlpha() {\n\n if (glowColorSize == 0.0) {\n return 0.0;\n }\n\n float totalAlpha = 0.0;\n totalAlpha += getAverageAlpha(glowColorSize * 0.1);\n totalAlpha += getAverageAlpha(glowColorSize * 0.2);\n totalAlpha += getAverageAlpha(glowColorSize * 0.3);\n totalAlpha += getAverageAlpha(glowColorSize * 0.4);\n totalAlpha += getAverageAlpha(glowColorSize * 0.5);\n totalAlpha += getAverageAlpha(glowColorSize * 0.6);\n totalAlpha += getAverageAlpha(glowColorSize * 0.7);\n totalAlpha += getAverageAlpha(glowColorSize * 0.8);\n totalAlpha += getAverageAlpha(glowColorSize * 0.9);\n totalAlpha += getAverageAlpha(glowColorSize * 1.0);\n return totalAlpha * 0.1;\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= getTextureColor(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_OUTTER_GLOW\n\n float alpha = getGlowAlpha();\n\n if (alpha <= glowThreshold) {\n\n alpha = alpha / glowThreshold;\n\n alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0;\n } else {\n\n alpha = 0.0;\n }\n\n vec4 color_dest = glowColor * alpha;\n vec4 color_src = o;\n\n gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);\n #endif\n}\n" + } + } + ], + "subMetas": {} +} \ No newline at end of file diff --git a/assets/effects/sprite-mosaic.effect b/assets/effects/sprite-mosaic.effect new file mode 100644 index 0000000..c27bb95 --- /dev/null +++ b/assets/effects/sprite-mosaic.effect @@ -0,0 +1,146 @@ +// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. +// 马赛克特效 +// 原理: n x n 方块内取同一颜色 + +CCEffect %{ + techniques: + - passes: + - vert: vs + frag: fs + blendState: + targets: + - blend: true + rasterizerState: + cullMode: none + properties: + texture: { value: white } + alphaThreshold: { value: 0.5 } + # X轴方块数量 + xBlockCount: { + value: 30.0, + inspector: { + tooltip: "X轴方向马赛克方块数量" + } + } + # Y轴方块数量 + yBlockCount: { + value: 30.0, + inspector: { + tooltip: "Y轴方向马赛克方块数量" + } + } +}% + + +CCProgram vs %{ + precision highp float; + + #include + #include + + in vec3 a_position; + in vec4 a_color; + out vec4 v_color; + + #if USE_TEXTURE + in vec2 a_uv0; + out vec2 v_uv0; + #endif + + void main () { + vec4 pos = vec4(a_position, 1); + + #if CC_USE_MODEL + pos = cc_matViewProj * cc_matWorld * pos; + #else + pos = cc_matViewProj * pos; + #endif + + #if USE_TEXTURE + v_uv0 = a_uv0; + #endif + + v_color = a_color; + + gl_Position = pos; + } +}% + + +CCProgram fs %{ + precision highp float; + + #include + + in vec4 v_color; + + #if USE_TEXTURE + in vec2 v_uv0; + uniform sampler2D texture; + #endif + + #if USE_MOSAIC + uniform Mosaic { + // X轴方块数量 + float xBlockCount; + // Y轴方块数量 + float yBlockCount; + } + + /** + * 获取v_uv0最终映射的马赛格格子的坐标 + * + * @return 映射后坐标 + */ + vec2 getUvMapPos() { + // 计算x轴格子宽度 + float xCount; + if (xBlockCount <= 0.0) { + xCount = 1.0; + } else { + xCount = xBlockCount; + } + float blockWidth = 1.0 / xCount; + + // 计算当前 v_uv0 在x轴的哪个格子上 + float blockXIndex = floor(v_uv0.x / blockWidth); + + // 同理,求出当前 v_uv0 在y轴上的哪个格子 + float yCount; + if (yBlockCount <= 0.0) { + yCount = 1.0; + } else { + yCount = yBlockCount; + } + float blockHeight = 1.0 / yCount; + float blockYIndex = floor(v_uv0.y / blockHeight); + + // 找到该格子的中心点实际对应的uv坐标 + return vec2(blockWidth * (blockXIndex + 0.5), blockHeight * (blockYIndex + 0.5)); + } + + + #endif + + void main () { + vec4 o = vec4(1, 1, 1, 1); + + vec2 realPos = v_uv0; + #if USE_MOSAIC + realPos = getUvMapPos(); + #endif + + #if USE_TEXTURE + o *= texture(texture, realPos); + #if CC_USE_ALPHA_ATLAS_TEXTURE + o.a *= texture2D(texture, realPos + vec2(0, 0.5)).r; + #endif + #endif + + o *= v_color; + + ALPHA_TEST(o); + + gl_FragColor = o; + } +}% diff --git a/assets/effects/sprite-mosaic.effect.meta b/assets/effects/sprite-mosaic.effect.meta new file mode 100644 index 0000000..0f09437 --- /dev/null +++ b/assets/effects/sprite-mosaic.effect.meta @@ -0,0 +1,17 @@ +{ + "ver": "1.0.23", + "uuid": "9638979d-62b3-4e5b-adea-7ad706e66e65", + "compiledShaders": [ + { + "glsl1": { + "vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\n\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if USE_MOSAIC\nuniform float xBlockCount;\nuniform float yBlockCount;\n/**\n * 获取v_uv0最终映射的马赛格格子的坐标\n *\n * @return 映射后坐标\n */\nvec2 getUvMapPos() {\n\n float xCount;\n if (xBlockCount <= 0.0) {\n xCount = 1.0;\n } else {\n xCount = xBlockCount;\n }\n float blockWidth = 1.0 / xCount;\n\n float blockXIndex = floor(v_uv0.x / blockWidth);\n\n float yCount; \n if (yBlockCount <= 0.0) {\n yCount = 1.0;\n } else {\n yCount = yBlockCount;\n }\n float blockHeight = 1.0 / yCount;\n float blockYIndex = floor(v_uv0.y / blockHeight);\n\n return vec2(blockWidth * (blockXIndex + 0.5), blockHeight * (blockYIndex + 0.5));\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n vec2 realPos = v_uv0;\n #if USE_MOSAIC\n realPos = getUvMapPos();\n #endif\n\n #if USE_TEXTURE\n o *= texture2D(texture, realPos);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, realPos + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n}\n" + }, + "glsl3": { + "vert": "\nprecision highp float;\nuniform CCGlobal {\n vec4 cc_time;\n\n vec4 cc_screenSize;\n\n vec4 cc_screenScale;\n\n vec4 cc_nativeSize;\n\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n\n vec4 cc_exposure;\n\n vec4 cc_mainLitDir;\n\n vec4 cc_mainLitColor;\n\n vec4 cc_ambientSky;\n vec4 cc_ambientGround;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\n\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 a_uv0;\nout vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if USE_MOSAIC\nuniform Mosaic {\n\n float xBlockCount;\n\n float yBlockCount;\n}\n\n/**\n * 获取v_uv0最终映射的马赛格格子的坐标\n *\n * @return 映射后坐标\n */\nvec2 getUvMapPos() {\n\n float xCount;\n if (xBlockCount <= 0.0) {\n xCount = 1.0;\n } else {\n xCount = xBlockCount;\n }\n float blockWidth = 1.0 / xCount;\n\n float blockXIndex = floor(v_uv0.x / blockWidth);\n\n float yCount; \n if (yBlockCount <= 0.0) {\n yCount = 1.0;\n } else {\n yCount = yBlockCount;\n }\n float blockHeight = 1.0 / yCount;\n float blockYIndex = floor(v_uv0.y / blockHeight);\n\n return vec2(blockWidth * (blockXIndex + 0.5), blockHeight * (blockYIndex + 0.5));\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n vec2 realPos = v_uv0;\n #if USE_MOSAIC\n realPos = getUvMapPos();\n #endif\n\n #if USE_TEXTURE\n o *= texture(texture, realPos);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, realPos + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n}\n" + } + } + ], + "subMetas": {} +} \ No newline at end of file diff --git a/assets/effects/sprite-old-photo.effect b/assets/effects/sprite-old-photo.effect new file mode 100644 index 0000000..b7e248a --- /dev/null +++ b/assets/effects/sprite-old-photo.effect @@ -0,0 +1,122 @@ +// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. +// 老照片特效 +// 原理: +// r = 0.393 * r + 0.769 * g + 0.189 * b; +// g = 0.349 * r + 0.686 * g + 0.168 * b; +// b = 0.272 * r + 0.534 * g + 0.131 * b; + +CCEffect %{ + techniques: + - passes: + - vert: vs + frag: fs + blendState: + targets: + - blend: true + rasterizerState: + cullMode: none + properties: + texture: { value: white } + alphaThreshold: { value: 0.5 } + # 老化程度 + oldLevel: { + value: 1.0, + inspector: { + tooltip: "老化程度", + range: [0.0, 1.0] + } + } +}% + + +CCProgram vs %{ + precision highp float; + + #include + #include + + in vec3 a_position; + in vec4 a_color; + out vec4 v_color; + + #if USE_TEXTURE + in vec2 a_uv0; + out vec2 v_uv0; + #endif + + void main () { + vec4 pos = vec4(a_position, 1); + + #if CC_USE_MODEL + pos = cc_matViewProj * cc_matWorld * pos; + #else + pos = cc_matViewProj * pos; + #endif + + #if USE_TEXTURE + v_uv0 = a_uv0; + #endif + + v_color = a_color; + + gl_Position = pos; + } +}% + + +CCProgram fs %{ + precision highp float; + + #include + + in vec4 v_color; + + #if USE_TEXTURE + in vec2 v_uv0; + uniform sampler2D texture; + #endif + + #if USE_OLD_PHOTO + uniform OldPhoto { + // 老化程度 + float oldLevel; + } + + /** + * 获取老化颜色 + * + * @param color 原始颜色 + * + * @return 老化后的颜色 + */ + vec4 getOldPhotoColor(vec4 color) { + float r = 0.393 * color.r + 0.769 * color.g + 0.189 * color.b; + float g = 0.349 * color.r + 0.686 * color.g + 0.168 * color.b; + float b = 0.272 * color.r + 0.534 * color.g + 0.131 * color.b; + return vec4(r, g, b, color.a); + } + #endif + + void main () { + vec4 o = vec4(1, 1, 1, 1); + + #if USE_TEXTURE + o *= texture(texture, v_uv0); + #if CC_USE_ALPHA_ATLAS_TEXTURE + o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r; + #endif + #endif + + o *= v_color; + + ALPHA_TEST(o); + + #if USE_OLD_PHOTO + vec4 srcColor = o; + vec4 oldColor = getOldPhotoColor(srcColor); + + o = srcColor + (oldColor - srcColor) * oldLevel; + #endif + gl_FragColor = o; + } +}% diff --git a/assets/effects/sprite-old-photo.effect.meta b/assets/effects/sprite-old-photo.effect.meta new file mode 100644 index 0000000..7f012f6 --- /dev/null +++ b/assets/effects/sprite-old-photo.effect.meta @@ -0,0 +1,17 @@ +{ + "ver": "1.0.23", + "uuid": "211eddf3-c53d-46e3-8c09-c1bf38e644e2", + "compiledShaders": [ + { + "glsl1": { + "vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\n\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if USE_OLD_PHOTO\nuniform float oldLevel;\n/**\n * 获取老化颜色\n * \n * @param color 原始颜色 \n *\n * @return 老化后的颜色\n */\nvec4 getOldPhotoColor(vec4 color) {\n float r = 0.393 * color.r + 0.769 * color.g + 0.189 * color.b; \n float g = 0.349 * color.r + 0.686 * color.g + 0.168 * color.b; \n float b = 0.272 * color.r + 0.534 * color.g + 0.131 * color.b;\n return vec4(r, g, b, color.a);\n}\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture2D(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n #if USE_OLD_PHOTO\n vec4 srcColor = o;\n vec4 oldColor = getOldPhotoColor(srcColor);\n\n o = srcColor + (oldColor - srcColor) * oldLevel;\n #endif\n gl_FragColor = o;\n}\n" + }, + "glsl3": { + "vert": "\nprecision highp float;\nuniform CCGlobal {\n vec4 cc_time;\n\n vec4 cc_screenSize;\n\n vec4 cc_screenScale;\n\n vec4 cc_nativeSize;\n\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n\n vec4 cc_exposure;\n\n vec4 cc_mainLitDir;\n\n vec4 cc_mainLitColor;\n\n vec4 cc_ambientSky;\n vec4 cc_ambientGround;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\n\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 a_uv0;\nout vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if USE_OLD_PHOTO\nuniform OldPhoto {\n\n float oldLevel;\n}\n\n/**\n * 获取老化颜色\n * \n * @param color 原始颜色 \n *\n * @return 老化后的颜色\n */\nvec4 getOldPhotoColor(vec4 color) {\n float r = 0.393 * color.r + 0.769 * color.g + 0.189 * color.b; \n float g = 0.349 * color.r + 0.686 * color.g + 0.168 * color.b; \n float b = 0.272 * color.r + 0.534 * color.g + 0.131 * color.b;\n return vec4(r, g, b, color.a);\n}\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n #if USE_OLD_PHOTO\n vec4 srcColor = o;\n vec4 oldColor = getOldPhotoColor(srcColor);\n\n o = srcColor + (oldColor - srcColor) * oldLevel;\n #endif\n gl_FragColor = o;\n}\n" + } + } + ], + "subMetas": {} +} \ No newline at end of file diff --git a/assets/effects/sprite-outline.effect b/assets/effects/sprite-outline.effect index 5fd3cf1..50ea566 100644 --- a/assets/effects/sprite-outline.effect +++ b/assets/effects/sprite-outline.effect @@ -1,5 +1,5 @@ // Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. - +// 描边特效 CCEffect %{ techniques: - passes: @@ -13,8 +13,24 @@ CCEffect %{ properties: texture: { value: white } alphaThreshold: { value: 0.5 } - outlineColor: { value: [1., .0, .0, 1.], editor: { type: color } } - outlineSize: { value: .01 } + + # 描边颜色 + outlineColor: { + value: [1.0, 0.0, 0.0, 1.0], + inspector: { + type: color, + tooltip: "描边颜色", + } + } + + # 描边宽度 + outlineWidth: { + value: 0.002, + inspector: { + tooltip: "描边宽度", + range: [0.0, 1.0] + } + } }% @@ -71,23 +87,23 @@ CCProgram fs %{ // 描边颜色 vec4 outlineColor; // 描边偏移大小 - float outlineSize; + float outlineWidth; // 特别地,必须是 vec4 先于 float 声明 }; - // 将图像往8个方向偏移后,得到一个类放大效果,然后取放大后的图像的透明度,即可得到一个放大后的区域,可以很方便填充(描边)颜色 - // 取当前点上、下、左、右、上左、上右、下左、下右共计8个方向,距离为 outlineSize 的8个点,求他们的透明度之和 + // 将图像往8个方向偏移后,得到一个类似放大的效果,然后取放大后的图像的透明度,即可得到一个放大后的区域,可以很方便填充(描边)颜色 + // 取当前点上、下、左、右、上左、上右、下左、下右共计8个方向,距离为 outlineWidth 的8个点,求他们的透明度之和 // 由此可以得到当前点是否属于图像往八个方向做偏移后得到的放大图区域,并且能得到该点最终透明度值 // 最终对应的为图像偏移/放大后的背景区域 float getBgAlpha() { - vec4 color_up = texture(texture, v_uv0 + vec2(0, outlineSize)); - vec4 color_down = texture(texture, v_uv0 - vec2(0, outlineSize)); - vec4 color_left = texture(texture, v_uv0 - vec2(outlineSize, 0)); - vec4 color_right = texture(texture, v_uv0 + vec2(outlineSize, 0)); - vec4 color_up_left = texture(texture, v_uv0 + vec2(outlineSize, -outlineSize)); - vec4 color_up_right = texture(texture, v_uv0 + vec2(outlineSize, outlineSize)); - vec4 color_down_left = texture(texture, v_uv0 + vec2(-outlineSize, -outlineSize)); - vec4 color_down_right = texture(texture, v_uv0 + vec2(-outlineSize, outlineSize)); + vec4 color_up = texture(texture, v_uv0 + vec2(0, outlineWidth)); + vec4 color_down = texture(texture, v_uv0 - vec2(0, outlineWidth)); + vec4 color_left = texture(texture, v_uv0 - vec2(outlineWidth, 0)); + vec4 color_right = texture(texture, v_uv0 + vec2(outlineWidth, 0)); + vec4 color_up_left = texture(texture, v_uv0 + vec2(outlineWidth, -outlineWidth)); + vec4 color_up_right = texture(texture, v_uv0 + vec2(outlineWidth, outlineWidth)); + vec4 color_down_left = texture(texture, v_uv0 + vec2(-outlineWidth, -outlineWidth)); + vec4 color_down_right = texture(texture, v_uv0 + vec2(-outlineWidth, outlineWidth)); float total = color_right.a + color_left.a + color_down.a + color_up.a + color_up_left.a + color_up_right.a + color_down_left.a + color_down_right.a; return clamp(total, 0.0, 1.0); } @@ -111,6 +127,11 @@ CCProgram fs %{ gl_FragColor = o; #if SHOW_OUT_LINE + // 无描边宽度即结束 + if (outlineWidth == 0.0) { + return; + } + // 先画背景色 vec4 color_dest = outlineColor * getBgAlpha(); diff --git a/assets/effects/sprite-outline.effect.meta b/assets/effects/sprite-outline.effect.meta index f0d2d6d..f71aaa4 100644 --- a/assets/effects/sprite-outline.effect.meta +++ b/assets/effects/sprite-outline.effect.meta @@ -5,11 +5,11 @@ { "glsl1": { "vert": "\nprecision highp float;\nuniform mat4 cc_matViewProj;\nuniform mat4 cc_matWorld;\n\nattribute vec3 a_position;\nattribute vec4 a_color;\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nattribute vec2 a_uv0;\nvarying vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", - "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if SHOW_OUT_LINE\n\nuniform vec4 outlineColor;\nuniform float outlineSize;\n\nfloat getBgAlpha() {\n vec4 color_up = texture2D(texture, v_uv0 + vec2(0, outlineSize)); \n vec4 color_down = texture2D(texture, v_uv0 - vec2(0, outlineSize)); \n vec4 color_left = texture2D(texture, v_uv0 - vec2(outlineSize, 0)); \n vec4 color_right = texture2D(texture, v_uv0 + vec2(outlineSize, 0)); \n vec4 color_up_left = texture2D(texture, v_uv0 + vec2(outlineSize, -outlineSize)); \n vec4 color_up_right = texture2D(texture, v_uv0 + vec2(outlineSize, outlineSize)); \n vec4 color_down_left = texture2D(texture, v_uv0 + vec2(-outlineSize, -outlineSize)); \n vec4 color_down_right = texture2D(texture, v_uv0 + vec2(-outlineSize, outlineSize)); \n float total = color_right.a + color_left.a + color_down.a + color_up.a + color_up_left.a + color_up_right.a + color_down_left.a + color_down_right.a; \n return clamp(total, 0.0, 1.0);\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture2D(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_OUT_LINE\n\n vec4 color_dest = outlineColor * getBgAlpha();\n\n vec4 color_src = o;\n\n gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);\n #endif\n}\n" + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform float alphaThreshold;\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nvarying vec4 v_color;\n\n#if USE_TEXTURE\nvarying vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if SHOW_OUT_LINE\n\nuniform vec4 outlineColor;\nuniform float outlineWidth;\n\nfloat getBgAlpha() {\n vec4 color_up = texture2D(texture, v_uv0 + vec2(0, outlineWidth)); \n vec4 color_down = texture2D(texture, v_uv0 - vec2(0, outlineWidth)); \n vec4 color_left = texture2D(texture, v_uv0 - vec2(outlineWidth, 0)); \n vec4 color_right = texture2D(texture, v_uv0 + vec2(outlineWidth, 0)); \n vec4 color_up_left = texture2D(texture, v_uv0 + vec2(outlineWidth, -outlineWidth)); \n vec4 color_up_right = texture2D(texture, v_uv0 + vec2(outlineWidth, outlineWidth)); \n vec4 color_down_left = texture2D(texture, v_uv0 + vec2(-outlineWidth, -outlineWidth)); \n vec4 color_down_right = texture2D(texture, v_uv0 + vec2(-outlineWidth, outlineWidth)); \n float total = color_right.a + color_left.a + color_down.a + color_up.a + color_up_left.a + color_up_right.a + color_down_left.a + color_down_right.a; \n return clamp(total, 0.0, 1.0);\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture2D(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_OUT_LINE\n\n if (outlineWidth == 0.0) {\n return;\n }\n\n vec4 color_dest = outlineColor * getBgAlpha();\n\n vec4 color_src = o;\n\n gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);\n #endif\n}\n" }, "glsl3": { "vert": "\nprecision highp float;\nuniform CCGlobal {\n vec4 cc_time;\n\n vec4 cc_screenSize;\n\n vec4 cc_screenScale;\n\n vec4 cc_nativeSize;\n\n mat4 cc_matView;\n mat4 cc_matViewInv;\n mat4 cc_matProj;\n mat4 cc_matProjInv;\n mat4 cc_matViewProj;\n mat4 cc_matViewProjInv;\n vec4 cc_cameraPos;\n\n vec4 cc_exposure;\n\n vec4 cc_mainLitDir;\n\n vec4 cc_mainLitColor;\n\n vec4 cc_ambientSky;\n vec4 cc_ambientGround;\n};\nuniform CCLocal {\n mat4 cc_matWorld;\n mat4 cc_matWorldIT;\n};\n\nin vec3 a_position;\nin vec4 a_color;\nout vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 a_uv0;\nout vec2 v_uv0;\n#endif\n\nvoid main () {\n vec4 pos = vec4(a_position, 1);\n\n #if CC_USE_MODEL\n pos = cc_matViewProj * cc_matWorld * pos;\n #else\n pos = cc_matViewProj * pos;\n #endif\n\n #if USE_TEXTURE\n v_uv0 = a_uv0;\n #endif\n\n v_color = a_color;\n\n gl_Position = pos;\n}\n", - "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if SHOW_OUT_LINE\n\nuniform Outline {\n\n vec4 outlineColor;\n\n float outlineSize;\n\n};\n\nfloat getBgAlpha() {\n vec4 color_up = texture(texture, v_uv0 + vec2(0, outlineSize)); \n vec4 color_down = texture(texture, v_uv0 - vec2(0, outlineSize)); \n vec4 color_left = texture(texture, v_uv0 - vec2(outlineSize, 0)); \n vec4 color_right = texture(texture, v_uv0 + vec2(outlineSize, 0)); \n vec4 color_up_left = texture(texture, v_uv0 + vec2(outlineSize, -outlineSize)); \n vec4 color_up_right = texture(texture, v_uv0 + vec2(outlineSize, outlineSize)); \n vec4 color_down_left = texture(texture, v_uv0 + vec2(-outlineSize, -outlineSize)); \n vec4 color_down_right = texture(texture, v_uv0 + vec2(-outlineSize, outlineSize)); \n float total = color_right.a + color_left.a + color_down.a + color_up.a + color_up_left.a + color_up_right.a + color_down_left.a + color_down_right.a; \n return clamp(total, 0.0, 1.0);\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_OUT_LINE\n\n vec4 color_dest = outlineColor * getBgAlpha();\n\n vec4 color_src = o;\n\n gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);\n #endif\n}\n" + "frag": "\nprecision highp float;\n\n#if USE_ALPHA_TEST\n \n uniform ALPHA_TEST {\n float alphaThreshold;\n }\n#endif\n\nvoid ALPHA_TEST (in vec4 color) {\n #if USE_ALPHA_TEST\n if (color.a < alphaThreshold) discard;\n #endif\n}\n\nvoid ALPHA_TEST (in float alpha) {\n #if USE_ALPHA_TEST\n if (alpha < alphaThreshold) discard;\n #endif\n}\n\nin vec4 v_color;\n\n#if USE_TEXTURE\nin vec2 v_uv0;\nuniform sampler2D texture;\n#endif\n\n#if SHOW_OUT_LINE\n\nuniform Outline {\n\n vec4 outlineColor;\n\n float outlineWidth;\n\n};\n\nfloat getBgAlpha() {\n vec4 color_up = texture(texture, v_uv0 + vec2(0, outlineWidth)); \n vec4 color_down = texture(texture, v_uv0 - vec2(0, outlineWidth)); \n vec4 color_left = texture(texture, v_uv0 - vec2(outlineWidth, 0)); \n vec4 color_right = texture(texture, v_uv0 + vec2(outlineWidth, 0)); \n vec4 color_up_left = texture(texture, v_uv0 + vec2(outlineWidth, -outlineWidth)); \n vec4 color_up_right = texture(texture, v_uv0 + vec2(outlineWidth, outlineWidth)); \n vec4 color_down_left = texture(texture, v_uv0 + vec2(-outlineWidth, -outlineWidth)); \n vec4 color_down_right = texture(texture, v_uv0 + vec2(-outlineWidth, outlineWidth)); \n float total = color_right.a + color_left.a + color_down.a + color_up.a + color_up_left.a + color_up_right.a + color_down_left.a + color_down_right.a; \n return clamp(total, 0.0, 1.0);\n}\n\n#endif\n\nvoid main () {\n vec4 o = vec4(1, 1, 1, 1);\n\n #if USE_TEXTURE\n o *= texture(texture, v_uv0);\n #if CC_USE_ALPHA_ATLAS_TEXTURE\n o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;\n #endif\n #endif\n\n o *= v_color;\n\n ALPHA_TEST(o);\n\n gl_FragColor = o;\n\n #if SHOW_OUT_LINE\n\n if (outlineWidth == 0.0) {\n return;\n }\n\n vec4 color_dest = outlineColor * getBgAlpha();\n\n vec4 color_src = o;\n\n gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);\n #endif\n}\n" } } ], diff --git a/assets/materials/sprite-example.mtl b/assets/materials/builtin-2d-sprite-explain.mtl similarity index 100% rename from assets/materials/sprite-example.mtl rename to assets/materials/builtin-2d-sprite-explain.mtl diff --git a/assets/materials/sprite-example.mtl.meta b/assets/materials/builtin-2d-sprite-explain.mtl.meta similarity index 100% rename from assets/materials/sprite-example.mtl.meta rename to assets/materials/builtin-2d-sprite-explain.mtl.meta diff --git a/assets/materials/sprite-glow-inner.mtl b/assets/materials/sprite-glow-inner.mtl new file mode 100644 index 0000000..717e6e3 --- /dev/null +++ b/assets/materials/sprite-glow-inner.mtl @@ -0,0 +1,26 @@ +{ + "__type__": "cc.Material", + "_name": "", + "_objFlags": 0, + "_native": "", + "_effectAsset": { + "__uuid__": "90211f16-c00e-4c37-a192-43ec50c9ea35" + }, + "_defines": { + "USE_TEXTURE": true, + "USE_ALPHA_TEST": false, + "SHOW_INNER_GLOW": true + }, + "_props": { + "texture": null, + "glowColor": { + "__type__": "cc.Color", + "r": 255, + "g": 0, + "b": 0, + "a": 255 + }, + "glowColorSize": 0.2, + "glowThreshold": 0.1 + } +} \ No newline at end of file diff --git a/assets/materials/sprite-glow-inner.mtl.meta b/assets/materials/sprite-glow-inner.mtl.meta new file mode 100644 index 0000000..cfcae2f --- /dev/null +++ b/assets/materials/sprite-glow-inner.mtl.meta @@ -0,0 +1,6 @@ +{ + "ver": "1.0.2", + "uuid": "2c760728-404d-4553-a1d0-7ab18263845c", + "dataAsSubAsset": null, + "subMetas": {} +} \ No newline at end of file diff --git a/assets/materials/sprite-glow-outter.mtl b/assets/materials/sprite-glow-outter.mtl new file mode 100644 index 0000000..a547d07 --- /dev/null +++ b/assets/materials/sprite-glow-outter.mtl @@ -0,0 +1,26 @@ +{ + "__type__": "cc.Material", + "_name": "", + "_objFlags": 0, + "_native": "", + "_effectAsset": { + "__uuid__": "89f30b2e-b75e-49b1-9dfc-cb341cadd30a" + }, + "_defines": { + "USE_TEXTURE": true, + "USE_ALPHA_TEST": false, + "SHOW_OUTTER_GLOW": true + }, + "_props": { + "texture": null, + "glowColor": { + "__type__": "cc.Color", + "r": 255, + "g": 0, + "b": 0, + "a": 255 + }, + "glowColorSize": 0.15, + "glowThreshold": 1 + } +} \ No newline at end of file diff --git a/assets/materials/sprite-glow-outter.mtl.meta b/assets/materials/sprite-glow-outter.mtl.meta new file mode 100644 index 0000000..fff69cd --- /dev/null +++ b/assets/materials/sprite-glow-outter.mtl.meta @@ -0,0 +1,6 @@ +{ + "ver": "1.0.2", + "uuid": "16dd0f06-6280-4d74-8483-a50e23c00733", + "dataAsSubAsset": null, + "subMetas": {} +} \ No newline at end of file diff --git a/assets/materials/sprite-mosaic.mtl b/assets/materials/sprite-mosaic.mtl new file mode 100644 index 0000000..08d93ec --- /dev/null +++ b/assets/materials/sprite-mosaic.mtl @@ -0,0 +1,17 @@ +{ + "__type__": "cc.Material", + "_name": "", + "_objFlags": 0, + "_native": "", + "_effectAsset": { + "__uuid__": "9638979d-62b3-4e5b-adea-7ad706e66e65" + }, + "_defines": { + "USE_TEXTURE": true, + "USE_MOSAIC": true + }, + "_props": { + "xBlockCount": 50, + "yBlockCount": 50 + } +} \ No newline at end of file diff --git a/assets/materials/sprite-mosaic.mtl.meta b/assets/materials/sprite-mosaic.mtl.meta new file mode 100644 index 0000000..9c1c661 --- /dev/null +++ b/assets/materials/sprite-mosaic.mtl.meta @@ -0,0 +1,6 @@ +{ + "ver": "1.0.2", + "uuid": "f2651803-80c3-4665-bd81-2ad946a12dec", + "dataAsSubAsset": null, + "subMetas": {} +} \ No newline at end of file diff --git a/assets/materials/sprite-old-photo.mtl b/assets/materials/sprite-old-photo.mtl new file mode 100644 index 0000000..5ee6bac --- /dev/null +++ b/assets/materials/sprite-old-photo.mtl @@ -0,0 +1,14 @@ +{ + "__type__": "cc.Material", + "_name": "", + "_objFlags": 0, + "_native": "", + "_effectAsset": { + "__uuid__": "211eddf3-c53d-46e3-8c09-c1bf38e644e2" + }, + "_defines": { + "USE_TEXTURE": true, + "USE_OLD_PHOTO": true + }, + "_props": {} +} \ No newline at end of file diff --git a/assets/materials/sprite-old-photo.mtl.meta b/assets/materials/sprite-old-photo.mtl.meta new file mode 100644 index 0000000..84e4c7f --- /dev/null +++ b/assets/materials/sprite-old-photo.mtl.meta @@ -0,0 +1,6 @@ +{ + "ver": "1.0.2", + "uuid": "268b1aff-299a-4735-9f5c-5aa8d4d51788", + "dataAsSubAsset": null, + "subMetas": {} +} \ No newline at end of file diff --git a/assets/materials/sprite-outline.mtl b/assets/materials/sprite-outline.mtl index 66141cf..73debb1 100644 --- a/assets/materials/sprite-outline.mtl +++ b/assets/materials/sprite-outline.mtl @@ -14,12 +14,12 @@ "_props": { "texture": null, "outlineColor": { - "__type__": "cc.Vec4", - "x": 1, - "y": 0, - "z": 0, - "w": 1 + "__type__": "cc.Color", + "r": 255, + "g": 0, + "b": 0, + "a": 255 }, - "outlineSize": 0.01 + "outlineWidth": 0.002 } } \ No newline at end of file diff --git a/assets/scenes/GlowInnerEffectScene.fire b/assets/scenes/GlowInnerEffectScene.fire new file mode 100755 index 0000000..4eb44b5 --- /dev/null +++ b/assets/scenes/GlowInnerEffectScene.fire @@ -0,0 +1,5882 @@ +[ + { + "__type__": "cc.SceneAsset", + "_name": "", + "_objFlags": 0, + "_native": "", + "scene": { + "__id__": 1 + } + }, + { + "__type__": "cc.Scene", + "_objFlags": 0, + "_parent": null, + "_children": [ + { + "__id__": 2 + } + ], + "_active": false, + "_components": [], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 0, + "height": 0 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_is3DNode": true, + "_groupIndex": 0, + "groupIndex": 0, + "autoReleaseAssets": false, + "_id": "69a920f1-0509-4d54-b033-5fb5b1283b72" + }, + { + "__type__": "cc.Node", + "_name": "Canvas", + "_objFlags": 0, + "_parent": { + "__id__": 1 + }, + "_children": [ + { + "__id__": 3 + }, + { + "__id__": 5 + } + ], + "_active": true, + "_components": [ + { + "__id__": 130 + }, + { + "__id__": 131 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 252, + "g": 252, + "b": 252, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 960, + "height": 640 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 480, + 320, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "a286bbGknJLZpRpxROV6M94" + }, + { + "__type__": "cc.Node", + "_name": "Main Camera", + "_objFlags": 0, + "_parent": { + "__id__": 2 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 4 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 0, + "height": 0 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 492.17758360225525, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "fbL5wf1mhFa6PPZbeZvnZ9" + }, + { + "__type__": "cc.Camera", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 3 + }, + "_enabled": true, + "_cullingMask": 4294967295, + "_clearFlags": 7, + "_backgroundColor": { + "__type__": "cc.Color", + "r": 0, + "g": 0, + "b": 0, + "a": 255 + }, + "_depth": -1, + "_zoomRatio": 1, + "_targetTexture": null, + "_fov": 60, + "_orthoSize": 10, + "_nearClip": 1, + "_farClip": 4096, + "_ortho": true, + "_rect": { + "__type__": "cc.Rect", + "x": 0, + "y": 0, + "width": 1, + "height": 1 + }, + "_renderStages": 1, + "_alignWithScreen": true, + "_id": "adItdqNzZHbYUhDAmfCr9b" + }, + { + "__type__": "cc.Node", + "_name": "Content", + "_objFlags": 0, + "_parent": { + "__id__": 2 + }, + "_children": [ + { + "__id__": 6 + }, + { + "__id__": 9 + }, + { + "__id__": 114 + } + ], + "_active": true, + "_components": [ + { + "__id__": 129 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 960, + "height": 640 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "faqYlnbttBCaJJgkn4Ntv/" + }, + { + "__type__": "cc.Node", + "_name": "Bg", + "_objFlags": 0, + "_parent": { + "__id__": 5 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 7 + }, + { + "__id__": 8 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 27, + "g": 38, + "b": 46, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 960, + "height": 640 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "e2e0crkOLxGrpMxpbC4iQg1" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 6 + }, + "_enabled": true, + "alignMode": 0, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 200, + "_originalHeight": 150, + "_id": "89IA6P0/5JEZERosKJJo6k" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 6 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "410fb916-8721-4663-bab8-34397391ace7" + }, + "_type": 1, + "_sizeMode": 0, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "2azjUbJNxALLAfDZrJ8TV0" + }, + { + "__type__": "cc.Node", + "_name": "Sliders", + "_objFlags": 0, + "_parent": { + "__id__": 5 + }, + "_children": [ + { + "__id__": 10 + }, + { + "__id__": 27 + }, + { + "__id__": 44 + }, + { + "__id__": 61 + }, + { + "__id__": 78 + }, + { + "__id__": 95 + } + ], + "_active": true, + "_components": [ + { + "__id__": 112 + }, + { + "__id__": 113 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 576, + "height": 460 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 1 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -192, + 320, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "d0PWmVX95D3LEcvBQBPDr+" + }, + { + "__type__": "cc.Node", + "_name": "ColorRedSlider", + "_objFlags": 0, + "_parent": { + "__id__": 9 + }, + "_children": [ + { + "__id__": 11 + }, + { + "__id__": 14 + }, + { + "__id__": 23 + } + ], + "_active": true, + "_components": [ + { + "__id__": 26 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 576, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + -30, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "75CtG/r79FIrGBRQBxUnMM" + }, + { + "__type__": "cc.Node", + "_name": "SliderDescLabel", + "_objFlags": 0, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 12 + }, + { + "__id__": 13 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -144, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "ed/vvuTO9EG6+WRy0En/W6" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 11 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_useOriginalSize": false, + "_string": "Red:", + "_N$string": "Red:", + "_fontSize": 40, + "_lineHeight": 40, + "_enableWrapText": true, + "_N$file": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_batchAsBitmap": false, + "_N$horizontalAlign": 2, + "_N$verticalAlign": 1, + "_N$fontFamily": "Arial", + "_N$overflow": 2, + "_N$cacheMode": 0, + "_id": "f7z02UrAJASZQYcxrcMJGt" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 11 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0.75, + "_top": 10, + "_bottom": 10, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": false, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 113.38, + "_originalHeight": 50.4, + "_id": "afzIZOHWBJA5+woZcJ2gwz" + }, + { + "__type__": "cc.Node", + "_name": "Slider", + "_objFlags": 0, + "_parent": { + "__id__": 10 + }, + "_children": [ + { + "__id__": 15 + }, + { + "__id__": 18 + } + ], + "_active": true, + "_components": [ + { + "__id__": 21 + }, + { + "__id__": 22 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 230.40000000000003, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -115.20000000000002, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "3dthetNVJOj7zluUpaljKC" + }, + { + "__type__": "cc.Node", + "_name": "Background", + "_objFlags": 0, + "_parent": { + "__id__": 14 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 16 + }, + { + "__id__": 17 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 230.40000000000003, + "height": 20 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "e39OJTLUlNJrje+eGwfquO" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 15 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "31d8962d-babb-4ec7-be19-8e9f54a4ea99" + }, + "_type": 1, + "_sizeMode": 0, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "15IILtSZRG5ouBCP+OBsoy" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 15 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0, + "_top": 20, + "_bottom": 20, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 20, + "_id": "05mU6YJy1EVoBT5Yq2Og8A" + }, + { + "__type__": "cc.Node", + "_name": "Handle", + "_objFlags": 0, + "_parent": { + "__id__": 14 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 19 + }, + { + "__id__": 20 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 32, + "height": 32 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 230.40000000000006, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "7bSyqIqN5AGpV7Q1H8UELD" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 18 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_type": 1, + "_sizeMode": 2, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "bdsXS3PtFPiK59vgFohUUn" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 18 + }, + "_enabled": true, + "_normalMaterial": null, + "_grayMaterial": null, + "duration": 0.1, + "zoomScale": 1.1, + "clickEvents": [], + "_N$interactable": true, + "_N$enableAutoGrayEffect": true, + "_N$transition": 3, + "transition": 3, + "_N$normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$hoverColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "hoverColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$disabledColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$normalSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$pressedSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "pressedSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$hoverSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "hoverSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$disabledSprite": { + "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" + }, + "_N$target": { + "__id__": 18 + }, + "_id": "9c/4Y0juRIZpOZZ7lyVI/u" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 14 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0.3, + "_right": 0.3, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": false, + "_isAbsRight": false, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 20, + "_id": "3dNMNnhp5CmaAbSbLqK54L" + }, + { + "__type__": "cc.Slider", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 14 + }, + "_enabled": true, + "direction": 0, + "slideEvents": [], + "_N$handle": { + "__id__": 20 + }, + "_N$progress": 1, + "_id": "16lk7dFbdHP4Lm1acPXErH" + }, + { + "__type__": "cc.Node", + "_name": "ValueLabel", + "_objFlags": 0, + "_parent": { + "__id__": 10 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 24 + }, + { + "__id__": 25 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 288, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "eeKVye8E5Cxbh+AWJEDLUf" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 23 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0.75, + "_right": 0, + "_top": 10, + "_bottom": 10, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": false, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 113.38, + "_originalHeight": 50.4, + "_id": "3d4moMMihBmLirK/X6nrNt" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 23 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_useOriginalSize": false, + "_string": "0.10 | 26", + "_N$string": "0.10 | 26", + "_fontSize": 40, + "_lineHeight": 40, + "_enableWrapText": true, + "_N$file": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_batchAsBitmap": false, + "_N$horizontalAlign": 0, + "_N$verticalAlign": 1, + "_N$fontFamily": "Arial", + "_N$overflow": 2, + "_N$cacheMode": 0, + "_id": "a5/IYKgkVBIprxaeuKTge+" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 10 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 40, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 461.38, + "_originalHeight": 0, + "_id": "afxGrMSLlInYj8+7gvzYaz" + }, + { + "__type__": "cc.Node", + "_name": "ColorGreenSlider", + "_objFlags": 0, + "_parent": { + "__id__": 9 + }, + "_children": [ + { + "__id__": 28 + }, + { + "__id__": 31 + }, + { + "__id__": 40 + } + ], + "_active": true, + "_components": [ + { + "__id__": 43 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 576, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + -110, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "326+Vf4/VCI4n/eb7ABmQ2" + }, + { + "__type__": "cc.Node", + "_name": "SliderDescLabel", + "_objFlags": 0, + "_parent": { + "__id__": 27 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 29 + }, + { + "__id__": 30 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -144, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "dc89G2vIVF261JRkYLWpr+" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 28 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_useOriginalSize": false, + "_string": "Green:", + "_N$string": "Green:", + "_fontSize": 40, + "_lineHeight": 40, + "_enableWrapText": true, + "_N$file": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_batchAsBitmap": false, + "_N$horizontalAlign": 2, + "_N$verticalAlign": 1, + "_N$fontFamily": "Arial", + "_N$overflow": 2, + "_N$cacheMode": 0, + "_id": "edj1Qt2bRFE7sqqv3+k9FR" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 28 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0.75, + "_top": 10, + "_bottom": 10, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": false, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 113.38, + "_originalHeight": 50.4, + "_id": "7b9qe0965Dk5xcg7/fw7Xw" + }, + { + "__type__": "cc.Node", + "_name": "Slider", + "_objFlags": 0, + "_parent": { + "__id__": 27 + }, + "_children": [ + { + "__id__": 32 + }, + { + "__id__": 35 + } + ], + "_active": true, + "_components": [ + { + "__id__": 38 + }, + { + "__id__": 39 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 230.40000000000003, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -115.20000000000002, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "b8VzriQJBAgogzmF5f14zV" + }, + { + "__type__": "cc.Node", + "_name": "Background", + "_objFlags": 0, + "_parent": { + "__id__": 31 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 33 + }, + { + "__id__": 34 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 230.40000000000003, + "height": 20 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "cewXFktFJEOJyZ0cfyjt9k" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 32 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "31d8962d-babb-4ec7-be19-8e9f54a4ea99" + }, + "_type": 1, + "_sizeMode": 0, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "1fqds7RW1Bj7n7IKuEYru7" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 32 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0, + "_top": 20, + "_bottom": 20, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 20, + "_id": "5f7aWhkBhLZKSH7nysQnZD" + }, + { + "__type__": "cc.Node", + "_name": "Handle", + "_objFlags": 0, + "_parent": { + "__id__": 31 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 36 + }, + { + "__id__": 37 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 32, + "height": 32 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "01xShpu7JJZJ16s+zzr3za" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 35 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_type": 1, + "_sizeMode": 2, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "f4Bovma6JGk7fv5agt9xfx" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 35 + }, + "_enabled": true, + "_normalMaterial": null, + "_grayMaterial": null, + "duration": 0.1, + "zoomScale": 1.1, + "clickEvents": [], + "_N$interactable": true, + "_N$enableAutoGrayEffect": true, + "_N$transition": 3, + "transition": 3, + "_N$normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$hoverColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "hoverColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$disabledColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$normalSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$pressedSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "pressedSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$hoverSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "hoverSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$disabledSprite": { + "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" + }, + "_N$target": { + "__id__": 35 + }, + "_id": "57cFuTtK1CAJ/hN9ewxzJY" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 31 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0.3, + "_right": 0.3, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": false, + "_isAbsRight": false, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 20, + "_id": "b33mmA5spJPr8++4P0Y/JP" + }, + { + "__type__": "cc.Slider", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 31 + }, + "_enabled": true, + "direction": 0, + "slideEvents": [], + "_N$handle": { + "__id__": 37 + }, + "_N$progress": 0, + "_id": "7ff0bXreRC05d9kAI/PAgA" + }, + { + "__type__": "cc.Node", + "_name": "ValueLabel", + "_objFlags": 0, + "_parent": { + "__id__": 27 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 41 + }, + { + "__id__": 42 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 288, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "9fwmi2UehO8p4XCB8ewlDL" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 40 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0.75, + "_right": 0, + "_top": 10, + "_bottom": 10, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": false, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 113.38, + "_originalHeight": 50.4, + "_id": "d8Cn7rGylPq4jjxFO9vdyX" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 40 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_useOriginalSize": false, + "_string": "0.10 | 26", + "_N$string": "0.10 | 26", + "_fontSize": 40, + "_lineHeight": 40, + "_enableWrapText": true, + "_N$file": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_batchAsBitmap": false, + "_N$horizontalAlign": 0, + "_N$verticalAlign": 1, + "_N$fontFamily": "Arial", + "_N$overflow": 2, + "_N$cacheMode": 0, + "_id": "e5rEyKV1VD/772YXNMSIAI" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 27 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 40, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 461.38, + "_originalHeight": 0, + "_id": "eai759mRVFGq2yx9v5QsUO" + }, + { + "__type__": "cc.Node", + "_name": "ColorBlueSlider", + "_objFlags": 0, + "_parent": { + "__id__": 9 + }, + "_children": [ + { + "__id__": 45 + }, + { + "__id__": 48 + }, + { + "__id__": 57 + } + ], + "_active": true, + "_components": [ + { + "__id__": 60 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 576, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + -190, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "77H3WJNzBFloSV/XcgYZ2h" + }, + { + "__type__": "cc.Node", + "_name": "SliderDescLabel", + "_objFlags": 0, + "_parent": { + "__id__": 44 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 46 + }, + { + "__id__": 47 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -144, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "c0mBRAF2RIYYAajo4eLQst" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 45 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_useOriginalSize": false, + "_string": "Blue:", + "_N$string": "Blue:", + "_fontSize": 40, + "_lineHeight": 40, + "_enableWrapText": true, + "_N$file": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_batchAsBitmap": false, + "_N$horizontalAlign": 2, + "_N$verticalAlign": 1, + "_N$fontFamily": "Arial", + "_N$overflow": 2, + "_N$cacheMode": 0, + "_id": "53G6DkWFdC24UTbk1INEnG" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 45 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0.75, + "_top": 10, + "_bottom": 10, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": false, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 113.38, + "_originalHeight": 50.4, + "_id": "ddGu+jkxhHnYaYVA5gg2QT" + }, + { + "__type__": "cc.Node", + "_name": "Slider", + "_objFlags": 0, + "_parent": { + "__id__": 44 + }, + "_children": [ + { + "__id__": 49 + }, + { + "__id__": 52 + } + ], + "_active": true, + "_components": [ + { + "__id__": 55 + }, + { + "__id__": 56 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 230.40000000000003, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -115.20000000000002, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "89knithiNNobnClrWw7OBf" + }, + { + "__type__": "cc.Node", + "_name": "Background", + "_objFlags": 0, + "_parent": { + "__id__": 48 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 50 + }, + { + "__id__": 51 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 230.40000000000003, + "height": 20 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "c6KPPPQQxKrJ5WlwYEtWgW" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 49 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "31d8962d-babb-4ec7-be19-8e9f54a4ea99" + }, + "_type": 1, + "_sizeMode": 0, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "catFOSdOtKvqBJU6NyZptL" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 49 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0, + "_right": 0, + "_top": 20, + "_bottom": 20, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 20, + "_id": "3fQjTIRnZO/KOLdzMb0GLz" + }, + { + "__type__": "cc.Node", + "_name": "Handle", + "_objFlags": 0, + "_parent": { + "__id__": 48 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 53 + }, + { + "__id__": 54 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 32, + "height": 32 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "05Lw5+ju5Km6CUuZHE0KIJ" + }, + { + "__type__": "cc.Sprite", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 52 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_srcBlendFactor": 770, + "_dstBlendFactor": 771, + "_spriteFrame": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_type": 1, + "_sizeMode": 2, + "_fillType": 0, + "_fillCenter": { + "__type__": "cc.Vec2", + "x": 0, + "y": 0 + }, + "_fillStart": 0, + "_fillRange": 0, + "_isTrimmedMode": true, + "_atlas": null, + "_id": "59km8OsEFBYKJBL8uemNsI" + }, + { + "__type__": "cc.Button", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 52 + }, + "_enabled": true, + "_normalMaterial": null, + "_grayMaterial": null, + "duration": 0.1, + "zoomScale": 1.1, + "clickEvents": [], + "_N$interactable": true, + "_N$enableAutoGrayEffect": true, + "_N$transition": 3, + "transition": 3, + "_N$normalColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "pressedColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$hoverColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "hoverColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$disabledColor": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_N$normalSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$pressedSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "pressedSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$hoverSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "hoverSprite": { + "__uuid__": "e7aba14b-f956-4480-b254-8d57832e273f" + }, + "_N$disabledSprite": { + "__uuid__": "29158224-f8dd-4661-a796-1ffab537140e" + }, + "_N$target": { + "__id__": 52 + }, + "_id": "60hGQyHlpFo5tBoUoSMlr0" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 48 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0.3, + "_right": 0.3, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": false, + "_isAbsRight": false, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 300, + "_originalHeight": 20, + "_id": "d59WBBmtNFop4L7e3muEqI" + }, + { + "__type__": "cc.Slider", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 48 + }, + "_enabled": true, + "direction": 0, + "slideEvents": [], + "_N$handle": { + "__id__": 54 + }, + "_N$progress": 0, + "_id": "85Bj14/jlEqJFygmdTXhhP" + }, + { + "__type__": "cc.Node", + "_name": "ValueLabel", + "_objFlags": 0, + "_parent": { + "__id__": 44 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 58 + }, + { + "__id__": 59 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 288, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "4clGFOBU5C1KS9BNZ3PBJO" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 57 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 45, + "_left": 0.75, + "_right": 0, + "_top": 10, + "_bottom": 10, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": false, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 113.38, + "_originalHeight": 50.4, + "_id": "67Bcp4s0ZFV4smaHkvs2PR" + }, + { + "__type__": "cc.Label", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 57 + }, + "_enabled": true, + "_materials": [ + { + "__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432" + } + ], + "_useOriginalSize": false, + "_string": "0.10 | 26", + "_N$string": "0.10 | 26", + "_fontSize": 40, + "_lineHeight": 40, + "_enableWrapText": true, + "_N$file": null, + "_isSystemFontUsed": true, + "_spacingX": 0, + "_batchAsBitmap": false, + "_N$horizontalAlign": 0, + "_N$verticalAlign": 1, + "_N$fontFamily": "Arial", + "_N$overflow": 2, + "_N$cacheMode": 0, + "_id": "b7jxERzvFB7aeQfSMt4bGk" + }, + { + "__type__": "cc.Widget", + "_name": "", + "_objFlags": 0, + "node": { + "__id__": 44 + }, + "_enabled": true, + "alignMode": 1, + "_target": null, + "_alignFlags": 40, + "_left": 0, + "_right": 0, + "_top": 0, + "_bottom": 0, + "_verticalCenter": 0, + "_horizontalCenter": 0, + "_isAbsLeft": true, + "_isAbsRight": true, + "_isAbsTop": true, + "_isAbsBottom": true, + "_isAbsHorizontalCenter": true, + "_isAbsVerticalCenter": true, + "_originalWidth": 461.38, + "_originalHeight": 0, + "_id": "e6kFzW7M1LRoUqbVaPBizj" + }, + { + "__type__": "cc.Node", + "_name": "ColorAlphaSlider", + "_objFlags": 0, + "_parent": { + "__id__": 9 + }, + "_children": [ + { + "__id__": 62 + }, + { + "__id__": 65 + }, + { + "__id__": 74 + } + ], + "_active": true, + "_components": [ + { + "__id__": 77 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 576, + "height": 60 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.5, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + 0, + -270, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "78ay9VkEVGU67Iinzm3rCq" + }, + { + "__type__": "cc.Node", + "_name": "SliderDescLabel", + "_objFlags": 0, + "_parent": { + "__id__": 61 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 63 + }, + { + "__id__": 64 + } + ], + "_prefab": null, + "_opacity": 255, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 144, + "height": 40 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 1, + "y": 0.5 + }, + "_trs": { + "__type__": "TypedArray", + "ctor": "Float64Array", + "array": [ + -144, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1 + ] + }, + "_eulerAngles": { + "__type__": "cc.Vec3", + "x": 0, + "y": 0, + "z": 0 + }, + "_skewX": 0, + "_skewY": 0, + "_is3DNode": false, + "_groupIndex": 0, + "groupIndex": 0, + "_id": "b0Am40rDhKiLU6um45ktt+" + }, + { + "__type__": "cc.Label", + "_name": "SliderDescLabel