Merge branch 'release/0.3.0'
This commit is contained in:
commit
079c16a2e5
@ -1,5 +1,9 @@
|
||||
# ChangeLog
|
||||
|
||||
## 0.3.0 (2020-01-09)
|
||||
|
||||
- 加入圆角裁剪特效
|
||||
|
||||
## 0.2.0 (2020-01-05)
|
||||
|
||||
- 加入灰度渐变特效
|
||||
|
11
README.md
11
README.md
@ -1,6 +1,6 @@
|
||||
# Cocos Creator Shader Effect Demo
|
||||
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
[](LICENSE)
|
||||
[](http://www.cocos.com/creator)
|
||||
|
||||
@ -43,6 +43,15 @@
|
||||
|
||||

|
||||
|
||||
### 圆角裁剪
|
||||
|
||||
> * 声明:此特效为搬运过来的特效,非原创。
|
||||
> * 修改的地方:搬运后,在原来的主要代码上加入了自己的理解注释
|
||||
> * 实现原理:参考文章 [《圆角计算 Shader》](https://www.cnblogs.com/jqm304775992/p/4987793.html)
|
||||
> * 参考代码:Cocos 论坛帖子[《分享更高效的 creator 裁圆角头像 shader》](https://forum.cocos.org/t/creator-shader-2019-10-22-2-2-0/82548) 和对应的 [实现代码](https://github.com/yanjifa/shaderDemo/blob/master/assets/Effect/CircleAvatar.effect)
|
||||
|
||||

|
||||
|
||||
### 外发光(完善中...)
|
||||
|
||||
### 外描边(完善中...)
|
||||
|
144
assets/effects/sprite-round-corner-crop.effect
Normal file
144
assets/effects/sprite-round-corner-crop.effect
Normal file
@ -0,0 +1,144 @@
|
||||
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
// 圆角裁剪
|
||||
// 原理:https://www.cnblogs.com/jqm304775992/p/4987793.html
|
||||
// 代码:复制 yanjifa/shaderDemor 的 https://github.com/yanjifa/shaderDemo/blob/master/assets/Effect/CircleAvatar.effect
|
||||
|
||||
CCEffect %{
|
||||
techniques:
|
||||
- passes:
|
||||
- vert: vs
|
||||
frag: fs
|
||||
blendState:
|
||||
targets:
|
||||
- blend: true
|
||||
rasterizerState:
|
||||
cullMode: none
|
||||
properties:
|
||||
texture: { value: white }
|
||||
alphaThreshold: { value: 0.5 }
|
||||
# 圆角半径
|
||||
roundCornerRadius: {
|
||||
value: 0.1,
|
||||
inspector: {
|
||||
tooltip: "圆角半径",
|
||||
range: [0.0, 0.5]
|
||||
}
|
||||
}
|
||||
}%
|
||||
|
||||
|
||||
CCProgram vs %{
|
||||
precision highp float;
|
||||
|
||||
#include <cc-global>
|
||||
#include <cc-local>
|
||||
|
||||
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 <alpha-test>
|
||||
|
||||
in vec4 v_color;
|
||||
|
||||
#if USE_TEXTURE
|
||||
in vec2 v_uv0;
|
||||
uniform sampler2D texture;
|
||||
#endif
|
||||
|
||||
#if ENABLE_ROUNDCORNER
|
||||
uniform RoundCorner {
|
||||
// 圆角半径
|
||||
float roundCornerRadius;
|
||||
}
|
||||
#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 ENABLE_ROUNDCORNER
|
||||
// 约束圆角半径范围在 [0.0, 0.5]
|
||||
float radius = clamp(0.0, 0.5, roundCornerRadius);
|
||||
|
||||
// 将纹理uv往左下偏移,实现偏移后的纹理中心点在 OpenGL 坐标系的原点
|
||||
vec2 uv = v_uv0.xy - vec2(0.5, 0.5);
|
||||
|
||||
// uv.x , uv.y : 为偏移后的的uv
|
||||
// abs(uv.x) , abs(uv.y) : 将第二、三、四象限的点都投影到第一象限上,这样子只需要处理第一象限的情况就可以,简化判断
|
||||
// 0.5 - radius : 计算出第一象限的圆角所在圆的圆心坐标
|
||||
// (rx, ry) : 偏移映射后的 新的uv 坐标,相对于 第一象限圆角坐在圆心坐标 的相对坐标
|
||||
float rx = abs(uv.x) - (0.5 - radius);
|
||||
float ry = abs(uv.y) - (0.5 - radius);
|
||||
|
||||
// 区分 以第一象限圆角所在圆心坐标为原点的坐标的四个象限
|
||||
//
|
||||
// 第一象限 mx = 1, my = 1
|
||||
// 第二象限 mx = 0, my = 1
|
||||
// 第三象限 mx = 0, my = 0
|
||||
// 第四象限 mx = 1, my = 0
|
||||
//
|
||||
// 当 mx * my 时,只要等于1,那就是标识第一象限(实际对应圆角区域所在矩形),否则就是第二、三、四象限
|
||||
float mx = step(0.5 - radius, abs(uv.x));
|
||||
float my = step(0.5 - radius, abs(uv.y));
|
||||
|
||||
// 计算相对uv坐标到圆心的距离
|
||||
float len = length(vec2(rx, ry));
|
||||
|
||||
// mx * my = 0 时,代表非圆角区域,a 值为1,代表完全采用原始纹理的透明度
|
||||
// mx * my = 1 时,代表园所所在矩形区域
|
||||
// step(radius, len) 可以区分出圆角所在矩形区域的 圆角区域 和 非圆角区域
|
||||
// 其中圆角区域值为0,非圆角区域值为1
|
||||
// 当为圆角区域时,a 值为1,代表完全采用原始纹理透明度
|
||||
// 当为非圆角区域时,a 值为0,代表完全透明
|
||||
// 至此已经实现圆角裁剪
|
||||
//
|
||||
// smoothstep(0., radius * 0.01, len - radius) 是用于抗锯齿优化
|
||||
// 原理:针对点在非圆角区域的情况,针对点在大于「圆半径一点点」地方的区域,进行平滑过渡,以实现抗锯齿
|
||||
// 其中,
|
||||
// 「圆半径一点点」用 radius * 0.01 表示(0.01 可自行改变)
|
||||
// 点在大于圆半径的区域用 len - radius ,此值会在 [0.0, radius * 0.01] 之间时会平滑过渡
|
||||
float a = 1.0 - mx * my * step(radius, len) * smoothstep(0., radius * 0.01, len - radius);
|
||||
o = vec4(o.rgb, o.a * a);
|
||||
#endif
|
||||
gl_FragColor = o;
|
||||
}
|
||||
}%
|
17
assets/effects/sprite-round-corner-crop.effect.meta
Normal file
17
assets/effects/sprite-round-corner-crop.effect.meta
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"ver": "1.0.23",
|
||||
"uuid": "a4afedba-5234-44d7-9031-cba83051d521",
|
||||
"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 ENABLE_ROUNDCORNER\nuniform float roundCornerRadius;\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 ENABLE_ROUNDCORNER\n\n float radius = clamp(0.0, 0.5, roundCornerRadius);\n\n vec2 uv = v_uv0.xy - vec2(0.5, 0.5);\n\n float rx = abs(uv.x) - (0.5 - radius);\n float ry = abs(uv.y) - (0.5 - radius);\n\n float mx = step(0.5 - radius, abs(uv.x));\n float my = step(0.5 - radius, abs(uv.y));\n\n float len = length(vec2(rx, ry));\n\n float a = 1.0 - mx * my * step(radius, len) * smoothstep(0., radius * 0.01, len - radius);\n o = vec4(o.rgb, o.a * a);\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 ENABLE_ROUNDCORNER\nuniform RoundCorner {\n\n float roundCornerRadius;\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 ENABLE_ROUNDCORNER\n\n float radius = clamp(0.0, 0.5, roundCornerRadius);\n\n vec2 uv = v_uv0.xy - vec2(0.5, 0.5);\n\n float rx = abs(uv.x) - (0.5 - radius);\n float ry = abs(uv.y) - (0.5 - radius);\n\n float mx = step(0.5 - radius, abs(uv.x));\n float my = step(0.5 - radius, abs(uv.y));\n\n float len = length(vec2(rx, ry));\n\n float a = 1.0 - mx * my * step(radius, len) * smoothstep(0., radius * 0.01, len - radius);\n o = vec4(o.rgb, o.a * a);\n #endif\n gl_FragColor = o;\n}\n"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subMetas": {}
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
"USE_MOSAIC": true
|
||||
},
|
||||
"_props": {
|
||||
"xBlockCount": 50,
|
||||
"yBlockCount": 50
|
||||
"xBlockCount": 40,
|
||||
"yBlockCount": 40
|
||||
}
|
||||
}
|
16
assets/materials/sprite-round-corner-crop.mtl
Normal file
16
assets/materials/sprite-round-corner-crop.mtl
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"__type__": "cc.Material",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"_native": "",
|
||||
"_effectAsset": {
|
||||
"__uuid__": "a4afedba-5234-44d7-9031-cba83051d521"
|
||||
},
|
||||
"_defines": {
|
||||
"USE_TEXTURE": true,
|
||||
"ENABLE_ROUNDCORNER": true
|
||||
},
|
||||
"_props": {
|
||||
"roundCornerRadius": 0.1
|
||||
}
|
||||
}
|
6
assets/materials/sprite-round-corner-crop.mtl.meta
Normal file
6
assets/materials/sprite-round-corner-crop.mtl.meta
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"ver": "1.0.2",
|
||||
"uuid": "642c2d0e-7eb6-4d65-96f2-d6e0d0305310",
|
||||
"dataAsSubAsset": null,
|
||||
"subMetas": {}
|
||||
}
|
2692
assets/scenes/PreviewEffectScene.fire
Executable file
2692
assets/scenes/PreviewEffectScene.fire
Executable file
File diff suppressed because it is too large
Load Diff
7
assets/scenes/PreviewEffectScene.fire.meta
Normal file
7
assets/scenes/PreviewEffectScene.fire.meta
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"ver": "1.2.5",
|
||||
"uuid": "3bf0537b-ca38-4d1d-9c51-4e6c8a6369b0",
|
||||
"asyncLoadAssets": false,
|
||||
"autoReleaseAssets": false,
|
||||
"subMetas": {}
|
||||
}
|
2159
assets/scenes/RoundCornerCropEffectScene.fire
Executable file
2159
assets/scenes/RoundCornerCropEffectScene.fire
Executable file
File diff suppressed because it is too large
Load Diff
7
assets/scenes/RoundCornerCropEffectScene.fire.meta
Normal file
7
assets/scenes/RoundCornerCropEffectScene.fire.meta
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"ver": "1.2.5",
|
||||
"uuid": "6c351889-b6c8-409f-b36c-4263b06d0b23",
|
||||
"asyncLoadAssets": false,
|
||||
"autoReleaseAssets": false,
|
||||
"subMetas": {}
|
||||
}
|
9
assets/scripts/PreviewEffectScene.ts
Normal file
9
assets/scripts/PreviewEffectScene.ts
Normal file
@ -0,0 +1,9 @@
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
@ccclass
|
||||
export default class PreviewEffectScene extends cc.Component {
|
||||
onLoad() {
|
||||
// 关闭动态合图
|
||||
cc.dynamicAtlasManager.enabled = false;
|
||||
}
|
||||
}
|
9
assets/scripts/PreviewEffectScene.ts.meta
Normal file
9
assets/scripts/PreviewEffectScene.ts.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "7d1a13dd-0ba0-4812-b685-31d59a70ecef",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
62
assets/scripts/RoundCornerCropEffectScene.ts
Normal file
62
assets/scripts/RoundCornerCropEffectScene.ts
Normal file
@ -0,0 +1,62 @@
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
@ccclass
|
||||
export default class RoundCornerCropEffectScene extends cc.Component {
|
||||
private _roundCornerRadiuSlider: cc.Slider = null;
|
||||
private _roundCornerRadiuLabel: cc.Label = null;
|
||||
|
||||
private _examplesParentNode: cc.Node = null;
|
||||
|
||||
onLoad() {
|
||||
// 关闭动态合图
|
||||
cc.dynamicAtlasManager.enabled = false;
|
||||
|
||||
this._roundCornerRadiuSlider = cc.find("Canvas/Content/Sliders/RoundCornerRadiusSlider/Slider").getComponent(cc.Slider);
|
||||
this._roundCornerRadiuLabel = cc.find("Canvas/Content/Sliders/RoundCornerRadiusSlider/ValueLabel").getComponent(cc.Label);
|
||||
|
||||
this._examplesParentNode = cc.find("Canvas/Content/Examples");
|
||||
}
|
||||
|
||||
onEnable() {
|
||||
this._roundCornerRadiuSlider.node.on("slide", this._onSliderChanged, this);
|
||||
}
|
||||
|
||||
onDisable() {
|
||||
this._roundCornerRadiuSlider.node.off("slide", this._onSliderChanged, this);
|
||||
}
|
||||
|
||||
start() {
|
||||
this._onSliderChanged();
|
||||
}
|
||||
|
||||
private _onSliderChanged() {
|
||||
this._roundCornerRadiuLabel.string = `${this._roundCornerRadiuSlider.progress.toFixed(2)}`;
|
||||
|
||||
// 更新材质
|
||||
this._updateRenderComponentMaterial({
|
||||
roundCornerRadius: this._roundCornerRadiuSlider.progress
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新渲染组件的材质
|
||||
*
|
||||
* 1. 获取材质
|
||||
* 2. 给材质的 unitform 变量赋值
|
||||
* 3. 重新将材质赋值回去
|
||||
*/
|
||||
private _updateRenderComponentMaterial(param: {
|
||||
/**
|
||||
* 圆角半径 [0.0, 0.5] ,0.5 表示圆形裁剪
|
||||
*/
|
||||
roundCornerRadius: number;
|
||||
}) {
|
||||
this._examplesParentNode.children.forEach(childNode => {
|
||||
childNode.getComponents(cc.RenderComponent).forEach(renderComponent => {
|
||||
let material: cc.Material = renderComponent.getMaterial(0);
|
||||
material.setProperty("roundCornerRadius", param.roundCornerRadius);
|
||||
renderComponent.setMaterial(0, material);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
9
assets/scripts/RoundCornerCropEffectScene.ts.meta
Normal file
9
assets/scripts/RoundCornerCropEffectScene.ts.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "d3d2bee7-2173-436c-a11c-94a31b2054c2",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
BIN
assets/textures/freedom.jpg
Normal file
BIN
assets/textures/freedom.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 160 KiB |
34
assets/textures/freedom.jpg.meta
Normal file
34
assets/textures/freedom.jpg.meta
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"ver": "2.3.3",
|
||||
"uuid": "caf42253-1569-497e-83da-2d1696f5866b",
|
||||
"type": "sprite",
|
||||
"wrapMode": "clamp",
|
||||
"filterMode": "bilinear",
|
||||
"premultiplyAlpha": false,
|
||||
"genMipmaps": false,
|
||||
"packable": true,
|
||||
"platformSettings": {},
|
||||
"subMetas": {
|
||||
"freedom": {
|
||||
"ver": "1.0.4",
|
||||
"uuid": "dbc8f785-d78b-4179-bfce-ffbf69396712",
|
||||
"rawTextureUuid": "caf42253-1569-497e-83da-2d1696f5866b",
|
||||
"trimType": "auto",
|
||||
"trimThreshold": 1,
|
||||
"rotated": false,
|
||||
"offsetX": 0,
|
||||
"offsetY": 0,
|
||||
"trimX": 0,
|
||||
"trimY": 0,
|
||||
"width": 755,
|
||||
"height": 755,
|
||||
"rawWidth": 755,
|
||||
"rawHeight": 755,
|
||||
"borderTop": 0,
|
||||
"borderBottom": 0,
|
||||
"borderLeft": 0,
|
||||
"borderRight": 0,
|
||||
"subMetas": {}
|
||||
}
|
||||
}
|
||||
}
|
BIN
static/effects/2d-sprite-round-corner-crop.gif
Normal file
BIN
static/effects/2d-sprite-round-corner-crop.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
Loading…
x
Reference in New Issue
Block a user