This commit is contained in:
2024-04-16 23:03:54 +08:00
commit 54580cc1b2
723 changed files with 103745 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// YAML 格式的 CC Effect
// 此部分为声明流程控制清单
CCEffect %{
# techniques 是一个数组
techniques:
# passes 是 techniques 数组的第0项
# 同时 passes 也是一个数组,存放渲染管道描述的数组集合
- passes:
# passes 数组的第0项完整的渲染流水线
# vert 属性是指定顶点 Shader 片段的名字,如:这里的顶点 Shader 片段的名字为 unlit-vs
# 根据文档介绍还可以这样子指定片段的入口函数 unlit-vs:vert 那么就代替main函数vert才是入口函数
- vert: unlit-vs
# frag 属性是指定片元 Shader 片段的名字,如:这里的片元 Shader 片段的名字为 unlit-fs
# 根据文档介绍还可以这样子指定片段的入口函数 unlit-fs:frag 那么就代替main函数frag才是入口函数
frag: unlit-fs
# 混合模式开启
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
# properties 列出可以在 Inspector 编辑器编辑的属性
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
}%
// 顶点 Shader 片段
CCProgram unlit-vs %{
// 定义 float 类型的精度为高精度
precision highp float;
// CC 所有内置的 Shader 变量都必须要要通过 #include 引入该变量的头文件
// 所有头文件都在 chunks 目录下
// Mac: /Applications/CocosCreator.app/Contents/Resources/engine/cocos2d/renderer/build/chunks
// 也可以通过 相对项目assets的相对路径 或者 绝对路径 引用头文件资源
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/cc-local>
// 顶点Shader 从渲染管道里面获取哪些数据
// in 用在函数的参数中表示这个参数是输入的在函数中改变这个值并不会影响对调用的函数产生副作用。相当于C语言的传值这个是函数参数默认的修饰符
// 顶点坐标
// a_position 是笛卡尔坐标右手系也是OpenGL的坐标系原点在左下角X轴正方向往右Y轴正方向往上Z轴正方向往外
in vec3 a_position;
// 顶点颜色,实际为对应节点的颜色
in vec4 a_color;
// out 用在函数的参数中,表示该参数是输出参数,值是会改变的
// 顶点 Shader 片段最后会输出的颜色值
// 在片元 Shader 片段中可以接收到这个参数名的值
out vec4 v_color;
// 定义了一个宏,如果使用了纹理那么执行这之间的代码
#if USE_TEXTURE
// 输入的纹理坐标
// a_uv0 是标准屏幕坐标系即原点在左上角X轴正方向往右Y轴正方向往下
in vec2 a_uv0;
// 输出的纹理坐标
// 在片元 Shader 片段中可以接收到这个参数名的值
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 unlit-fs %{
precision highp float;
// 这里引入了内置的chunks目录下的 alpha-test 头文件
#include <builtin/internal/alpha-test>
// 接收来自上方顶点 Shader 片段的输出参数 v_color
// 顶点的颜色
in vec4 v_color;
#if USE_TEXTURE
// 接收来自上方顶点 Shader 片段的输出参数 v_uv0
// 顶点的坐标
in vec2 v_uv0;
// uniform :一致变量。在着色器执行期间一致变量的值是不变的
// 与const常量不同的是这个值在编译时期是未知的是由着色器外部初始化的
// 一致变量在顶点着色器和片段着色器之间是共享的。它也只能在全局范围进行声明。
uniform sampler2D mainTexture;
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
// 纹理颜色 和 节点颜色进行混合得出最终颜色
o *= v_color;
// 这个方法来自 alpha-test 头文件
// 意思大概为如果传入的参数vec4 类型的参数o的透明通道值小于传入来的 alphaThreshold 值时会discard
// 使用discard会退出片段着色器不执行后面的片段着色操作。片段也不会写入帧缓冲区。
ALPHA_TEST(o);
gl_FragColor = o;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "8f277982-dc0a-4030-90cc-b336a928a372",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,76 @@
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
textureWidth: { value: 600.0 }
speed: { value: 10.0 }
amplitude: { value: 5.0 }
wave: { value: 5.0 }
startPos: { value: [0.0, 0.0] }
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-local>
#include <builtin/uniforms/cc-global>
in vec3 a_position;
uniform LAMYOUMG_COM {
float textureWidth;
float speed;
float amplitude;
float wave;
vec2 startPos;
};
#if USE_TEXTURE
in mediump vec2 a_uv0;
out mediump vec2 v_uv0;
#endif
void main () {
float angleSpanH = wave * 3.14159265;
float pz = amplitude * sin(cc_time.x * speed - (a_position.x - startPos.x + a_position.y - startPos.y) / textureWidth * angleSpanH);
vec4 position = vec4(a_position.x, a_position.y + pz, a_position.z, 1);
// vec4 position = vec4(a_position.x, a_position.y , a_position.z + pz, 1); // use in 3d
#if USE_TEXTURE
v_uv0 = a_uv0;
#endif
gl_Position = cc_matViewProj * cc_matWorld * position;
}
}%
CCProgram unlit-fs %{
#include <builtin/uniforms/cc-global>
precision highp float;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#endif
gl_FragColor = o;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "d0c80b5d-d212-4e75-8581-23ec133eb3a4",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,235 @@
// Copyright (c) 20172018 Xiamen Yaji Software Co., Ltd.
// 闪光(光速扫过)
// 原理(和点光的很类似):
// 1. 画光束
// 2. 圆心中间高亮(透明度=1.0),边缘不亮(透明度=0.0
// 3. 在原图像上方叠加光束
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 光束颜色
lightColor: {
value: [1.0, 1.0, 0.0, 1.0],
editor: {
type: color,
tooltip: "光束颜色"
}
}
# 光束中心点坐标
lightCenterPoint: {
value: [0.2, 0.2],
editor: {
tooltip: "光束中心点坐标"
}
}
# 光束倾斜角度
lightAngle: {
value: 36.0,
editor: {
tooltip: "光束倾斜角度",
range: [0.0, 1.0],
}
}
# 光束宽度
lightWidth: {
value: 0.2,
editor: {
tooltip: "光束宽度"
}
}
# 启用光束渐变
enableGradient: {
value: 1.0,
editor: {
tooltip: "是否启用光束渐变。0不启用非0启用"
}
}
# 裁剪掉透明区域上的光
cropAlpha: {
value: 1.0,
editor: {
tooltip: "是否裁剪透明区域上的光。0不启用非0启用"
}
}
# 是否启用迷雾效果
enableFog: {
value: 0.0,
editor: {
tooltip: "是否启用迷雾效果。0不启用非0启用"
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if ENABLE_LIGHT
uniform Light {
// 光束颜色
vec4 lightColor;
// 光束中心点坐标
vec2 lightCenterPoint;
// 光束倾斜角度
float lightAngle;
// 光束宽度
float lightWidth;
// 启用光束渐变
// ps编辑器还不支持 bool 类型的样子因此用float来定义
float enableGradient;
// 裁剪掉透明区域上的光
// ps编辑器还不支持 bool 类型的样子因此用float来定义
float cropAlpha;
// 是否启用迷雾效果
// ps编辑器还不支持 bool 类型的样子因此用float来定义
float enableFog;
};
/**
* 添加光束颜色
*/
vec4 addLightColor(vec4 textureColor, vec4 lightColor, vec2 lightCenterPoint, float lightAngle, float lightWidth) {
// 边界值处理,没有宽度就返回原始颜色
if (lightWidth <= 0.0) {
return textureColor;
}
// 计算当前 uv 到 光束 的距离
float angleInRadians = radians(lightAngle);
// 角度0与非0不同处理
float dis = 0.0;
if (mod(lightAngle, 180.0) != 0.0) {
// 计算光束中心线下方与X轴交点的X坐标
// 1.0 - lightCenterPoint.y 是将转换为OpenGL坐标系下文的 1.0 - y 类似
float lightOfunlit = lightCenterPoint.x - ((1.0 - lightCenterPoint.y) / tan(angleInRadians));
// 以当前点画一条平行于X轴的线假设此线和光束中心线相交的点为D点
// 那么
// D.y = uv0.y
// D.x = lightOfunlit + D.y / tan(angle)
float dx = lightOfunlit + (1.0 - v_uv0.y) / tan(angleInRadians);
// D 到当前 uv0 的距离就是
// dis = |uv0.x - D.x|
float offsetDis = abs(v_uv0.x - dx);
// 当前点到光束中心线的的垂直距离就好算了
dis = sin(angleInRadians) * offsetDis;
} else {
dis = abs(v_uv0.y - lightCenterPoint.y);
}
float a = 1.0 ;
// 裁剪掉透明区域上的点光
if (bool(cropAlpha)) {
a *= step(0.01, textureColor.a);
}
// 裁剪掉光束范围外的uv迷雾效果
if (!bool(enableFog)) {
a *= step(dis, lightWidth * 0.5);
}
// 加入从中心往外渐变的效果
if (bool(enableGradient)) {
a *= 1.0 - dis / (lightWidth * 0.5);
}
// 计算出扩散范围内,不同 uv 对应的实际扩散颜色值
vec4 finalLightColor = lightColor * a;
// 混合颜色:在原始图像颜色上叠加扩散颜色
return textureColor * textureColor.a + finalLightColor;
}
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
gl_FragColor = o;
#if ENABLE_LIGHT
gl_FragColor = addLightColor(gl_FragColor, lightColor, lightCenterPoint, lightAngle, lightWidth);
#endif
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "e9682cd1-a19c-4fcb-ad8c-cf1783b805e6",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,196 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// 高斯模糊
//
// 参考资料(必读)
// * http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html
// * https://zh.wikipedia.org/wiki/%E9%AB%98%E6%96%AF%E6%A8%A1%E7%B3%8A
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# # 标准方差值
# stDev: {
# value: 0.84089642,
# editor: {
# tooltip: "标准方差值"
# }
# }
# 纹理尺寸
textureSize: {
value: [100.0, 100.0],
editor: {
tooltip: "纹理尺寸px宽 x 高)"
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if ENABLE_GAUSSIAN_BLUR
// 定义无理数
#pragma define e 2.718281828459045
// 定义标准方差值(方差值越大,越模糊,但是需要计算的高斯矩阵范围会变大,从而带来巨大的计算量)
// #pragma define stDev 0.84089642
#pragma define stDev 1.5
// #pragma define stDev 5.0
// #pragma define stDev 10.0
// 定义π
#pragma define pi 3.141592653589793
// 接收外部变量
uniform GaussianBlur {
// 纹理尺寸(宽 x 高px
vec2 textureSize;
// // 标准方差值
// float stDev;
};
/**
* 获取权重(对应二维高斯函数公式,见 https://zh.wikipedia.org/wiki/%E9%AB%98%E6%96%AF%E6%A8%A1%E7%B3%8A )
*/
float getWeight(float x, float y) {
return (1.0 / (2.0 * pi * pow(stDev, 2.0))) * pow(1.0 / e, (pow(x, 2.0) + pow(y, 2.0)) / (2.0 * pow(stDev, 2.0)));
}
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
gl_FragColor = o;
#if ENABLE_GAUSSIAN_BLUR
// 根据高斯分布也叫正态分布在3个标准差范围内的分布比例占到99%的权重,因此我们只需要计算矩阵范围 [6 * stDev + 1, 6 * stDev +1] 上的权重
const float size = floor(stDev * 6.0 + 1.0);
const float halfSize = floor(size / 2.0);
// 步骤一:计算高斯矩阵上所有权重的和
// // v1遍历所有点每个点都计算权重
// float totalWeight = 0.0;
// for(float x = -halfSize; x<= halfSize; x++) {
// for (float y = -halfSize; y<= halfSize; y++) {
// totalWeight += getWeight(x, y);
// }
// }
// v2因为高斯分布是对称的所以只计算原点、X轴正方向 * 2 、Y轴正方向 * 2 、第一象限的权重 * 4即可求出所有权重之和相比起v1版本减少很多循环计算
// 原点
float totalWeight = getWeight(0.0, 0.0);
// X轴正方向上的权重 * 2.0 就是整个X轴上的权重
for(float x = 1.0; x <= halfSize; x++) {
totalWeight += getWeight(x, 0.0) * 2.0;
}
// Y轴正方向上的权重 * 2.0 就是整个Y轴上的权重
for(float y = 1.0; y <= halfSize; y++) {
totalWeight += getWeight(0.0, y) * 2.0;
}
// 第一象限的权重 * 4.0 就是4个象限的权重
for(float x = 1.0; x <= halfSize; x++) {
for (float y = 1.0; y<= halfSize; y++) {
totalWeight += getWeight(x, y) * 4.0;
}
}
// TODO:
//
// 因为权重矩阵是一次性计算即可不断应用因此可以将权重矩阵的计算放到CPU计算并传入到Shader直接渲染因此有以下优化方案
//
// v3原始权重矩阵在CPU计算并传入到Shader
// v4加权平均后的权重矩阵在CPU计算并传入Shader
// 步骤二:采样周边像素并应用加权平均值,得出最终像素值
vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);
// float divider = 0.01;
float onePxWidth = 1.0 / textureSize.x;
float onePxHeight = 1.0 / textureSize.y;
for(float x = -halfSize; x<= halfSize; x++) {
for (float y = -halfSize; y<= halfSize; y++) {
// 求出对应坐标的真正权重(对应权重矩阵)
float weight = getWeight(x, y) / totalWeight;
// 求出对应坐标像素颜色值的加权值
// finalColor += texture(mainTexture, v_uv0 + vec2(divider * x, divider * y)) * weight;
finalColor += texture(mainTexture, v_uv0 + vec2(onePxWidth * x, onePxHeight * y)) * weight;
}
}
gl_FragColor = finalColor;
#endif
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "41f4d474-d707-45bb-af93-637573f92d54",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,258 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 自定义参数
# 发光颜色
glowColor: {
value: [1.0, 1.0, 0.0, 1.0],
editor: {
type: color,
tooltip: "发光颜色"
}
}
# 发光宽度
glowColorSize: {
value: 0.2,
editor: {
tooltip: "发光宽度",
range: [0.0, 1.0],
}
}
# 发光透明度阈值
# 只有超过这个透明度的点才会发光
# 一般用于解决图像边缘存在渐变透明的时,决定超过这个透明度阈值的边缘点才点发光,具体可以操作一下
glowThreshold: {
value: 0.1,
editor: {
tooltip: "发光阈值",
range: [0.0, 1.0]
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#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 mainTexture, 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(mainTexture, 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
float radian = radians(angle);
vec4 color = getTextureColor(mainTexture, 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(mainTexture, 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 *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, 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
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "345a48c3-c00c-45d2-b6c9-b1ac49f46662",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,291 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 自定义参数
# 发光颜色
glowColor: {
value: [1.0, 1.0, 0.0, 1.0],
editor: {
type: color,
tooltip: "发光颜色"
}
}
# 发光宽度
glowColorSize: {
value: 0.15,
editor: {
tooltip: "发光宽度",
range: [0.0, 1.0],
}
}
# 发光透明度阈值
# 只有小于等于这个透明度的点才会发光
glowThreshold: {
value: 1.0,
editor: {
tooltip: "发光阈值",
range: [0.0, 1.0]
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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;
// // 左移
// 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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#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 mainTexture, 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(mainTexture, 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(mainTexture, 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(mainTexture, 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 *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, 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
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "67e9833e-aa43-427a-ba89-d7bdd1ef0aed",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,110 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// 灰化特效
// 原理:
// r = 0.2126 * r + 0.7152 * g + 0.0722 * b
// g = 0.2126 * r + 0.7152 * g + 0.0722 * b
// b = 0.2126 * r + 0.7152 * g + 0.0722 * b
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 灰化程度
grayLevel: {
value: 1.0,
editor: {
tooltip: "灰化程度",
range: [0.0, 1.0]
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if USE_GRAY
uniform GrayPhoto {
// 灰化程度
float grayLevel;
};
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
#if USE_GRAY
vec4 srcColor = o;
float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
vec4 grayColor = vec4(gray, gray, gray, o.a);
o = srcColor + (grayColor - srcColor) * grayLevel;
#endif
gl_FragColor = o;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "2e5b29d9-dd5e-4f3d-92e9-e580745b3bc8",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,146 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// 马赛克特效
// 原理: n x n 方块内取同一颜色
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# X轴方块数量
xBlockCount: {
value: 30.0,
editor: {
tooltip: "X轴方向马赛克方块数量"
}
}
# Y轴方块数量
yBlockCount: {
value: 30.0,
editor: {
tooltip: "Y轴方向马赛克方块数量"
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#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(mainTexture, realPos);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, realPos + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
gl_FragColor = o;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "9638979d-62b3-4e5b-adea-7ad706e66e65",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -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: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 老化程度
oldLevel: {
value: 1.0,
editor: {
tooltip: "老化程度",
range: [0.0, 1.0]
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#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(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, 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;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "211eddf3-c53d-46e3-8c09-c1bf38e644e2",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,153 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 描边颜色
outlineColor: {
value: [1.0, 0.0, 0.0, 1.0],
editor: {
type: color,
tooltip: "描边颜色",
}
}
# 描边宽度
outlineWidth: {
value: 0.002,
editor: {
tooltip: "描边宽度",
range: [0.0, 1.0]
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if SHOW_OUT_LINE
uniform Outline {
// 描边颜色
vec4 outlineColor;
// 描边偏移大小
float outlineWidth;
// 特别地,必须是 vec4 先于 float 声明
};
// 将图像往8个方向偏移后得到一个类似放大的效果然后取放大后的图像的透明度即可得到一个放大后的区域可以很方便填充描边颜色
// 取当前点上、下、左、右、上左、上右、下左、下右共计8个方向距离为 outlineWidth 的8个点求他们的透明度之和
// 由此可以得到当前点是否属于图像往八个方向做偏移后得到的放大图区域,并且能得到该点最终透明度值
// 最终对应的为图像偏移/放大后的背景区域
float getBgAlpha() {
vec4 color_up = texture(mainTexture, v_uv0 + vec2(0, outlineWidth));
vec4 color_down = texture(mainTexture, v_uv0 - vec2(0, outlineWidth));
vec4 color_left = texture(mainTexture, v_uv0 - vec2(outlineWidth, 0));
vec4 color_right = texture(mainTexture, v_uv0 + vec2(outlineWidth, 0));
vec4 color_up_left = texture(mainTexture, v_uv0 + vec2(outlineWidth, -outlineWidth));
vec4 color_up_right = texture(mainTexture, v_uv0 + vec2(outlineWidth, outlineWidth));
vec4 color_down_left = texture(mainTexture, v_uv0 + vec2(-outlineWidth, -outlineWidth));
vec4 color_down_right = texture(mainTexture, 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);
}
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
gl_FragColor = o;
#if SHOW_OUT_LINE
// 无描边宽度即结束
if (outlineWidth == 0.0) {
return;
}
// 先画背景色
vec4 color_dest = outlineColor * getBgAlpha();
// 然后在背景色上方画图案颜色
vec4 color_src = o;
// 按照这个顺序,源颜色就是图案颜色,目标颜色就是背景色
// 所以命名就是 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_MINUS_SRC_ALPHA
// 即最终颜色如下:
// color_src * GL_SRC_ALPHA + color_dest * GL_ONE_MINUS_SRC_ALPHA
gl_FragColor = color_src * color_src.a + color_dest * (1.0 - color_src.a);
#endif
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "34c2ed47-4d59-41c4-b91c-157c32e9d0eb",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,182 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// 点光/点扩散
// 原理:
// 1. 画圆
// 2. 圆心高亮(透明度=1.0),圆边缘不亮(透明度=0.0
// 3. 在原图像上方叠加圆
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 扩散颜色
centerColor: {
value: [1.0, 1.0, 0.0, 1.0],
editor: {
type: color,
tooltip: "发光颜色"
}
}
# 扩散起点坐标
centerPoint: {
value: [0.2, 0.2],
editor: {
tooltip: "扩散起点坐标"
}
}
# 扩散半径
radius: {
value: 0.4,
editor: {
tooltip: "扩散半径"
}
}
# 裁剪掉透明区域上的光
cropAlpha: {
value: 1.0,
editor: {
tooltip: "是否裁剪透明区域上的光。0不启用非0启用"
}
}
# 是否启用迷雾效果
enableFog: {
value: 0.0,
editor: {
tooltip: "是否启用迷雾效果。0不启用非0启用"
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if ENABLE_DIFFUSION
uniform Diffusion {
// 扩散颜色
vec4 centerColor;
// 扩散起点坐标
vec2 centerPoint;
// 扩展半径
float radius;
// 裁剪掉透明区域上的光
// ps编辑器还不支持 bool 类型的样子因此用float来定义
float cropAlpha;
// 是否启用迷雾效果
// ps编辑器还不支持 bool 类型的样子因此用float来定义
float enableFog;
};
/**
* 添加某个扩散点后混合后的纹理颜色
*/
vec4 addLightColor(vec4 textureColor, vec2 centerPoint, float radius, vec4 centerColor) {
// 计算当前 uv 到圆心起点的距离
float dis = distance(v_uv0, centerPoint);
float a = 1.0 ;
// 裁剪掉透明区域上的点光
if (bool(cropAlpha)) {
a *= step(0.01, textureColor.a);
}
// 裁剪掉光束范围外的uv迷雾效果
if (!bool(enableFog)) {
a *= step(dis, radius);
}
// 加入从中心往外渐变的效果
a *= 1.0 - (dis / radius);
// 计算出圆范围内,不同 uv 对应的实际颜色值
vec4 lightColor = centerColor * a;
// 混合颜色:在原始图像颜色上叠加圆颜色
return textureColor * textureColor.a + lightColor;
}
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
gl_FragColor = o;
#if ENABLE_DIFFUSION
gl_FragColor = addLightColor(gl_FragColor, centerPoint, radius, centerColor);
#endif
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "72a182fc-08a6-4faa-8e36-8bd84b4a0b53",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,145 @@
// 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: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 圆角半径
radius: {
value: 0.4,
editor: {
tooltip: "圆角半径"
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if ENABLE_ROUNDCORNER
uniform RoundCorner {
// 圆角半径
float radius;
};
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
#if ENABLE_ROUNDCORNER
// 约束圆角半径范围在 [0.0, 0.5]
float circleRadius = clamp(0.0, 0.5, radius);
// 将纹理uv往左上偏移实现偏移后的坐标系原点在纹理中心
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 - circleRadius);
float ry = abs(uv.y) - (0.5 - circleRadius);
// 区分 以第一象限圆角所在圆心坐标为原点的坐标的四个象限
//
// 第一象限 mx = 1, my = 1
// 第二象限 mx = 0, my = 1
// 第三象限 mx = 0, my = 0
// 第四象限 mx = 1, my = 0
//
// 当 mx * my 时只要等于1那就是标识第一象限实际对应圆角区域所在矩形否则就是第二、三、四象限
float mx = step(0.5 - circleRadius, abs(uv.x));
float my = step(0.5 - circleRadius, abs(uv.y));
// 计算相对uv坐标到圆心的距离
float len = length(vec2(rx, ry));
// mx * my = 0 时代表非圆角区域a 值为1代表完全采用原始纹理的透明度
// mx * my = 1 时,代表园所所在矩形区域
// step(circleRadius, len) 可以区分出圆角所在矩形区域的 圆角区域 和 非圆角区域
// 其中圆角区域值为0非圆角区域值为1
// 当为圆角区域时a 值为1代表完全采用原始纹理透明度
// 当为非圆角区域时a 值为0代表完全透明
// 至此已经实现圆角裁剪
//
// smoothstep(0., circleRadius * 0.01, len - circleRadius) 是用于抗锯齿优化
// 原理:针对点在非圆角区域的情况,针对点在大于「圆半径一点点」地方的区域,进行平滑过渡,以实现抗锯齿
// 其中,
// 「圆半径一点点」用 circleRadius * 0.01 表示0.01 可自行改变)
// 点在大于圆半径的区域用 len - circleRadius ,此值会在 [0.0, circleRadius * 0.01] 之间时会平滑过渡
float a = 1.0 - mx * my * step(circleRadius, len) * smoothstep(0., circleRadius * 0.01, len - circleRadius);
o = vec4(o.rgb, o.a * a);
#endif
gl_FragColor = o;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "a4afedba-5234-44d7-9031-cba83051d521",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,192 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
//
// 圆角裁剪(支持任意宽高纹理)
//
// 原理:
// 1. 正方形纹理的圆角原理参考 https://www.cnblogs.com/jqm304775992/p/4987793.html
// 2. 正方形纹理的圆角代码参考 yanjifa/shaderDemor 的 https://github.com/yanjifa/shaderDemo/blob/master/assets/Effect/CircleAvatar.effect
// 3. 上述皆为只针对正方形纹理做的操作,如果是长方形的纹理,那么圆角就会有拉伸后的效果,最后变成看起来就不是圆角了,本特效支持任意长方形做圆角
CCEffect %{
techniques:
- passes:
- vert: unlit-vs
frag: unlit-fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
mainTexture: { value: white }
alphaThreshold: { value: 0.5 }
# 圆角x轴半径长度相对于纹理宽度
xRadius: {
value: 0.4,
editor: {
tooltip: "圆角x轴半径长度相对于纹理宽度"
}
}
# 圆角y轴半径长度相对于纹理高度
yRadius: {
value: 0.4,
editor: {
tooltip: "圆角y轴半径长度相对于纹理高度"
}
}
}%
CCProgram unlit-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#include <builtin/uniforms/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 unlit-fs %{
precision highp float;
#include <builtin/internal/alpha-test>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D mainTexture;
#endif
#if ENABLE_ROUNDCORNER
uniform RoundCorner {
// 圆角x轴半径长度相对于纹理宽度
float xRadius;
// 圆角y轴半径长度相对于纹理高度
float yRadius;
};
#endif
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
o *= texture(mainTexture, v_uv0);
#if CC_USE_ALPHA_ATLAS_TEXTURE
o.a *= texture2D(mainTexture, v_uv0 + vec2(0, 0.5)).r;
#endif
#endif
o *= v_color;
ALPHA_TEST(o);
#if ENABLE_ROUNDCORNER
// 约束圆角半径范围在 [0.0, 0.5]
//
// 请注意这里我是用椭圆前缀去命名的半径
//
// 为什么是椭圆?
//
// 因为圆角,相对于长方形的纹理的宽高来说,归一化后值并不一样,不是圆,而是一个椭圆
//
// 比如:
//
// 纹理是 200 x 100 的像素圆角半径是20像素那么归一化后
// X轴上的半径就是 20 / 200 = 0.1
// Y轴上的半径就是 20 / 100 = 0.2
//
// 这就会变成是椭圆,而不是圆
float ellipseXRadius = clamp(0.0, 0.5, xRadius);
float ellipseYRadius = clamp(0.0, 0.5, yRadius);
// 将纹理uv往左上偏移实现偏移后的坐标系原点在纹理中心
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 - ellipseXRadius);
float ry = abs(uv.y) - (0.5 - ellipseYRadius);
// 区分 以第一象限圆角所在圆心坐标为原点的坐标的四个象限
//
// 第一象限 mx = 1, my = 1
// 第二象限 mx = 0, my = 1
// 第三象限 mx = 0, my = 0
// 第四象限 mx = 1, my = 0
//
// 当 mx * my 时只要等于1那就是标识第一象限实际对应圆角区域所在矩形否则就是第二、三、四象限
float mx = step(0.5 - ellipseXRadius, abs(uv.x));
float my = step(0.5 - ellipseYRadius, abs(uv.y));
// 判断点(rx, ry)是否在椭圆外部(应用椭圆公式)
float isOutOfEllipse = step(1.0, pow(rx, 2.0) / pow(xRadius, 2.0) + pow(ry, 2.0) / pow(yRadius, 2.0));
///////////////////////////////////////////////////////////////////////////////////////////
// 抗锯齿
// 1. 先计算当前点到椭圆中心的角度
float angleInRadian = atan(ry / rx);
// 2. 计算这个角度下,对于对应圆角(椭圆)上的点
vec2 pointInEllipse = vec2(xRadius * cos(angleInRadian), yRadius * sin(angleInRadian));
// 3. 计算这个角度下,比当前圆角大一点椭圆上的点
vec2 pointInBigEllipse = vec2((xRadius * 1.01) * cos(angleInRadian), (yRadius * 1.01)* sin(angleInRadian));
// 4. 计算最远点到当前椭圆的距离
float maxDis = distance(pointInBigEllipse, pointInEllipse);
// 5. 计算当前点到当前椭圆的距离
float curDis = distance(vec2(rx, ry), pointInEllipse);
// 6. 生成插值
float smo = smoothstep(0.0, maxDis, curDis);
///////////////////////////////////////////////////////////////////////////////////////////
// mx * my = 0 时代表非椭圆角区域alpha 值为1代表完全采用原始纹理的透明度
// mx * my = 1 时,代表椭圆角所在矩形区域
// isOutOfEllipse:
// 当点在椭圆外部时此值为1导致 alpha 最终值为0.0,即表示不显示椭圆外部的像素
// 当点在椭圆内部时此值为0导致 alpha 最终值为1.0,即表示显示椭圆内部的像素
// smo : 抗锯齿实现
// float alpha = 1.0 - mx * my * isOutOfEllipse;
float alpha = 1.0 - mx * my * isOutOfEllipse * smo;
o = vec4(o.rgb, o.a * alpha);
#endif
gl_FragColor = o;
}
}%

View File

@@ -0,0 +1,11 @@
{
"ver": "1.7.1",
"importer": "effect",
"imported": true,
"uuid": "7c24b57e-e819-4fc9-a8d2-b06cf61b782d",
"files": [
".json"
],
"subMetas": {},
"userData": {}
}