加入马赛克特效
This commit is contained in:
parent
9ba4d886b7
commit
cda2d5ab60
146
assets/effects/sprite-mosaic.effect
Normal file
146
assets/effects/sprite-mosaic.effect
Normal file
@ -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 <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 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;
|
||||
}
|
||||
}%
|
17
assets/effects/sprite-mosaic.effect.meta
Normal file
17
assets/effects/sprite-mosaic.effect.meta
Normal file
@ -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": {}
|
||||
}
|
17
assets/materials/sprite-mosaic.mtl
Normal file
17
assets/materials/sprite-mosaic.mtl
Normal file
@ -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": 30,
|
||||
"yBlockCount": 30
|
||||
}
|
||||
}
|
6
assets/materials/sprite-mosaic.mtl.meta
Normal file
6
assets/materials/sprite-mosaic.mtl.meta
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"ver": "1.0.2",
|
||||
"uuid": "f2651803-80c3-4665-bd81-2ad946a12dec",
|
||||
"dataAsSubAsset": null,
|
||||
"subMetas": {}
|
||||
}
|
2826
assets/scenes/MosaicEffectScene.fire
Executable file
2826
assets/scenes/MosaicEffectScene.fire
Executable file
File diff suppressed because it is too large
Load Diff
7
assets/scenes/MosaicEffectScene.fire.meta
Normal file
7
assets/scenes/MosaicEffectScene.fire.meta
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"ver": "1.2.5",
|
||||
"uuid": "4dcbd4ff-0bf9-4429-8c1f-44ad1b7a2192",
|
||||
"asyncLoadAssets": false,
|
||||
"autoReleaseAssets": false,
|
||||
"subMetas": {}
|
||||
}
|
80
assets/scripts/MosaicEffectScene.ts
Normal file
80
assets/scripts/MosaicEffectScene.ts
Normal file
@ -0,0 +1,80 @@
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
@ccclass
|
||||
export default class MosaicEffectScene extends cc.Component {
|
||||
private _xMosaicCountSlider: cc.Slider = null;
|
||||
private _xMosaicCountSliderLabel: cc.Label = null;
|
||||
private _yMosaicCountSlider: cc.Slider = null;
|
||||
private _yMosaicCountSliderLabel: cc.Label = null;
|
||||
|
||||
private _examplesParentNode: cc.Node = null;
|
||||
|
||||
|
||||
onLoad() {
|
||||
// 关闭动态合图
|
||||
cc.dynamicAtlasManager.enabled = false;
|
||||
|
||||
this._xMosaicCountSlider = cc.find("Canvas/Content/Sliders/XMosaicCountSlider/Slider").getComponent(cc.Slider);
|
||||
this._xMosaicCountSliderLabel = cc.find("Canvas/Content/Sliders/XMosaicCountSlider/ValueLabel").getComponent(cc.Label);
|
||||
this._yMosaicCountSlider = cc.find("Canvas/Content/Sliders/YMosaicCountSlider/Slider").getComponent(cc.Slider);
|
||||
this._yMosaicCountSliderLabel = cc.find("Canvas/Content/Sliders/YMosaicCountSlider/ValueLabel").getComponent(cc.Label);
|
||||
|
||||
this._examplesParentNode = cc.find("Canvas/Content/Examples");
|
||||
}
|
||||
|
||||
onEnable() {
|
||||
this._xMosaicCountSlider.node.on("slide", this._onSliderChanged, this);
|
||||
this._yMosaicCountSlider.node.on("slide", this._onSliderChanged, this);
|
||||
}
|
||||
|
||||
onDisable() {
|
||||
this._xMosaicCountSlider.node.off("slide", this._onSliderChanged, this);
|
||||
this._yMosaicCountSlider.node.off("slide", this._onSliderChanged, this);
|
||||
}
|
||||
|
||||
start() {
|
||||
this._onSliderChanged();
|
||||
}
|
||||
|
||||
private _onSliderChanged() {
|
||||
let xMosaicCount = Math.round(this._xMosaicCountSlider.progress * 100);
|
||||
this._xMosaicCountSliderLabel.string = `${xMosaicCount}`;
|
||||
|
||||
let yMosaicCount = Math.round(this._yMosaicCountSlider.progress * 100);
|
||||
this._yMosaicCountSliderLabel.string = `${yMosaicCount}`;
|
||||
|
||||
// 更新材质
|
||||
this._updateRenderComponentMaterial({
|
||||
xBlockCount: xMosaicCount,
|
||||
yBlockCount: yMosaicCount
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新渲染组件的材质
|
||||
*
|
||||
* 1. 获取材质
|
||||
* 2. 给材质的 unitform 变量赋值
|
||||
* 3. 重新将材质赋值回去
|
||||
*/
|
||||
private _updateRenderComponentMaterial(param: {
|
||||
/**
|
||||
* X轴方块数量 [1.0, 正无穷]
|
||||
*/
|
||||
xBlockCount: number;
|
||||
|
||||
/**
|
||||
* Y轴方块数量 [1.0, 正无穷]
|
||||
*/
|
||||
yBlockCount: number;
|
||||
}) {
|
||||
this._examplesParentNode.children.forEach(childNode => {
|
||||
childNode.getComponents(cc.RenderComponent).forEach(renderComponent => {
|
||||
let material: cc.Material = renderComponent.getMaterial(0);
|
||||
material.setProperty("xBlockCount", param.xBlockCount);
|
||||
material.setProperty("yBlockCount", param.yBlockCount);
|
||||
renderComponent.setMaterial(0, material);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
9
assets/scripts/MosaicEffectScene.ts.meta
Normal file
9
assets/scripts/MosaicEffectScene.ts.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "79bbea43-4873-4c16-a20a-6824f7135017",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
Loading…
Reference in New Issue
Block a user