Commit ffec93db authored by wjf's avatar wjf

l

parents
Pipeline #242522 failed with stages
in 0 seconds
# project ignores
node_modules
# project ignores
node_modules
/scripts
/src
tsConfig.json
webpack.config.js
jsconfig111111.json
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"allowSyntheticDefaultImports": true
},
"exclude": [
"node_modules",
"bower_components",
"jspm_packages",
"tmp",
"temp"
]
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "fyge",
"version": "1.0.3",
"description": "淘宝小程序canvas渲染引擎",
"main": "./dist/fyge.min.js",
"types": "./types/FYGE.d.ts",
"dependencies": {},
"scripts": {
"declare": "node scripts/declare.js src/index.ts",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack -w",
"watch": "webpack --watch"
},
"author": "MrKwon",
"license": "ISC",
"devDependencies": {
"ts-loader": "^4.0.0",
"webpack": "^4.1.0",
"webpack-cli": "^3.3.2",
"typescript": "^2.7.2",
"uglifyjs-webpack-plugin": "^2.1.2"
},
"keywords": [
"淘宝小程序,canvas"
]
}
const fs = require('fs');
const ts = require("typescript");
const regLine = /(export|declare)((?!from).)*/g;
function compile(fileNames, options) {
const host = ts.createCompilerHost(options);
const exports = [];
host.writeFile = (fileName, fileContent) => {
const result = fileContent.match(regLine);
for (let line of result) {
if (line.match(/export (default)? \w+;/)) {
continue;
}
if (line.endsWith(';')) {
if (!line.startsWith('_') && !line.startsWith('export default function')) {
exports.push(line);
}
} else {
if (line.endsWith('{')) {
let start = fileContent.indexOf(line);
const block = fileContent.substring(start, fileContent.indexOf('\n}', start) + 2);
if (!block.startsWith('_')) {
exports.push(block);
}
}
}
}
};
const program = ts.createProgram(fileNames, options, host);
program.emit();
let allExports = exports.join('\n\n')
.replace(/export default _default;/g, '')
.replace(/export declare/g, 'export ')
.replace(/export default/g, 'export ')
.replace(/declare /g, 'export ')
;
// const content = `declare module FYGE{${allExports}}`;
const content = `declare namespace FYGE{${allExports}}\ndeclare module "fyge" {export = FYGE;}`;
fs.writeFileSync('types/FYGE.d.ts', content);
}
compile(process.argv.slice(2), {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
});
/**
* 基础
*/
export abstract class HashObject {
protected _instanceId: number = 0;
protected _instanceType: string = "HashObject";
protected static _object_id = 0;
constructor() {
this._instanceId = HashObject._object_id++;
}
/**
* 每一个对象都会有一个唯一的id码。
* @property instanceId
* @public
* @since 1.0.0
* @return {number}
* @readonly
* @example
* //获取 对象唯一码
* trace(this.instanceId);
*/
public get instanceId(): number {
return this._instanceId;
}
/**
* 每一个类都有一个实例类型字符串,通过这个字符串,你能知道这个实例是从哪个类实例而来
* @property instanceType
* @since 1.0.3
* @public
* @return {string}
* @readonly
*/
public get instanceType(): string {
return this._instanceType;
}
/**
* 销毁一个对象
* 销毁之前一定要从显示对象移除,否则将会出错
* @method destroy
* @since 2.0.0
* @public
* @return {void}
*/
abstract destroy(): void;
}
//这里都是一些常量
/**
* 版本号
* @static
* @constant
* @name VERSION
* @type {string}
*/
export const VERSION = "1.0";
/**
* 有问题
*/
//@ts-ignore
export const sysInfo = my.getSystemInfoSync();
/**
* 有问题
*/
export const devicePixelRatio: number = sysInfo.pixelRatio //window.devicePixelRatio || 1;
/**
* 获取设备号iOS Android
*/
export const osType: "ios" | "android" = sysInfo.platform.toLowerCase()
let PI: number = Math.PI;
let HalfPI: number = PI >> 1;
let PacPI: number = PI + HalfPI;
/**
* @method cos
* @private
* @param {number} angle,弧度制
* @return {number}
*/
export function cos(angle: number): number {
switch (angle) {
case HalfPI:
case -PacPI:
return 0;
case PI:
case -PI:
return -1;
case PacPI:
case -HalfPI:
return 0;
default:
return Math.cos(angle);
}
}
/**
* @method sin
* @param {number} angle,弧度制
* @return {number}
*/
export function sin(angle: number): number {
switch (angle) {
case HalfPI:
case -PacPI:
return 1;
case PI:
case -PI:
return 0;
case PacPI:
case -HalfPI:
return -1;
default:
return Math.sin(angle);
}
}
/**
* Two Pi.
*
* @static
* @constant
* @type {number}
*/
export const PI_2: number = PI * 2;
/**
* Conversion factor for converting radians to degrees.
* 弧度转角度
* @static
* @constant
* @type {number}
*/
export const RAD_TO_DEG: number = 180 / PI;
/**
* Conversion factor for converting degrees to radians.
* 角度转弧度
* @static
* @constant
* @type {number}
*/
export const DEG_TO_RAD: number = PI / 180;
/**
* 渲染方式记录
* @static
* @constant
* @name RENDERER_TYPE
* @type {object}
* @property {number} UNKNOWN - Unknown render type.
* @property {number} WEBGL - WebGL render type.
* @property {number} CANVAS - Canvas render type.
*/
export enum RENDERER_TYPE {
UNKNOWN = 0,
WEBGL,
CANVAS,
};
/**
* 各种形状
* @static
* @constant
* @name SHAPES
* @type {object}
* @property {number} POLY Polygon 多边形
* @property {number} RECT Rectangle 矩形
* @property {number} CIRC Circle 圆形
* @property {number} ELIP Ellipse 椭圆
* @property {number} RREC Rounded Rectangle 圆角矩形
*/
export enum SHAPES {
POLY = 0,
RECT,
CIRC,
ELIP,
RREC,
};
/**
* 着色器浮点精度
* @static
* @constant
* @name PRECISION
* @type {object}
* @property {string} LOW='lowp'
* @property {string} MEDIUM='mediump'
* @property {string} HIGH='highp'
*/
export enum PRECISION {
LOW = 'lowp',
MEDIUM = 'mediump',
HIGH = 'highp',
};
/**
* 文本渐变方式,以后用
* @static
* @constant
* @name TEXT_GRADIENT
* @type {object}
* @property {number} LINEAR_VERTICAL 水平渐变
* @property {number} LINEAR_HORIZONTAL 垂直渐变
*/
export enum TEXT_GRADIENT {
LINEAR_VERTICAL = 0,
LINEAR_HORIZONTAL,
};
/**
* 文本对齐方式 水平
*/
export enum TEXT_ALIGN {
CENTER = "center",
LEFT = "left",
RIGHT = "right",
}
export enum VERTICAL_ALIGN {
MIDDLE = "middle",
UP = "up",
DOWN = "down",
}
/**
* 文本类型,单行或多行
*/
export enum TEXT_lINETYPE {
SINGLE = "single",
MULTI = "multi"
}
/**
* 画线时的对齐方式
*/
export enum LINE_ALIGNMENT {
middle = 0.5,
outter = 1,
inner = 0
}
/**
* canvas线头
*/
export enum LINE_CAP {
BUTT = "butt",
ROUND = "round",
SQUARE = "square",
}
/**
* canvas线连接处
*/
export enum LINE_JOIN {
MITER = "miter",
ROUND = "round",
BEVEL = "bevel"
}
/**
* Various blend modes supported by
*
* IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes.
* Anything else will silently act like NORMAL.
*
* @static
* @constant
* @name BLEND_MODES
* @type {object}
* @property {number} NORMAL
* @property {number} ADD
* @property {number} MULTIPLY
* @property {number} SCREEN
* @property {number} OVERLAY
* @property {number} DARKEN
* @property {number} LIGHTEN
* @property {number} COLOR_DODGE
* @property {number} COLOR_BURN
* @property {number} HARD_LIGHT
* @property {number} SOFT_LIGHT
* @property {number} DIFFERENCE
* @property {number} EXCLUSION
* @property {number} HUE
* @property {number} SATURATION
* @property {number} COLOR
* @property {number} LUMINOSITY
*/
export enum BLEND_MODES {
NORMAL = 0,
ADD,
MULTIPLY,
SCREEN,
OVERLAY,
DARKEN,
LIGHTEN,
COLOR_DODGE,
COLOR_BURN,
HARD_LIGHT,
SOFT_LIGHT,
DIFFERENCE,
EXCLUSION,
HUE,
SATURATION,
COLOR,
LUMINOSITY,
NORMAL_NPM,
ADD_NPM,
SCREEN_NPM,
NONE,
SRC_OVER,
SRC_IN,
SRC_OUT,
SRC_ATOP,
DST_OVER,
DST_IN,
DST_OUT,
DST_ATOP,
ERASE,
SUBTRACT,
};
/**
* Various webgl draw modes. These can be used to specify which GL drawMode to use
* under certain situations and renderers.
*
* @static
* @constant
* @name DRAW_MODES
* @type {object}
* @property {number} POINTS
* @property {number} LINES
* @property {number} LINE_LOOP
* @property {number} LINE_STRIP
* @property {number} TRIANGLES
* @property {number} TRIANGLE_STRIP
* @property {number} TRIANGLE_FAN
*/
export enum DRAW_MODES {
POINTS = 0,
LINES,
LINE_LOOP,
LINE_STRIP,
TRIANGLES,
TRIANGLE_STRIP,
TRIANGLE_FAN,
};
/**
* The scale modes that are supported by
*
* The {@link settings.SCALE_MODE} scale mode affects the default scaling mode of future operations.
* It can be re-assigned to either LINEAR or NEAREST, depending upon suitability.
*
* @static
* @constant
* @name SCALE_MODES
* @type {object}
* @property {number} LINEAR Smooth scaling
* @property {number} NEAREST Pixelating scaling
*/
export enum SCALE_MODES {
LINEAR = 0,
NEAREST,
};
/**
* The wrap modes that are supported by
*
* The {@link settings.WRAP_MODE} wrap mode affects the default wrapping mode of future operations.
* It can be re-assigned to either CLAMP or REPEAT, depending upon suitability.
* If the texture is non power of two then clamp will be used regardless as webGL can
* only use REPEAT if the texture is po2.
*
* This property only affects WebGL.
*
* @static
* @constant
* @name WRAP_MODES
* @type {object}
* @property {number} CLAMP - The textures uvs are clamped
* @property {number} REPEAT - The texture uvs tile and repeat
* @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring
*/
export enum WRAP_MODES {
CLAMP = 33071,
REPEAT = 10497,
MIRRORED_REPEAT = 33648,
};
/**
* The gc modes that are supported by
*
* The {@link settings.GC_MODE} Garbage Collection mode for textures is AUTO
* If set to GC_MODE, the renderer will occasionally check textures usage. If they are not
* used for a specified period of time they will be removed from the GPU. They will of course
* be uploaded again when they are required. This is a silent behind the scenes process that
* should ensure that the GPU does not get filled up.
*
* Handy for mobile devices!
* This property only affects WebGL.
*
* @static
* @constant
* @name GC_MODES
* @type {object}
* @property {number} AUTO - Garbage collection will happen periodically automatically
* @property {number} MANUAL - Garbage collection will need to be called manually
*/
export enum GC_MODES {
AUTO = 0,
MANUAL,
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
export { default as Container } from "./Container"
export * from "./DisplayObject"
// export * from "./FloatDisplay"//淘宝上用不了,考虑怎么加
export { default as Sprite } from "./Sprite"
export * from "./Stage"
\ No newline at end of file
import { HashObject } from "../HashObject";
/**
* 事件类,引擎中一切事件的基类
* @class Event
* @extends AObject
* @public
* @since 1.0.0
*/
export class Event extends HashObject {
// public static IMAGE_LOADED: string = "onImageLoaded"
/**
* 舞台尺寸发生变化时触发
* @Event
* @property RESIZE
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static RESIZE: string = "onResize";
/**
* ScrollPage组件滑动到开始位置事件
* @property SCROLL_TO_HEAD
* @static
* @since 1.1.0
* @type {string}
*/
public static SCROLL_TO_HEAD: string = "onScrollToHead";
/**
* ScrollPage组件停止滑动事件
* @property SCROLL_STOP
* @static
* @since 1.1.0
* @type {string}
*/
public static SCROLL_STOP: string = "onScrollStop";
/**
* ScrollPage组件开始滑动事件
* @property SCROLL_START
* @static
* @since 1.1.0
* @type {string}
*/
public static SCROLL_START: string = "onScrollStart";
/**
* ScrollPage组件滑动到结束位置事件
* @property ON_SCROLL_TO_END
* @static
* @since 1.1.0
* @type {string}
*/
public static SCROLL_TO_END: string = "onScrollToEnd";
/**
* 舞台初始化完成后会触发的事件
* @property INIT_STAGE
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static INIT_STAGE: string = "onInitStage";
/**
* 显示对象加入到舞台事件
* @Event
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static ADDED_TO_STAGE: string = "onAddedToStage";
/**
* 显示对象从舞台移出事件
* @Event
* @property REMOVE_TO_STAGE
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static REMOVED_FROM_STAGE: string = "onRemovedFromStage";
/**
* 显示对象 循环帧事件
* @Event
* @property ENTER_FRAME
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static ENTER_FRAME: string = "onEnterFrame";
/**
* MovieClip 播放完成事件
* @Event
* @property END_FRAME
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static END_FRAME: string = "onEndFrame";
/**
* MovieClip 帧标签事件
* @Event
* @property CALL_FRAME
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static CALL_FRAME: string = "onCallFrame";
/**
* 完成事件
* @Event
* @property COMPLETE
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static COMPLETE: string = "onComplete";
/**
* 加载过程事件
* @Event
* @property PROGRESS
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static PROGRESS: string = "onProgress";
/**
* 出错事件
* @Event
* @property ERROR
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static ERROR: string = "onError";
/**
* 中断事件
* @Event
* @property ABORT
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static ABORT: string = "onAbort";
/**
* 开始事件
* @Event
* @property START
* @type {string}
* @static
* @public
* @since 1.0.0
*/
public static START: string = "onStart";
/**
* 定时器触发事件
* @property TIMER
* @static
* @since 1.0.9
* @public
* @type {string}
*/
public static TIMER: string = "onTimer";
/**
* 定时器完成事件
* @property TIMER_COMPLETE
* @since 1.0.9
* @static
* @public
* @type {string}
*/
public static TIMER_COMPLETE: string = "onTimerComplete";
/**
* 事件类型名
* @property type
* @type {string}
* @public
* @since 1.0.0
*/
public type: string = "";
/**
* 触发此事件的对象
* @property target
* @public
* @since 1.0.0
* @type {any}
*/
public target: any = null;
/**
* 随着事件一起附带的信息对象
* 所有需要随事件一起发送的信息都可以放在此对象中
* @property data
* @public
* @since 1.0.0
* @type {any}
* @default null
*/
public data: any = null;
/**
* @method Event
* @param {string} type 事件类型
* @public
* @since 1.0.0
*/
public constructor(type: string) {
super();
this._instanceType = "Event";
this.type = type;
}
/**
* 防止对事件流中当前节点的后续节点中的所有事件侦听器进行处理。
* @method stopPropagation
* @public
* @since 2.0.0
* @return {void}
*/
public stopPropagation(): void {
this._pd = true;
}
/**
* 是否阻止事件向下冒泡
* @property _pd
* @type {boolean}
* @private
* @since 1.0.0
*/
private _pd: boolean = false;
public destroy(): void {
let s = this;
s.target = null;
s.data = null;
}
/**
* 重围事件到初始状态方便重复利用
* @method reset
* @param {string} type
* @param target
* @since 2.0.0
* @return {void}
* @public
*/
public reset(type: string, target: any): void {
let s = this;
s.target = target;
s._pd = false;
s.type = type;
}
}
This diff is collapsed.
export class GDispatcher {
/**
* 事件回调池
*/
private static callbackPool: any = {};
/**
* 事件作用域池
*/
private static thisObjPool: any = {};
/**
*
* @param name 事件名
* @param callback 回调
* @param thisObj 作用域
*/
public static addEvent(name: string, callback, thisObj?: any): void {
if (!this.callbackPool[name]) {
this.callbackPool[name] = [];
this.thisObjPool[name] = [];
}
const index: number = this.callbackPool[name].indexOf(callback);
if (index != -1) {
this.callbackPool[name][index] = callback;
this.thisObjPool[name][index] = thisObj;
} else {
this.callbackPool[name].push(callback);
this.thisObjPool[name].push(thisObj);
}
}
/**
*
* @param name 事件名
* @param callback 回调
* @param thisObj 作用域
*/
public static removeEvent(name: string, callback, thisObj?: any): void {
if (this.callbackPool[name]) {
var len = this.callbackPool[name].length;
for (let i = len - 1; i >= 0; i--) {
if (this.callbackPool[name][i] === callback && this.thisObjPool[name][i] == thisObj) {
this.callbackPool[name].splice(i, 1);
this.thisObjPool[name].splice(i, 1);
}
}
// const index: number = this.callbackPool[name].indexOf(callback);
// if (index != -1) {
// this.callbackPool[name].splice(index, 1);
// this.thisObjPool[name].splice(index, 1);
// }
}
}
/**
* 派发事件
* @param name 事件名
* @param args 任意参数
*/
public static dispatchEvent(name: string, ...args): void {
const callbacks: Function[] = this.callbackPool[name];
const thisObjs: any = this.thisObjPool[name];
if (callbacks) {
let i = 0;
const len: number = callbacks.length;
for (i; i < len; i++) {
callbacks[i].apply(thisObjs[i], args);
}
}
}
}
\ No newline at end of file
import { Event } from "./Event";
import { DisplayObject } from "../display/DisplayObject";
/**
* 鼠标事件类,电脑端鼠标,移动设备端的触摸都使用此事件来监听
* @class MouseEvent
* @extends Event
* @public
* @since 1.0.0
*/
export class MouseEvent extends Event {
/**
* 鼠标或者手指按下事件
* @property MOUSE_DOWN
* @static
* @public
* @since 1.0.0
* @type {string}
*/
public static MOUSE_DOWN: string = "onMouseDown";
/**
* 鼠标或者手指抬起事件
* @property MOUSE_UP
* @static
* @public
* @since 1.0.0
* @type {string}
*/
public static MOUSE_UP: string = "onMouseUp";
/**
* 鼠标或者手指单击
* @property CLICK
* @static
* @public
* @since 1.0.0
* @type {string}
*/
public static CLICK: string = "onMouseClick";
/**
* 鼠标或者手指移动事件
* @property MOUSE_MOVE
* @static
* @public
* @since 1.0.0
* @type {string}
*/
public static MOUSE_MOVE: string = "onMouseMove";
/**
* 鼠标或者手指移入到显示对象上里触发的事件
* @property MOUSE_OVER
* @static
* @public
* @since 1.0.0
* @type {string}
*/
public static MOUSE_OVER: string = "onMouseOver";
/**
* 鼠标或者手指移出显示对象边界触发的事件
* @property MOUSE_OUT
* @static
* @public
* @since 1.0.0
* @type {string}
*/
public static MOUSE_OUT: string = "onMouseOut";
/**
* mouse或touch事件时rootDiv坐标x点
* @property clientX
* @public
* @since 1.0.0
* @type {number}
*/
public clientX: number = 0;
/**
* mouse或touch事件时rootDiv坐标y点
* @property clientY
* @public
* @since 1.0.0
* @type {number}
*/
public clientY: number = 0;
/**
* mouse或touch事件时全局坐标x点
* @property stageX
* @public
* @since 1.0.0
* @type {number}
*/
public stageX: number = 0;
/**
* mouse或touch事件时全局坐标y点
* @property stageY
* @public
* @since 1.0.0
* @type {number}
*/
public stageY: number = 0;
/**
* mouse或touch事件时本地坐标x点
* @property localX
* @public
* @since 1.0.0
* @type {number}
*/
public localX: number = 0;
/**
* mouse或touch事件时本地坐标y点
* @property localY
* @public
* @since 1.0.0
* @type {number}
*/
public localY: number = 0;
/**
* 触发事件的终点对象
* @property currentTarget
* @public
* @since 1.0.0
* @type{DisplayObject}
* @default null
*/
public currentTarget: DisplayObject = null;
/**
* 触摸或者鼠标事件的手指唯一标识
* @property identifier
* @type {number}
* @since 1.1.2
* @public
*/
public identifier: any = 0;
/**
* @method MouseEvent
* @public
* @since 1.0.0
* @param {string} type
*/
public constructor(type: string) {
super(type);
this._instanceType = "MouseEvent";
}
/**
* 事件后立即更新显示列表状态
* @method updateAfterEvent
* @since 1.0.9
* @public
*/
public updateAfterEvent() {
this.target.stage._cp = true;
}
public destroy(): void {
//清除相应的数据引用
let s = this;
s.currentTarget = null;
super.destroy();
}
}
\ No newline at end of file
export * from "./Event";
export * from "./EventDispatcher";
export * from "./GDispatcher";
export * from "./MouseEvent";
\ No newline at end of file
import extractUniformsFromSrc from './extractUniformsFromSrc';
import { BLEND_MODES } from '../const';
import { uid } from '../utils';
import RenderTarget from '../renderers/renderTarget/RenderTarget';
const SOURCE_KEY_MAP = {};
/**
* 基本就是一个着色器,暂时不考虑集成GLShader,还不晓得咋搞
*/
export default class Filter {
//顶点着色器
vertexSrc: string;
//片元着色器
fragmentSrc: string;
// state,新的用stat,以后处理
private _blendMode: BLEND_MODES;
get blendMode(): BLEND_MODES {
return this._blendMode;
}
/**
* 别用先
*/
set blendMode(value: BLEND_MODES) {
this._blendMode = value;
}
uniformData: any;
/**
* An object containing the current values of custom uniforms.
* @example <caption>Updating the value of a custom uniform</caption>
* filter.uniforms.time = performance.now();
*
* @member {object}
*/
uniforms: any;
glShaders: any;
glShaderKey: string;
/**
* The padding of the filter. Some filters require extra space to breath such as a blur.
* Increasing this will add extra width and height to the bounds of the object that the
* filter is applied to.
*
* @member {number}
*/
padding: number;
/**
* The resolution of the filter. Setting this to be lower will lower the quality but
* increase the performance of the filter.
*
* @member {number}
*/
resolution: number;
/**
* If enabled is true the filter is applied, if false it will not.
*
* @member {boolean}
*/
enabled: boolean;
/**
* If enabled, PixiJS will fit the filter area into boundaries for better performance.
* Switch it off if it does not work for specific shader.
*
* @member {boolean}
*/
autoFit: boolean;
/**
* @param {string} [vertexSrc] - The source of the vertex shader.
* @param {string} [fragmentSrc] - The source of the fragment shader.
* @param {object} [uniforms] - Custom uniforms to use to augment the built-in ones.
*/
constructor(vertexSrc?: string, fragmentSrc?: string, uniforms?: any) {
this.vertexSrc = vertexSrc || Filter.defaultVertexSrc;
this.fragmentSrc = fragmentSrc || Filter.defaultFragmentSrc;
this._blendMode = BLEND_MODES.NORMAL;
this.uniformData = uniforms || extractUniformsFromSrc(this.vertexSrc, this.fragmentSrc);
this.uniforms = {};
for (const i in this.uniformData) {
this.uniforms[i] = this.uniformData[i].value;
if (this.uniformData[i].type) {
this.uniformData[i].type = this.uniformData[i].type.toLowerCase();
}
}
// this is where we store shader references..
// TODO we could cache this!
this.glShaders = {};
// used for cacheing.. sure there is a better way!
if (!SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc]) {
SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc] = uid();
}
this.glShaderKey = SOURCE_KEY_MAP[this.vertexSrc + this.fragmentSrc];
this.padding = 4;
this.resolution = 1;
this.enabled = true;
this.autoFit = true;
}
/**
* Applies the filter
*
* @param {FilterManager} filterManager - The renderer to retrieve the filter from
* @param {RenderTarget} input - The input render target.
* @param {RenderTarget} output - The target to output to.
* @param {boolean} clear - Should the output be cleared before rendering to it
* @param {object} [currentState] - It's current state of filter.
* There are some useful properties in the currentState :
* target, filters, sourceFrame, destinationFrame, renderTarget, resolution
*/
apply(filterManager, input: RenderTarget, output: RenderTarget, clear: boolean) {
filterManager.applyFilter(this, input, output, clear);
}
/**
* The default vertex shader source
*
* @static
* @constant
*/
private static get defaultVertexSrc() {
return [
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'uniform mat3 projectionMatrix;',
'uniform mat3 filterMatrix;',
'varying vec2 vTextureCoord;',
'varying vec2 vFilterCoord;',
'void main(void){',
' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
' vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0) ).xy;',
' vTextureCoord = aTextureCoord ;',
'}',
].join('\n');
}
/**
* The default fragment shader source
*
* @static
* @constant
*/
private static get defaultFragmentSrc() {
return [
'varying vec2 vTextureCoord;',
'varying vec2 vFilterCoord;',
'uniform sampler2D uSampler;',
'uniform sampler2D filterSampler;',
'void main(void){',
' vec4 masky = texture2D(filterSampler, vFilterCoord);',
' vec4 sample = texture2D(uSampler, vTextureCoord);',
' vec4 color;',
' if(mod(vFilterCoord.x, 1.0) > 0.5)',
' {',
' color = vec4(1.0, 0.0, 0.0, 1.0);',
' }',
' else',
' {',
' color = vec4(0.0, 1.0, 0.0, 1.0);',
' }',
// ' gl_FragColor = vec4(mod(vFilterCoord.x, 1.5), vFilterCoord.y,0.0,1.0);',
' gl_FragColor = mix(sample, masky, 0.5);',
' gl_FragColor *= sample.a;',
'}',
].join('\n');
}
}
import Filter from "../Filter";
import { defaultVert } from "../defaultVerts";
const adjustmentFrag = [
"precision mediump float;",
'varying vec2 vTextureCoord;',
'uniform sampler2D uSampler;',
'uniform float gamma;',
'uniform float contrast;',
'uniform float saturation;',
'uniform float brightness;',
'uniform float red;',
'uniform float green;',
'uniform float blue;',
'uniform float alpha;',
'void main(void)',
'{',
'vec4 c = texture2D(uSampler, vTextureCoord);',
'if (c.a > 0.0) {',
'c.rgb /= c.a;',
'vec3 rgb = pow(c.rgb, vec3(1. / gamma));',
'rgb = mix(vec3(.5), mix(vec3(dot(vec3(.2125, .7154, .0721), rgb)), rgb, saturation), contrast);',
'rgb.r *= red;',
'rgb.g *= green;',
'rgb.b *= blue;',
'c.rgb = rgb * brightness;',
'c.rgb *= c.a;',
'}',
'gl_FragColor = c * alpha;',
'}'
].join("\n")
interface OptionsInt {
gamma?: number;
saturation?: number;
contrast?: number;
brightness?: number;
red?: number;
green?: number;
blue?: number;
alpha?: number;
}
/**
*
* @param {object} [options] - The optional parameters of the filter.
* @param {number} [options.gamma=1] - The amount of luminance
* @param {number} [options.saturation=1] - The amount of color saturation
* @param {number} [options.contrast=1] - The amount of contrast
* @param {number} [options.brightness=1] - The overall brightness
* @param {number} [options.red=1] - The multipled red channel
* @param {number} [options.green=1] - The multipled green channel
* @param {number} [options.blue=1] - The multipled blue channel
* @param {number} [options.alpha=1] - The overall alpha amount
*/
export class AdjustmentFilter extends Filter {
/**
* The amount of luminance
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
gamma: number = 1;
/**
* The amount of saturation
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
saturation: number = 1;
/**
* The amount of contrast
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
contrast: number = 1;
/**
* The amount of brightness
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
brightness: number = 1;
/**
* The amount of red channel
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
red: number = 1;
/**
* The amount of green channel
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
green: number = 1;
/**
* The amount of blue channel
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
blue: number = 1;
/**
* The amount of alpha channel
* @member {number}
* @memberof filters.AdjustmentFilter#
* @default 1
*/
alpha: number = 1;
constructor(options?: OptionsInt) {
super(defaultVert, adjustmentFrag);
if (typeof options == "object") {
Object.keys(options).forEach(e => { this[e] = options[e]; });
}
}
/**
* Override existing apply method in Filter
* @private
*/
apply(filterManager, input, output, clear) {
this.uniforms.gamma = Math.max(this.gamma, 0.0001);
this.uniforms.saturation = this.saturation;
this.uniforms.contrast = this.contrast;
this.uniforms.brightness = this.brightness;
this.uniforms.red = this.red;
this.uniforms.green = this.green;
this.uniforms.blue = this.blue;
this.uniforms.alpha = this.alpha;
filterManager.applyFilter(this, input, output, clear);
}
}
import { ExtractBrightnessFilter } from './ExtractBrightnessFilter';
import Filter from '../Filter';
import { defaultVert } from '../defaultVerts';
import { KawaseBlurFilter } from '../kawase-blur/KawaseBlurFilter';
import FilterManager from '../../renderers/managers/FilterManager';
const fragment = [
"precision mediump float;",
'uniform sampler2D uSampler;',
'varying vec2 vTextureCoord;',
'uniform sampler2D bloomTexture;',
'uniform float bloomScale;',
'uniform float brightness;',
'void main() {',
'vec4 color = texture2D(uSampler, vTextureCoord);',
'color.rgb *= brightness;',
'vec4 bloomColor = vec4(texture2D(bloomTexture, vTextureCoord).rgb, 0.0);',
'bloomColor.rgb *= bloomScale;',
'gl_FragColor = color + bloomColor;',
'}'
].join("\n")
interface OptionsInt {
threshold?: number;
bloomScale?: number;
brightness?: number;
blur?: number;
quality?: number;
kernels?: number;
pixelSize?: number;
resolution?: number;
}
/**
* The AdvancedBloomFilter applies a Bloom Effect to an object. Unlike the normal BloomFilter
* this had some advanced controls for adjusting the look of the bloom. Note: this filter
* is slower than normal BloomFilter.<br>
* ![original](../tools/screenshots/dist/original.png)![filter](../tools/screenshots/dist/advanced-bloom.png)
*
* @param {object|number} [options] - The optional parameters of advanced bloom filter.
* When options is a number , it will be `options.threshold`.
* @param {number} [options.threshold=0.5] - Defines how bright a color needs to be to affect bloom.
* @param {number} [options.bloomScale=1.0] - To adjust the strength of the bloom. Higher values is more intense brightness.
* @param {number} [options.brightness=1.0] - The brightness, lower value is more subtle brightness, higher value is blown-out.
* @param {number} [options.blur=8] - Sets the strength of the Blur properties simultaneously
* @param {number} [options.quality=4] - The quality of the Blur filter.
* @param {number[]} [options.kernels=null] - The kernels of the Blur filter.
* @param {number|number[]|Point} [options.pixelSize=1] - the pixelSize of the Blur filter.
* @param {number} [options.resolution=1] - The resolution of the Blur filter.
*/
export class AdvancedBloomFilter extends Filter {
private _extractFilter: ExtractBrightnessFilter
private _blurFilter: KawaseBlurFilter
bloomScale: number;
brightness: number;
private _resolution: number;
constructor(options?: OptionsInt) {
super(defaultVert, fragment);
if (typeof options === 'number') {
options = { threshold: options };
}
options = Object["assign"]({
threshold: 0.5,
bloomScale: 1.0,
brightness: 1.0,
kernels: null,
blur: 8,
quality: 4,
pixelSize: 1,
resolution: 1,
}, options);
/**
* To adjust the strength of the bloom. Higher values is more intense brightness.
*
* @member {number}
* @default 1.0
*/
this.bloomScale = options.bloomScale;
/**
* The brightness, lower value is more subtle brightness, higher value is blown-out.
*
* @member {number}
* @default 1.0
*/
this.brightness = options.brightness;
const { kernels, blur, quality, pixelSize, resolution } = options;
this._extractFilter = new ExtractBrightnessFilter(options.threshold);
this._extractFilter.resolution = resolution;
this._blurFilter = kernels ?
new KawaseBlurFilter(kernels) :
new KawaseBlurFilter(blur, quality);
this.pixelSize = pixelSize;
this.resolution = resolution;
}
/**
* Override existing apply method in Filter
* @private
*/
apply(filterManager: FilterManager, input, output, clear) {
const brightTarget = filterManager.getRenderTarget();
this._extractFilter.apply(filterManager, input, brightTarget, true);
const bloomTarget = filterManager.getRenderTarget();
this._blurFilter.apply(filterManager, brightTarget, bloomTarget, true);
this.uniforms.bloomScale = this.bloomScale;
this.uniforms.brightness = this.brightness;
this.uniforms.bloomTexture = bloomTarget;
filterManager.applyFilter(this, input, output, clear);
filterManager.returnRenderTarget(bloomTarget);
filterManager.returnRenderTarget(brightTarget);
}
/**
* The resolution of the filter.
*
* @member {number}
*/
get resolution() {
return this._resolution;
}
set resolution(value) {
this._resolution = value;
if (this._extractFilter) {
this._extractFilter.resolution = value;
}
if (this._blurFilter) {
this._blurFilter.resolution = value;
}
}
/**
* Defines how bright a color needs to be to affect bloom.
*
* @member {number}
* @default 0.5
*/
get threshold() {
return this._extractFilter.threshold;
}
set threshold(value) {
this._extractFilter.threshold = value;
}
/**
* Sets the kernels of the Blur Filter
*
* @member {number}
* @default 4
*/
get kernels() {
return this._blurFilter.kernels;
}
set kernels(value) {
this._blurFilter.kernels = value;
}
/**
* Sets the strength of the Blur properties simultaneously
*
* @member {number}
* @default 2
*/
get blur() {
return this._blurFilter.blur;
}
set blur(value) {
this._blurFilter.blur = value;
}
/**
* Sets the quality of the Blur Filter
*
* @member {number}
* @default 4
*/
get quality() {
return this._blurFilter.quality;
}
set quality(value) {
this._blurFilter.quality = value;
}
/**
* Sets the pixelSize of the Kawase Blur filter
*
* @member {number|number[]|Point}
* @default 1
*/
get pixelSize() {
return this._blurFilter.pixelSize;
}
set pixelSize(value) {
this._blurFilter.pixelSize = value;
}
}
import Filter from "../Filter";
import { defaultVert } from "../defaultVerts";
const extractBrightnessFrag = [
"precision mediump float;",
'uniform sampler2D uSampler;',
'varying vec2 vTextureCoord;',
'uniform float threshold;',
'void main() {',
'vec4 color = texture2D(uSampler, vTextureCoord);',
// A simple & fast algorithm for getting brightness.
// It's inaccuracy , but good enought for this feature.
'float _max = max(max(color.r, color.g), color.b);',
'float _min = min(min(color.r, color.g), color.b);',
'float brightness = (_max + _min) * 0.5;',
'if(brightness > threshold) {',
'gl_FragColor = color;',
'} else {',
'gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);',
'}',
'}'
].join("\n")
/**
* Internal filter for AdvancedBloomFilter to get brightness.
* @class
* @private
* @param {number} [threshold=0.5] Defines how bright a color needs to be extracted.
*/
export class ExtractBrightnessFilter extends Filter {
constructor(threshold = 0.5) {
super(defaultVert, extractBrightnessFrag);
this.threshold = threshold;
}
/**
* Defines how bright a color needs to be extracted.
*
* @member {number}
* @default 0.5
*/
get threshold() {
return this.uniforms.threshold;
}
set threshold(value) {
this.uniforms.threshold = value;
}
}
import Filter from '../Filter';
import { defaultVert } from '../defaultVerts';
const alphaFrag =
'precision mediump float;' +
'varying vec2 vTextureCoord;' +
'uniform sampler2D uSampler;' +
'uniform float uAlpha;' +
'void main(void){' +
'gl_FragColor = texture2D(uSampler, vTextureCoord) * uAlpha;' +
'}'
/**
* Simplest filter - applies alpha
*
* Use this instead of Container's alpha property to avoid visual layering of individual elements.
* AlphaFilter applies alpha evenly across the entire display object and any opaque elements it contains.
* If elements are not opaque, they will blend with each other anyway.
*
* Very handy if you want to use common features of all filters:
*
* 1. Assign a blendMode to this filter, blend all elements inside display object with background.
*
* 2. To use clipping in display coordinates, assign a filterArea to the same container that has this filter.
*
* @class
* @extends Filter
* @memberof filters
*/
export default class AlphaFilter extends Filter {
/**
* @param {number} [alpha=1] Amount of alpha from 0 to 1, where 0 is transparent
*/
constructor(alpha: number = 1.0) {
super(defaultVert, alphaFrag);
this.alpha = alpha;
this.glShaderKey = 'alpha';
}
/**
* Coefficient for alpha multiplication
*
* @member {number}
* @default 1
*/
get alpha() {
return this.uniforms.uAlpha;
}
set alpha(value: number) {
this.uniforms.uAlpha = value;
}
}
import BlurXFilter from './BlurXFilter';
import BlurYFilter from './BlurYFilter';
import Filter from '../Filter';
/**
* The BlurFilter applies a Gaussian blur to an object.
* The strength of the blur can be set for x- and y-axis separately.
*
* @class
* @extends Filter
* @memberof filters
*/
export default class BlurFilter extends Filter {
private blurXFilter: BlurXFilter;
private blurYFilter: BlurYFilter;
/**
* @param {number} strength - The strength of the blur filter.
* @param {number} quality - The quality of the blur filter.
* @param {number} resolution - The resolution of the blur filter.
* @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15.
*/
constructor(strength?, quality?, resolution?, kernelSize?) {
super();
this.blurXFilter = new BlurXFilter(strength, quality, resolution, kernelSize);
this.blurYFilter = new BlurYFilter(strength, quality, resolution, kernelSize);
this.padding = 0;
this.resolution = resolution || 1;
this.quality = quality || 4;
this.blur = strength || 8;
}
/**
* Applies the filter.
*
* @param {FilterManager} filterManager - The manager.
* @param {RenderTarget} input - The input target.
* @param {RenderTarget} output - The output target.
*/
apply(filterManager, input, output) {
const renderTarget = filterManager.getRenderTarget(true);
this.blurXFilter.apply(filterManager, input, renderTarget, true);
this.blurYFilter.apply(filterManager, renderTarget, output, false);
filterManager.returnRenderTarget(renderTarget);
}
/**
* Sets the strength of both the blurX and blurY properties simultaneously
*
* @member {number}
* @default 2
*/
get blur() {
return this.blurXFilter.blur;
}
set blur(value) {
this.blurXFilter.blur = this.blurYFilter.blur = value;
this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2;
}
/**
* Sets the number of passes for blur. More passes means higher quaility bluring.
*
* @member {number}
* @default 1
*/
get quality() {
return this.blurXFilter.quality;
}
set quality(value) {
this.blurXFilter.quality = this.blurYFilter.quality = value;
}
/**
* Sets the strength of the blurX property
*
* @member {number}
* @default 2
*/
get blurX() {
return this.blurXFilter.blur;
}
set blurX(value) {
this.blurXFilter.blur = value;
this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2;
}
/**
* Sets the strength of the blurY property
*
* @member {number}
* @default 2
*/
get blurY() {
return this.blurYFilter.blur;
}
set blurY(value) {
this.blurYFilter.blur = value;
this.padding = Math.max(Math.abs(this.blurXFilter.strength), Math.abs(this.blurYFilter.strength)) * 2;
}
/**
* Sets the blendmode of the filter
*
* @member {number}
* @default BLEND_MODES.NORMAL
*/
get blendMode() {
return this.blurYFilter.blendMode;
}
set blendMode(value) {
this.blurYFilter.blendMode = value;
}
}
import Filter from "../Filter";
import { defaultVert } from "../defaultVerts";
const blurFrag = [
"precision mediump float;",
"varying vec2 vTextureCoord;",
"uniform sampler2D uSampler;",
"const float resolution=1024.0;",
"uniform float radius;",//radius可为1.4
"uniform vec2 dir;",//若为x模糊,可传入(1.0,0.0)  y模糊  (0.0,1.0)
"void main() {",
//this will be our RGBA sum
"vec4 sum = vec4(0.0);",
//our original texcoord for this fragment
"vec2 tc = vTextureCoord;",
//the amount to blur, i.e. how far off center to sample from
//1.0 -> blur by one pixel
//2.0 -> blur by two pixels, etc.
"float blur = radius/resolution;",
//the direction of our blur
//(1.0, 0.0) -> x-axis blur
//(0.0, 1.0) -> y-axis blur
"float hstep = dir.x;",
"float vstep = dir.y;",
//apply blurring, using a 9-tap filter with predefined gaussian weights
"sum += texture2D(uSampler, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;",
"sum += texture2D(uSampler, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;",
"sum += texture2D(uSampler, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;",
"sum += texture2D(uSampler, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;",
"sum += texture2D(uSampler, vec2(tc.x, tc.y)) * 0.2270270270;",
"sum += texture2D(uSampler, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;",
"sum += texture2D(uSampler, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;",
"sum += texture2D(uSampler, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;",
"sum += texture2D(uSampler, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;",
"vec4 cc= texture2D(uSampler,vTextureCoord );",
//discard alpha for our simple demo, multiply by vertex color and return
"gl_FragColor =vec4(sum.rgb, cc.a);",
"}"
].join("\n")
//简单新能高点的模糊滤镜
export default class BlurFilterNew extends Filter {
private _blur: number;
get blur() {
return this._blur;
}
/**
* 系数0到1
*/
set blur(value) {
if (this._blur === value) return;
if (value > 1) value = 1;
if (value < 0) value = 0;
this._blur = value
this.uniforms.radius = value * 10;
}
/**
*
* @param blur 模糊系数 0到1
*/
constructor(blur: number = 0.5) {
super(defaultVert, blurFrag);
this.blur = blur;
//先固定吧
this.uniforms.dir = [1.0, 1.0];
}
}
\ No newline at end of file
import generateBlurVertSource from './generateBlurVertSource';
import generateBlurFragSource from './generateBlurFragSource';
import getMaxBlurKernelSize from './getMaxBlurKernelSize';
import Filter from '../Filter';
/**
* The BlurXFilter applies a horizontal Gaussian blur to an object.
*
* @class
* @extends Filter
* @memberof filters
*/
export default class BlurXFilter extends Filter {
strength: number
/**
* Sets the strength of both the blur.
*
* @member {number}
* @default 16
*/
get blur() {
return this.strength;
}
set blur(value) {
this.padding = Math.abs(value) * 2;
this.strength = value;
}
private _quality: number
private passes: number
/**
* Sets the quality of the blur by modifying the number of passes. More passes means higher
* quaility bluring but the lower the performance.
*
* @member {number}
* @default 4
*/
get quality() {
return this._quality;
}
set quality(value) {
this._quality = value;
this.passes = value;
}
private firstRun:boolean
/**
* @param {number} strength - The strength of the blur filter.
* @param {number} quality - The quality of the blur filter.
* @param {number} resolution - The resolution of the blur filter.
* @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15.
*/
constructor(strength?: number, quality?: number, resolution?: number, kernelSize?: number) {
kernelSize = kernelSize || 5;
const vertSrc = generateBlurVertSource(kernelSize, true);
const fragSrc = generateBlurFragSource(kernelSize);
super(
// vertex shader
vertSrc,
// fragment shader
fragSrc
);
this.resolution = resolution || 1;
this._quality = 0;
this.quality = quality || 4;
this.strength = strength || 8;
this.firstRun = true;
}
/**
* Applies the filter.
*
* @param {FilterManager} filterManager - The manager.
* @param {RenderTarget} input - The input target.
* @param {RenderTarget} output - The output target.
* @param {boolean} clear - Should the output be cleared before rendering?
*/
apply(filterManager, input, output, clear) {
if (this.firstRun) {
const gl = filterManager.renderer.gl;
const kernelSize = getMaxBlurKernelSize(gl);
this.vertexSrc = generateBlurVertSource(kernelSize, true);
this.fragmentSrc = generateBlurFragSource(kernelSize);
this.firstRun = false;
}
this.uniforms.strength = (1 / output.size.width) * (output.size.width / input.size.width);
// screen space!
this.uniforms.strength *= this.strength;
this.uniforms.strength /= this.passes;// / this.passes//Math.pow(1, this.passes);
if (this.passes === 1) {
filterManager.applyFilter(this, input, output, clear);
}
else {
const renderTarget = filterManager.getRenderTarget(true);
let flip = input;
let flop = renderTarget;
for (let i = 0; i < this.passes - 1; i++) {
filterManager.applyFilter(this, flip, flop, true);
const temp = flop;
flop = flip;
flip = temp;
}
filterManager.applyFilter(this, flip, output, clear);
filterManager.returnRenderTarget(renderTarget);
}
}
}
import generateBlurVertSource from './generateBlurVertSource';
import generateBlurFragSource from './generateBlurFragSource';
import getMaxBlurKernelSize from './getMaxBlurKernelSize';
import Filter from '../Filter';
import FilterManager from '../../renderers/managers/FilterManager';
/**
* The BlurYFilter applies a horizontal Gaussian blur to an object.
*
* @class
* @extends Filter
* @memberof filters
*/
export default class BlurYFilter extends Filter {
strength: number;
/**
* Sets the strength of both the blur.
*
* @member {number}
* @default 2
*/
get blur() {
return this.strength;
}
set blur(value) {
this.padding = Math.abs(value) * 2;
this.strength = value;
}
private _quality: number;
private passes: number;
/**
* Sets the quality of the blur by modifying the number of passes. More passes means higher
* quaility bluring but the lower the performance.
*
* @member {number}
* @default 4
*/
get quality() {
return this._quality;
}
set quality(value) {
this._quality = value;
this.passes = value;
}
private firstRun: boolean
/**
* @param {number} strength - The strength of the blur filter.
* @param {number} quality - The quality of the blur filter.
* @param {number} resolution - The resolution of the blur filter.
* @param {number} [kernelSize=5] - The kernelSize of the blur filter.Options: 5, 7, 9, 11, 13, 15.
*/
constructor(strength?, quality?, resolution?, kernelSize?) {
kernelSize = kernelSize || 5;
const vertSrc = generateBlurVertSource(kernelSize, false);
const fragSrc = generateBlurFragSource(kernelSize);
super(
// vertex shader
vertSrc,
// fragment shader
fragSrc
);
this.resolution = resolution || 1;
this._quality = 0;
this.quality = quality || 4;
this.strength = strength || 8;
this.firstRun = true;
}
/**
* Applies the filter.
*
* @param {FilterManager} filterManager - The manager.
* @param {RenderTarget} input - The input target.
* @param {RenderTarget} output - The output target.
* @param {boolean} clear - Should the output be cleared before rendering?
*/
apply(filterManager: FilterManager, input, output, clear) {
if (this.firstRun) {
const gl = filterManager.renderer.gl;
const kernelSize = getMaxBlurKernelSize(gl);
this.vertexSrc = generateBlurVertSource(kernelSize, false);
this.fragmentSrc = generateBlurFragSource(kernelSize);
this.firstRun = false;
}
this.uniforms.strength = (1 / output.size.height) * (output.size.height / input.size.height);
this.uniforms.strength *= this.strength;
this.uniforms.strength /= this.passes;
if (this.passes === 1) {
filterManager.applyFilter(this, input, output, clear);
}
else {
const renderTarget = filterManager.getRenderTarget(true);
let flip = input;
let flop = renderTarget;
for (let i = 0; i < this.passes - 1; i++) {
filterManager.applyFilter(this, flip, flop, true);
const temp = flop;
flop = flip;
flip = temp;
}
filterManager.applyFilter(this, flip, output, clear);
filterManager.returnRenderTarget(renderTarget);
}
}
}
const GAUSSIAN_VALUES = {
5: [0.153388, 0.221461, 0.250301],
7: [0.071303, 0.131514, 0.189879, 0.214607],
9: [0.028532, 0.067234, 0.124009, 0.179044, 0.20236],
11: [0.0093, 0.028002, 0.065984, 0.121703, 0.175713, 0.198596],
13: [0.002406, 0.009255, 0.027867, 0.065666, 0.121117, 0.174868, 0.197641],
15: [0.000489, 0.002403, 0.009246, 0.02784, 0.065602, 0.120999, 0.174697, 0.197448],
};
const fragTemplate = [
'precision mediump float;',
'varying vec2 vBlurTexCoords[%size%];',
'uniform sampler2D uSampler;',
'void main(void)',
'{',
' gl_FragColor = vec4(0.0);',
' %blur%',
'}',
].join('\n');
export default function generateFragBlurSource(kernelSize) {
const kernel = GAUSSIAN_VALUES[kernelSize];
const halfLength = kernel.length;
let fragSource = fragTemplate;
let blurLoop = '';
const template = 'gl_FragColor += texture2D(uSampler, vBlurTexCoords[%index%]) * %value%;';
let value;
for (let i = 0; i < kernelSize; i++) {
let blur = template.replace('%index%', i + "");
value = i;
if (i >= halfLength) {
value = kernelSize - i - 1;
}
blur = blur.replace('%value%', kernel[value]);
blurLoop += blur;
blurLoop += '\n';
}
fragSource = fragSource.replace('%blur%', blurLoop);
fragSource = fragSource.replace('%size%', kernelSize);
return fragSource;
}
This diff is collapsed.
export default function getMaxBlurKernelSize(gl) {
const maxVaryings = (gl.getParameter(gl.MAX_VARYING_VECTORS));
let kernelSize = 15;
while (kernelSize > maxVaryings) {
kernelSize -= 2;
}
return kernelSize;
}
This diff is collapsed.
//默认下顶点着色器都用highp float精度,片元着色器用mediump float
export const defaultVert =
"precision highp float;" +
"attribute vec2 aVertexPosition;" +
"attribute vec2 aTextureCoord;" +
"uniform mat3 projectionMatrix;" +
"varying vec2 vTextureCoord;" +
"void main(void){" +
"gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);" +
"vTextureCoord = aTextureCoord;" +
"}"
export const defaultFilterMatrix =
"precision highp float;" +
"attribute vec2 aVertexPosition;" +
"attribute vec2 aTextureCoord;" +
"uniform mat3 projectionMatrix;" +
"uniform mat3 filterMatrix;" +
"varying vec2 vTextureCoord;" +
"varying vec2 vFilterCoord;" +
"void main(void){" +
"gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);" +
"vFilterCoord = ( filterMatrix * vec3( aTextureCoord, 1.0) ).xy;" +
"vTextureCoord = aTextureCoord;" +
"}"
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
export * from "./Loader"
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment