加入马赛克特效

This commit is contained in:
caizhitao 2019-12-26 23:28:27 +08:00
parent 9ba4d886b7
commit cda2d5ab60
8 changed files with 3108 additions and 0 deletions

View 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;
}
}%

View 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": {}
}

View 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
}
}

View File

@ -0,0 +1,6 @@
{
"ver": "1.0.2",
"uuid": "f2651803-80c3-4665-bd81-2ad946a12dec",
"dataAsSubAsset": null,
"subMetas": {}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
{
"ver": "1.2.5",
"uuid": "4dcbd4ff-0bf9-4429-8c1f-44ad1b7a2192",
"asyncLoadAssets": false,
"autoReleaseAssets": false,
"subMetas": {}
}

View 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);
});
});
}
}

View File

@ -0,0 +1,9 @@
{
"ver": "1.0.5",
"uuid": "79bbea43-4873-4c16-a20a-6824f7135017",
"isPlugin": false,
"loadPluginInWeb": true,
"loadPluginInNative": true,
"loadPluginInEditor": false,
"subMetas": {}
}