diff --git a/README.md b/README.md index 8725294f..2f9ca439 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This project is maintained by [RedCamel](mailto:webseon@gmail.com) ### Release Notes ### - [Releases](https://github.com/redcamel/RedGL2/releases) +- [Release Note V6.0](https://github.com/redcamel/RedGL2/releases/tag/Master_V6.0) - [Release Note V5.0](https://github.com/redcamel/RedGL2/releases/tag/Master_V5.0) - [Release Note V4.0](https://github.com/redcamel/RedGL2/releases/tag/Master_V4.0) - [Release Note V3.0](https://github.com/redcamel/RedGL2/releases/tag/Master_V3.0) diff --git a/example/baseTestUI.js b/example/baseTestUI.js index 629c384d..36a05fcb 100644 --- a/example/baseTestUI.js +++ b/example/baseTestUI.js @@ -1,8 +1,9 @@ /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.7.5 11:56 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:52:14 + * */ var baseTestUI = function (redGL, width) { @@ -252,6 +253,22 @@ baseTestUI.exampleList = [ { key: 'object3D pivotTest', href: 'object3D/pivotTest.html' + }, + { + key: 'object3D pivotTest 2D Mode', + href: 'object3D/pivotTest_2dMode.html' + }, + { + key: 'object3D outline(2D mode)', + href: 'object3D/object3D_outline.html' + }, + { + key: 'object3D outline(3D mode)', + href: 'object3D/object3D_outline_3dMode.html' + }, + { + key: 'object3D outline skin', + href: 'object3D/object3D_outline_skin.html' } ] }, @@ -320,6 +337,28 @@ baseTestUI.exampleList = [ } ] }, + { + key: 'Mesh Filter', + list: [ + { + key: 'filterTest(2D Mode)', + href: 'filter/filterTest_2dMode.html' + }, + { + key: 'filterTest(3D Mode)', + href: 'filter/filterTest_3dMode.html' + }, + { + key: 'filters', + href: 'filter/RedFilters.html' + }, + { + key: 'Mesh filter + PostEffect', + href: 'filter/filterWithPostEffect.html' + } + + ] + }, { key: 'Texture', list: [ diff --git a/example/filter/RedFilters.html b/example/filter/RedFilters.html new file mode 100644 index 00000000..a6aea041 --- /dev/null +++ b/example/filter/RedFilters.html @@ -0,0 +1,203 @@ + + + + + + + + + RedGL - Filters + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/filter/filterTest_2dMode.html b/example/filter/filterTest_2dMode.html new file mode 100644 index 00000000..dd046430 --- /dev/null +++ b/example/filter/filterTest_2dMode.html @@ -0,0 +1,176 @@ + + + + + + + + + RedGL Example - Mesh filter Test (2D Mode) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/filter/filterTest_3dMode.html b/example/filter/filterTest_3dMode.html new file mode 100644 index 00000000..c87240ff --- /dev/null +++ b/example/filter/filterTest_3dMode.html @@ -0,0 +1,181 @@ + + + + + + + + + RedGL Example - Mesh filter Test (3D Mode) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/filter/filterWithPostEffect.html b/example/filter/filterWithPostEffect.html new file mode 100644 index 00000000..5cb2809d --- /dev/null +++ b/example/filter/filterWithPostEffect.html @@ -0,0 +1,178 @@ + + + + + + + + + RedGL Example - Mesh filter with PostEffect + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/object3D/object3D_outline.html b/example/object3D/object3D_outline.html new file mode 100644 index 00000000..85266c2c --- /dev/null +++ b/example/object3D/object3D_outline.html @@ -0,0 +1,206 @@ + + + + + + + + + RedGL Example - outline property(2D mode) + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/object3D/object3D_outline_3dMode.html b/example/object3D/object3D_outline_3dMode.html new file mode 100644 index 00000000..13baf778 --- /dev/null +++ b/example/object3D/object3D_outline_3dMode.html @@ -0,0 +1,196 @@ + + + + + + + + + RedGL Example - outline property(3D mode) + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/object3D/object3D_outline_skin.html b/example/object3D/object3D_outline_skin.html new file mode 100644 index 00000000..cbf2af7a --- /dev/null +++ b/example/object3D/object3D_outline_skin.html @@ -0,0 +1,159 @@ + + + + + + + + + RedGL Example - object3D_outline_skin + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/object3D/pivotTest.html b/example/object3D/pivotTest.html index 20c5e12b..4842e1c6 100644 --- a/example/object3D/pivotTest.html +++ b/example/object3D/pivotTest.html @@ -1,8 +1,9 @@ @@ -21,7 +22,7 @@ - + @@ -50,19 +51,22 @@ tWorld.addView(tView); // 그리드 설정 tScene['grid'] = RedGrid(redGL); + // tScene['axis'] = RedAxis(redGL); // 렌더시작 tRenderer.start(redGL, function (time) { var i = tScene.children.length var tMesh while (i--) { tMesh = tScene.children[i] - if (tMesh != tPivotPoint) { + if (tMesh != tPivotPoint1) { // tMesh.rotationX += 1 // tMesh.rotationY += 1 tMesh.rotationZ += 1 } + } + tMesh2.rotationZ +=0.5 }); // 렌더 디버거 활성화 @@ -97,35 +101,71 @@ )); tMesh.useCullFace = false tMesh.pivot = [0, 0, 0] - tMesh.scaleX = tMesh.scaleY = tMesh.scaleZ = 3 + tMesh.scaleX = tMesh.scaleY = tMesh.scaleZ = 10 tScene.addChild(tMesh); - var tPivotPoint = RedMesh(this, RedSphere(this, 0.2), RedColorMaterial(this, '#00ff00')); - tPivotPoint.useCullFace = false - tScene.addChild(tPivotPoint); - testUI(this, tScene, tMesh, tPivotPoint); + var tPivotPoint1 = RedMesh(this, RedSphere(this, 0.2), RedColorMaterial(this, '#00ff00')); + tPivotPoint1.useCullFace = false + tMesh.addChild(tPivotPoint1); + /// + var tMesh2 = RedMesh(this, tGeometry, RedBitmapMaterial( + this, + RedBitmapTexture(this, assetPath + 'UV_Grid_Sm.jpg') + )); + tMesh2.useCullFace = false + tMesh2.pivot = [0, 0, 0] + tMesh2.scaleX = tMesh2.scaleY = tMesh2.scaleZ = 1 + tMesh2.x = 2 + tMesh.addChild(tMesh2); + var tPivotPoint2 = RedMesh(this, RedSphere(this, 0.2), RedColorMaterial(this, '#ff0000')); + tPivotPoint2.useCullFace = false + tMesh2.addChild(tPivotPoint2); + + testUI(this, tScene, tMesh,tMesh2, tPivotPoint1,tPivotPoint2); } else { console.log('초기화 실패!'); } }); - testUI = function (redGL, tScene, tMesh, tPivotPoint) { + testUI = function (redGL, tScene, tMesh, tMesh2,tPivotPoint1,tPivotPoint2) { var gui = new baseTestUI(redGL); gui.initRedGL(); var test = { pivotX: 0, pivotY: 0, pivotZ: 0 - + } + var test2 = { + pivotX: 0, + pivotY: 0, + pivotZ: 0 } var tFolder = gui['gui'].addFolder('RedMesh') - tFolder.open() + tFolder.open(); + 'x,y,z'.split(',').forEach(function (tKey) { + tFolder.add(tMesh, tKey, -10, 10, 0.01).onChange(function (v) { + tMesh[tKey] = v + }) + + }); 'pivotX,pivotY,pivotZ'.split(',').forEach(function (tKey) { - tFolder.add(test, tKey, -10, 10, 0.01).onChange(function (v) { + tFolder.add(test, tKey, -1, 1, 0.01).onChange(function (v) { tMesh[tKey] = v - tPivotPoint.x = test['pivotX'] - tPivotPoint.y = test['pivotY'] - tPivotPoint.z = test['pivotZ'] + tPivotPoint1.x = test['pivotX'] + tPivotPoint1.y = test['pivotY'] + tPivotPoint1.z = test['pivotZ'] + }) + + }); + var tFolder = gui['gui'].addFolder('RedMesh2') + tFolder.open() + 'pivotX,pivotY,pivotZ'.split(',').forEach(function (tKey) { + tFolder.add(test2, tKey, -1, 1, 0.01).onChange(function (v) { + tMesh2[tKey] = v + tPivotPoint2.x = test2['pivotX'] + tPivotPoint2.y = test2['pivotY'] + tPivotPoint2.z = test2['pivotZ'] }) }); + } diff --git a/example/object3D/pivotTest_2dMode.html b/example/object3D/pivotTest_2dMode.html new file mode 100644 index 00000000..d7a3dd0b --- /dev/null +++ b/example/object3D/pivotTest_2dMode.html @@ -0,0 +1,170 @@ + + + + + + + + + RedGL Example - PivotTest 2D Mode + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/thumb/Mesh filter + PostEffect.png b/example/thumb/Mesh filter + PostEffect.png new file mode 100644 index 00000000..01b9879c Binary files /dev/null and b/example/thumb/Mesh filter + PostEffect.png differ diff --git a/example/thumb/filterTest(2D Mode).png b/example/thumb/filterTest(2D Mode).png new file mode 100644 index 00000000..d3e7d4fa Binary files /dev/null and b/example/thumb/filterTest(2D Mode).png differ diff --git a/example/thumb/filterTest(3D Mode).png b/example/thumb/filterTest(3D Mode).png new file mode 100644 index 00000000..9111b1c0 Binary files /dev/null and b/example/thumb/filterTest(3D Mode).png differ diff --git a/example/thumb/filters.png b/example/thumb/filters.png new file mode 100644 index 00000000..6823129f Binary files /dev/null and b/example/thumb/filters.png differ diff --git a/example/thumb/object3D outline skin.png b/example/thumb/object3D outline skin.png new file mode 100644 index 00000000..fefa2eae Binary files /dev/null and b/example/thumb/object3D outline skin.png differ diff --git a/example/thumb/object3D outline(2D mode).png b/example/thumb/object3D outline(2D mode).png new file mode 100644 index 00000000..ab856c22 Binary files /dev/null and b/example/thumb/object3D outline(2D mode).png differ diff --git a/example/thumb/object3D outline(3D mode).png b/example/thumb/object3D outline(3D mode).png new file mode 100644 index 00000000..ab856c22 Binary files /dev/null and b/example/thumb/object3D outline(3D mode).png differ diff --git a/example/thumb/object3D pivotTest 2d Mode.png b/example/thumb/object3D pivotTest 2d Mode.png new file mode 100644 index 00000000..1a8a366e Binary files /dev/null and b/example/thumb/object3D pivotTest 2d Mode.png differ diff --git a/gulpfile.js b/gulpfile.js index 63cce42c..aa89663b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,8 +1,9 @@ /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.6.20 15:0 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * */ var gulp = require('gulp'); @@ -22,7 +23,8 @@ var name = "RedGL"; var transformString = function (s) { var reg = /\/\*DOC\:[\s\S]+?\:\DOC\*\//g; var list = s.match(reg) - var dedent = function (callSite,...args) + var dedent = function (callSite,...args +) { var tList = callSite.trim().split('\n') var tList2 = [] @@ -170,6 +172,8 @@ gulp.task('combine-js', function () { "src/material/system/RedColorPointCloudMaterial.js", "src/material/system/RedPBRMaterial_system.js", "src/material/system/RedTextMaterial.js", + "src/material/system/RedOutlineMaterial.js", + "src/material/system/RedOutlinePlaneMaterial.js", // "src/light/RedAmbientLight.js", "src/light/RedDirectionalLight.js", @@ -255,6 +259,29 @@ gulp.task('combine-js', function () { "src/postEffect/RedPostEffect_Vignetting.js", "src/postEffect/RedPostEffect_Vignetting.js", "src/postEffect/antialiasing/RedPostEffect_FXAA.js", + + "src/filter/RedFilterFrameBuffer.js", + "src/filter/RedFilterEffectManager.js", + "src/base/RedBaseFilter.js", + "src/material/system/RedFilterMaterial.js", + + "src/filter/adjustments/RedFilter_BrightnessContrast.js", + "src/filter/adjustments/RedFilter_Gray.js", + "src/filter/adjustments/RedFilter_Invert.js", + "src/filter/adjustments/RedFilter_Threshold.js", + "src/filter/adjustments/RedFilter_HueSaturation.js", + "src/filter/blur/RedFilter_Blur.js", + "src/filter/blur/RedFilter_BlurX.js", + "src/filter/blur/RedFilter_BlurY.js", + "src/filter/blur/RedFilter_GaussianBlur.js", + "src/filter/pixelate/RedFilter_Pixelize.js", + "src/filter/pixelate/RedFilter_HalfTone.js", + "src/filter/bloom/RedFilter_Bloom.js", + "src/filter/bloom/RedFilter_BloomThreshold.js", + "src/filter/RedFilter_Film.js", + "src/filter/RedFilter_Convolution.js", + + // "src/launcher/RedGLOffScreen.js" ]) diff --git a/package-lock.json b/package-lock.json index 6ee54d8b..37650bc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1189,8 +1189,8 @@ "dev": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.3.6" } }, "balanced-match": { @@ -1203,7 +1203,7 @@ "bundled": true, "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -1240,7 +1240,7 @@ "dev": true, "optional": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.1" } }, "deep-extend": { @@ -1267,7 +1267,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.3.5" } }, "fs.realpath": { @@ -1282,14 +1282,14 @@ "dev": true, "optional": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.3" } }, "glob": { @@ -1298,12 +1298,12 @@ "dev": true, "optional": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "has-unicode": { @@ -1318,7 +1318,7 @@ "dev": true, "optional": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "ignore-walk": { @@ -1327,7 +1327,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "3.0.4" } }, "inflight": { @@ -1336,8 +1336,8 @@ "dev": true, "optional": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -1356,7 +1356,7 @@ "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "isarray": { @@ -1370,7 +1370,7 @@ "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -1383,8 +1383,8 @@ "bundled": true, "dev": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "safe-buffer": "5.1.2", + "yallist": "3.0.3" } }, "minizlib": { @@ -1393,7 +1393,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.3.5" } }, "mkdirp": { @@ -1416,9 +1416,9 @@ "dev": true, "optional": true, "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" + "debug": "4.1.1", + "iconv-lite": "0.4.24", + "sax": "1.2.4" } }, "node-pre-gyp": { @@ -1427,16 +1427,16 @@ "dev": true, "optional": true, "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" + "detect-libc": "1.0.3", + "mkdirp": "0.5.1", + "needle": "2.3.0", + "nopt": "4.0.1", + "npm-packlist": "1.4.1", + "npmlog": "4.1.2", + "rc": "1.2.8", + "rimraf": "2.6.3", + "semver": "5.7.0", + "tar": "4.4.8" } }, "nopt": { @@ -1445,8 +1445,8 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1.1.1", + "osenv": "0.1.5" } }, "npm-bundled": { @@ -1461,8 +1461,8 @@ "dev": true, "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.6" } }, "npmlog": { @@ -1471,10 +1471,10 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "1.1.5", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" } }, "number-is-nan": { @@ -1493,7 +1493,7 @@ "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-homedir": { @@ -1514,8 +1514,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "path-is-absolute": { @@ -1536,10 +1536,10 @@ "dev": true, "optional": true, "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "deep-extend": "0.6.0", + "ini": "1.3.5", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" }, "dependencies": { "minimist": { @@ -1556,13 +1556,13 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "rimraf": { @@ -1571,7 +1571,7 @@ "dev": true, "optional": true, "requires": { - "glob": "^7.1.3" + "glob": "7.1.3" } }, "safe-buffer": { @@ -1614,9 +1614,9 @@ "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "string_decoder": { @@ -1625,7 +1625,7 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } }, "strip-ansi": { @@ -1633,7 +1633,7 @@ "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-json-comments": { @@ -1648,13 +1648,13 @@ "dev": true, "optional": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "chownr": "1.1.1", + "fs-minipass": "1.2.5", + "minipass": "2.3.5", + "minizlib": "1.2.1", + "mkdirp": "0.5.1", + "safe-buffer": "5.1.2", + "yallist": "3.0.3" } }, "util-deprecate": { @@ -1669,7 +1669,7 @@ "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "1.0.2" } }, "wrappy": { @@ -1932,7 +1932,7 @@ "integrity": "sha512-LG/ZmdloodRFUS6sSClzLNZ1PDldNPS1UZSjwgr2QibM/JRlQWMf2uacXeylCzamfpsrwx01cb24I3y/TVwOnA==", "dev": true, "requires": { - "lodash": "4.17.11", + "lodash": "4.17.15", "readable-stream": "2.3.6", "through2": "2.0.5" } @@ -2346,9 +2346,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "make-iterator": { diff --git a/package.json b/package.json index 662898f9..376c781e 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ }, "dependencies": {}, "devDependencies": { + "lodash": ">=4.17.13", "strip-comments": "^1.0.2", "date-utils": "^1.2.21", "gulp": "^4.0.0", diff --git a/redDoc/docs/base/RedBaseFilter.json b/redDoc/docs/base/RedBaseFilter.json new file mode 100644 index 00000000..9403efd9 --- /dev/null +++ b/redDoc/docs/base/RedBaseFilter.json @@ -0,0 +1,23 @@ +[ + { + "title": "_process", + "code": "PROPERTY", + "description": "\n\t\t해당메쉬 필터 처리전 전처리과정이 필요할 경우 사용.\n\t", + "return": "void" + }, + { + "constructorYn": true, + "title": "RedBaseFilter", + "description": "\n\t 메쉬 필터 정의 사용되는 기저층\n ", + "extends": [ + "RedBaseMaterial" + ], + "return": "RedBaseFilter Instance" + }, + { + "title": "updateTexture", + "code": "METHOD", + "description": "\n\t\t메쉬 필터 정의시 반드시 재정의 되어야함.\n\t\t메쉬 필터 내부에서 사용되는 텍스쳐를 업데이트함.\n\t", + "return": "void" + } +] \ No newline at end of file diff --git a/redDoc/docs/base/RedBaseObject3D.json b/redDoc/docs/base/RedBaseObject3D.json index 0b0ebcf1..abfd4bfb 100644 --- a/redDoc/docs/base/RedBaseObject3D.json +++ b/redDoc/docs/base/RedBaseObject3D.json @@ -1,4 +1,17 @@ [ + { + "title": "addFilter", + "code": "METHOD", + "description": "\n\t\tfilter 추가\n\t", + "params": { + "filter": [ + { + "type": "RedBaseFilter Instance" + } + ] + }, + "return": "void" + }, { "title": "addLOD", "code": "METHOD", @@ -212,6 +225,24 @@ "description": "\n 계산된 노멀 메트릭스\n normalMatrix 렌더링시 자동계산\n", "return": "mat4" }, + { + "code": "PROPERTY", + "title": "outlineAlpha", + "description": "\n 기본값 : 1\n 최소값 : 0\n 최대값 : 1\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "outlineColor", + "description": "기본값 : #ff0000", + "return": "hex" + }, + { + "code": "PROPERTY", + "title": "outlineThickness", + "description": "\n\t기본값 : 0\n\t최소값 : 0\n ", + "return": "Number" + }, { "code": "PROPERTY", "title": "pivotX", @@ -260,6 +291,25 @@ "example": "\n var testMesh = function (redGL) {\n\t var tGL;\n\t tGL = redGL.gl;\n\t RedBaseObject3D['build'].call(this, tGL)\n }\n ", "return": "void" }, + { + "title": "removeAllFilter", + "code": "METHOD", + "description": "\n\t\t모든 filter 제거\n\t", + "return": "void" + }, + { + "title": "removeFilter", + "code": "METHOD", + "description": "\n\t\tfilter 제거\n\t", + "params": { + "filter": [ + { + "type": "RedBaseFilter Instance" + } + ] + }, + "return": "void" + }, { "title": "removeLOD", "code": "METHOD", diff --git a/redDoc/docs/filter/RedFilterEffectManager.json b/redDoc/docs/filter/RedFilterEffectManager.json new file mode 100644 index 00000000..3875d9f6 --- /dev/null +++ b/redDoc/docs/filter/RedFilterEffectManager.json @@ -0,0 +1,54 @@ +[ + { + "title": "bind", + "code": "METHOD", + "description": "\n\t\t프레임 버퍼 바인딩.\n\t\t렌더러에서 자동호출됨.\n\t", + "params": { + "gl": [ + { + "type": "WebGL Context" + } + ] + }, + "return": "void" + }, + { + "title": "filterList", + "code": "PROPERTY", + "description": "\n\t\t이펙트 리스트\n\t", + "return": "Array" + }, + { + "title": "frameBuffer", + "code": "PROPERTY", + "description": "\n\t\t이펙트 렌더링시 사용될 프레임버퍼\n\t", + "return": "RedFrameBuffer Instance" + }, + { + "constructorYn": true, + "title": "RedFilterEffectManager", + "description": "\n\t RedFilterEffectManager Instance 생성.\n\t RedScene 생성시 내부속성으로 자동생성됨.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "demo": "../example/RedFilter.html", + "return": "RedFilterEffectManager Instance" + }, + { + "title": "unbind", + "code": "METHOD", + "description": "\n\t\t프레임 버퍼 언바인딩.\n\t\t렌더러에서 자동호출됨.\n\t", + "params": { + "gl": [ + { + "type": "WebGL Context" + } + ] + }, + "return": "void" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/RedFilterFrameBuffer.json b/redDoc/docs/filter/RedFilterFrameBuffer.json new file mode 100644 index 00000000..ee0e3bfc --- /dev/null +++ b/redDoc/docs/filter/RedFilterFrameBuffer.json @@ -0,0 +1,66 @@ +[ + { + "code": "METHOD", + "title": "bind", + "description": "소유하고있는 webglFrameBuffer, webglTexture, webglRenderBuffer를 binding.", + "params": { + "gl": [ + { + "type": "WebGL Context" + } + ] + }, + "return": "void" + }, + { + "code": "PROPERTY", + "title": "height", + "description": "\n\t기본값 : 1080 or 하드웨어 최대값\n", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilterFrameBuffer", + "description": "\n\t RedFilterFrameBuffer Instance 생성자.\n ", + "params": { + "redGL": [ + { + "type": "RedGL Instance" + } + ], + "width": [ + { + "type": "Number" + }, + "기기허용 최대값보다 큰경우 기기허용 최대값으로 설정됨" + ], + "height": [ + { + "type": "Number" + }, + "기기허용 최대값보다 큰경우 기기허용 최대값으로 설정됨" + ] + }, + "example": "\n\t RedFilterFrameBuffer( RedGL Instance );\n ", + "return": "RedGeometry Instance" + }, + { + "code": "METHOD", + "title": "unbind", + "description": "소유하고있는 webglFrameBuffer, webglTexture, webglRenderBuffer를 unbinding.", + "params": { + "gl": [ + { + "type": "WebGL Context" + } + ] + }, + "return": "void" + }, + { + "code": "PROPERTY", + "title": "width", + "description": "\n\t기본값 : 1920 or 하드웨어 최대값\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/RedFilter_Film.json b/redDoc/docs/filter/RedFilter_Film.json new file mode 100644 index 00000000..14931b2e --- /dev/null +++ b/redDoc/docs/filter/RedFilter_Film.json @@ -0,0 +1,45 @@ +[ + { + "code": "PROPERTY", + "title": "grayMode", + "description": "\n\t 그레이모드\n\t 기본값 : false\n ", + "return": "Boolean" + }, + { + "code": "PROPERTY", + "title": "noiseIntensity", + "description": "\n\t 노이즈강도\n\t 기본값 : 0.5\n\t min : 0\n ", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilter_Film", + "description": "\n\t Film 이펙트\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/RedFilter_Film.html", + "example": "\n var effect;\n effect = RedFilter_Film(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Film Instance" + }, + { + "code": "PROPERTY", + "title": "scanlineCount", + "description": "\n\t 스캔라인 수\n\t 기본값 : 2048\n\t min : 0\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "scanlineIntensity", + "description": "\n\t 스캔라인강도\n\t 기본값 : 0.5\n\t min : 0\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/adjustments/RedFilter_Gray.json b/redDoc/docs/filter/adjustments/RedFilter_Gray.json new file mode 100644 index 00000000..01b85e87 --- /dev/null +++ b/redDoc/docs/filter/adjustments/RedFilter_Gray.json @@ -0,0 +1,21 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_Gray", + "description": "\n\t Gray 이펙트\n\t postEffectManager.addEffect( effect Instance ) 로 추가.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/adjustments/RedFilter_Gray.html", + "example": "\n\tvar effect;\n\teffect = RedFilter_Gray(RedGL Instance); // 포스트이펙트 생성\n\t// postEffectManager는 RedView 생성시 자동생성됨.\n\t(RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Gray Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/adjustments/RedFilter_HueSaturation.json b/redDoc/docs/filter/adjustments/RedFilter_HueSaturation.json new file mode 100644 index 00000000..b67a3159 --- /dev/null +++ b/redDoc/docs/filter/adjustments/RedFilter_HueSaturation.json @@ -0,0 +1,33 @@ +[ + { + "code": "PROPERTY", + "title": "hue", + "description": "\n\t 색조\n\t 기본값 : 0\n\t min: -180\n\t max: 180\n ", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilter_HueSaturation", + "description": "\n\t HueSaturation 이펙트\n\t postEffectManager.addEffect( effect Instance ) 로 추가.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/adjustments/RedFilter_HueSaturation.html", + "example": "\n var effect;\n effect = RedFilter_HueSaturation(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_HueSaturation Instance" + }, + { + "code": "PROPERTY", + "title": "saturation", + "description": "\n\t 채도\n\t 기본값 : 0\n\t min: -100\n\t max: 100\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/adjustments/RedFilter_Invert.json b/redDoc/docs/filter/adjustments/RedFilter_Invert.json new file mode 100644 index 00000000..5e3a293f --- /dev/null +++ b/redDoc/docs/filter/adjustments/RedFilter_Invert.json @@ -0,0 +1,21 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_Invert", + "description": "\n\t Invert 이펙트\n\t postEffectManager.addEffect( effect Instance ) 로 추가.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/adjustments/RedFilter_Invert.html", + "example": "\n\tvar effect;\n\teffect = RedFilter_Invert(RedGL Instance); // 포스트이펙트 생성\n\t// postEffectManager는 RedView 생성시 자동생성됨.\n\t(RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Invert Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/adjustments/RedFilter_Threshold.json b/redDoc/docs/filter/adjustments/RedFilter_Threshold.json new file mode 100644 index 00000000..ce555347 --- /dev/null +++ b/redDoc/docs/filter/adjustments/RedFilter_Threshold.json @@ -0,0 +1,27 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_Threshold", + "description": "\n\t Threshold 이펙트\n\t postEffectManager.addEffect( effect Instance ) 로 추가.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/adjustments/RedFilter_Threshold.html", + "example": "\n var effect;\n effect = RedFilter_Threshold(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Threshold Instance" + }, + { + "code": "PROPERTY", + "title": "threshold", + "description": "\n\t 최소 유효값\n\t 기본값 : 128\n\t min: 1\n\t max: 255\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/bloom/RedFilter_Bloom.json b/redDoc/docs/filter/bloom/RedFilter_Bloom.json new file mode 100644 index 00000000..ed378f2a --- /dev/null +++ b/redDoc/docs/filter/bloom/RedFilter_Bloom.json @@ -0,0 +1,45 @@ +[ + { + "code": "PROPERTY", + "title": "bloomStrength", + "description": "\n\t 블룸 강도\n\t 기본값 : 1.2\n\t min : 0\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "blur", + "description": "\n\t blur 정도.\n\t 기본값 : 20\n\t min : 0\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "exposure", + "description": "\n\t 확산 강도.\n\t 기본값 : 1\n\t min : 0\n ", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilter_Bloom", + "description": "\n\t Bloom 이펙트\n\t postEffectManager.addEffect( effect Instance ) 로 추가.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/bloom/RedFilter_Bloom.html", + "example": "\n var effect;\n effect = RedFilter_Bloom(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Bloom Instance" + }, + { + "code": "PROPERTY", + "title": "threshold", + "description": "\n\t 최소 유효값\n\t 기본값 : 75\n\t min : 0\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/bloom/RedFilter_BloomThreshold.json b/redDoc/docs/filter/bloom/RedFilter_BloomThreshold.json new file mode 100644 index 00000000..a5af3de0 --- /dev/null +++ b/redDoc/docs/filter/bloom/RedFilter_BloomThreshold.json @@ -0,0 +1,26 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_BloomThreshold", + "description": "\n\t BloomThreshold 이펙트\n\t RedFilter_Bloom 내부에서 사용하는 절차 이펙트\n\t 시스템적으로 사용됨.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "example": "\n var effect;\n effect = RedFilter_BloomThreshold(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_BloomThreshold Instance" + }, + { + "code": "PROPERTY", + "title": "threshold", + "description": "\n\t 최소 유효값\n\t 기본값 : 128\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/blur/RedFilter_Blur.json b/redDoc/docs/filter/blur/RedFilter_Blur.json new file mode 100644 index 00000000..249cbe9c --- /dev/null +++ b/redDoc/docs/filter/blur/RedFilter_Blur.json @@ -0,0 +1,21 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_Blur", + "description": "\n\t 기본 블러 이펙트\n\t postEffectManager.addEffect( effect Instance ) 로 추가.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/blur/RedFilter_Blur.html", + "example": "\n\tvar effect;\n\teffect = RedFilter_Blur(RedGL Instance); // 포스트이펙트 생성\n\t// postEffectManager는 RedView 생성시 자동생성됨.\n\t(RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Blur Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/blur/RedFilter_BlurX.json b/redDoc/docs/filter/blur/RedFilter_BlurX.json new file mode 100644 index 00000000..e97ce765 --- /dev/null +++ b/redDoc/docs/filter/blur/RedFilter_BlurX.json @@ -0,0 +1,27 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_BlurX", + "description": "\n\t X축 블러 이펙트\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/blur/RedFilter_BlurX.html", + "example": "\n var effect;\n effect = RedFilter_BlurX(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_BlurX Instance" + }, + { + "code": "PROPERTY", + "title": "size", + "description": "\n\t 블러 사이즈\n\t 기본값 : 50\n\t min : 0\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/blur/RedFilter_BlurY.json b/redDoc/docs/filter/blur/RedFilter_BlurY.json new file mode 100644 index 00000000..f028de92 --- /dev/null +++ b/redDoc/docs/filter/blur/RedFilter_BlurY.json @@ -0,0 +1,27 @@ +[ + { + "constructorYn": true, + "title": "RedFilter_BlurY", + "description": "\n\t X축 블러 이펙트\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/blur/RedFilter_BlurY.html", + "example": "\n var effect;\n effect = RedFilter_BlurY(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_BlurY Instance" + }, + { + "code": "PROPERTY", + "title": "size", + "description": "\n\t 블러 사이즈\n\t 기본값 : 50\n\t min : 0\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/blur/RedFilter_GaussianBlur.json b/redDoc/docs/filter/blur/RedFilter_GaussianBlur.json new file mode 100644 index 00000000..507af1ff --- /dev/null +++ b/redDoc/docs/filter/blur/RedFilter_GaussianBlur.json @@ -0,0 +1,27 @@ +[ + { + "code": "PROPERTY", + "title": "radius", + "description": "\n\t 가우시간 블러강도\n\t 기본값 : 1\n\t min: 0.1\n\t max: 255\n ", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilter_GaussianBlur", + "description": "\n\t 가우시안 블러 이펙트\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/blur/RedFilter_GaussianBlur.html", + "example": "\n var effect;\n effect = RedFilter_GaussianBlur(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_GaussianBlur Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/pixelate/RedFilter_HalfTone.json b/redDoc/docs/filter/pixelate/RedFilter_HalfTone.json new file mode 100644 index 00000000..8d711da7 --- /dev/null +++ b/redDoc/docs/filter/pixelate/RedFilter_HalfTone.json @@ -0,0 +1,51 @@ +[ + { + "code": "PROPERTY", + "title": "angle", + "description": "\n\t 기본값 0.0\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "centerX", + "description": "\n\t 기본값 0.0\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "centerY", + "description": "\n\t 기본값 0.0\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "grayMode", + "description": "\n\t 기본값 false\n ", + "return": "Boolean" + }, + { + "code": "PROPERTY", + "title": "radius", + "description": "\n\t 기본값 2\n\t min : 0\n ", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilter_HalfTone", + "description": "\n\t HalfTone 이펙트\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/pixelate/RedFilter_HalfTone.html", + "example": "\n var effect;\n effect = RedFilter_HalfTone(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_HalfTone Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/filter/pixelate/RedFilter_Pixelize.json b/redDoc/docs/filter/pixelate/RedFilter_Pixelize.json new file mode 100644 index 00000000..fc66104e --- /dev/null +++ b/redDoc/docs/filter/pixelate/RedFilter_Pixelize.json @@ -0,0 +1,33 @@ +[ + { + "code": "PROPERTY", + "title": "height", + "description": "\n\t 픽셀화 세로 크기\n\t 기본값 : 5\n\t min : 0\n ", + "return": "Number" + }, + { + "constructorYn": true, + "title": "RedFilter_Pixelize", + "description": "\n\t Pixelize 효과\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ] + }, + "extends": [ + "RedBaseFilter", + "RedBaseMaterial" + ], + "demo": "../example/postEffect/pixelate/RedFilter_Pixelize.html", + "example": "\n var effect;\n effect = RedFilter_Pixelize(RedGL Instance); // 포스트이펙트 생성\n // postEffectManager는 RedView 생성시 자동생성됨.\n (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가\n ", + "return": "RedFilter_Pixelize Instance" + }, + { + "code": "PROPERTY", + "title": "width", + "description": "\n\t 픽셀화 가로 크기\n\t 기본값 : 5\n\t min : 0\n ", + "return": "Number" + } +] \ No newline at end of file diff --git a/redDoc/docs/list.json b/redDoc/docs/list.json index c555198c..6272fc79 100644 --- a/redDoc/docs/list.json +++ b/redDoc/docs/list.json @@ -1 +1 @@ -[["base","RedBaseContainer"],["base","RedBaseController"],["base","RedBaseLight"],["base","RedBaseMaterial"],["base","RedBaseObject3D"],["base","RedBasePostEffect"],["base","RedBaseTexture"],["base","RedDefinePropertyInfo"],["camera","RedBasicController"],["camera","RedCamera"],["camera","RedObitController"],["detect","RedGLDetect"],["frameBuffer","RedFrameBuffer"],["geometry","RedBuffer"],["geometry","RedGeometry"],["geometry","RedInterleaveInfo"],["gl-matrix-min.2.4"],["gl-matrix-min"],["launcher","RedGLOffScreen"],["launcher","RedXR"],["light","RedAmbientLight"],["light","RedDirectionalLight"],["light","RedPointLight"],["loader","3ds","Red3DSLoader"],["loader","dae","RedDAELoader"],["loader","gltf","RedGLTFLoader"],["loader","obj","RedMTLLoader"],["loader","obj","RedOBJLoader"],["loader","RedImageLoader"],["material","RedBitmapMaterial"],["material","RedBitmapPointCloudMaterial"],["material","RedColorMaterial"],["material","RedColorPhongMaterial"],["material","RedColorPhongTextureMaterial"],["material","RedEnvironmentMaterial"],["material","RedParticleMaterial"],["material","RedPBRMaterial"],["material","RedSheetMaterial"],["material","RedStandardMaterial"],["material","RedVideoMaterial"],["material","system","RedColorPointCloudMaterial"],["material","system","RedDirectionalShadowMaterial"],["material","system","RedGridMaterial"],["material","system","RedMouseEventMaterial"],["material","system","RedPBRMaterial_System"],["material","system","RedPostEffectMaterial"],["material","system","RedSkyBoxMaterial"],["material","system","RedTextMaterial"],["object3D","RedAxis"],["object3D","RedGrid"],["object3D","RedLatheMesh"],["object3D","RedLine"],["object3D","RedMesh"],["object3D","RedSkyBox"],["object3D","RedSprite3D"],["object3D","RedTransformController"],["object3D","system","RedLathe"],["object3D","system","RedLinePoint"],["particle","RedBitmapPointCloud"],["particle","RedColorPointCloud"],["particle","RedParticleEmitter"],["particle","system","RedParticleUnit"],["particle","system","RedPointCloud"],["postEffect","adjustments","RedPostEffect_BrightnessContrast"],["postEffect","adjustments","RedPostEffect_Gray"],["postEffect","adjustments","RedPostEffect_HueSaturation"],["postEffect","adjustments","RedPostEffect_Invert"],["postEffect","adjustments","RedPostEffect_Threshold"],["postEffect","antialiasing","RedPostEffect_FXAA"],["postEffect","bloom","RedPostEffect_Bloom"],["postEffect","bloom","RedPostEffect_BloomThreshold"],["postEffect","blur","RedPostEffect_Blur"],["postEffect","blur","RedPostEffect_BlurX"],["postEffect","blur","RedPostEffect_BlurY"],["postEffect","blur","RedPostEffect_GaussianBlur"],["postEffect","blur","RedPostEffect_ZoomBlur"],["postEffect","dof","RedPostEffect_DoF"],["postEffect","dof","RedPostEffect_DoF_DepthMaterial"],["postEffect","pixelate","RedPostEffect_HalfTone"],["postEffect","pixelate","RedPostEffect_Pixelize"],["postEffect","RedPostEffectManager"],["postEffect","RedPostEffect_Convolution"],["postEffect","RedPostEffect_Film"],["postEffect","RedPostEffect_Vignetting"],["primitives","RedBox"],["primitives","RedCylinder"],["primitives","RedPlane"],["primitives","RedSphere"],["program","RedProgram"],["program","RedShader"],["program","RedSystemShaderCode"],["README.md"],["RedBoxSelection"],["RedGL"],["RedGLUtil"],["RedScene"],["RedView"],["RedWorld"],["renderer","RedRenderer"],["renderer","system","RedMouseEventManager"],["renderer","system","RedRenderDebuger"],["renderer","system","RedSystemUniformUpdater"],["resources","RedBitmapCubeTexture"],["resources","RedBitmapTexture"],["resources","RedDDSTexture"],["resources","RedVideoTexture"],["resources","system","RedTextureOptionChecker"],["shadow","RedDirectionalShadow"],["shadow","RedShadowManager"],["text","RedText"]] \ No newline at end of file +[["base","RedBaseContainer"],["base","RedBaseController"],["base","RedBaseFilter"],["base","RedBaseLight"],["base","RedBaseMaterial"],["base","RedBaseObject3D"],["base","RedBasePostEffect"],["base","RedBaseTexture"],["base","RedDefinePropertyInfo"],["camera","RedBasicController"],["camera","RedCamera"],["camera","RedObitController"],["detect","RedGLDetect"],["filter","adjustments","RedFilter_Gray"],["filter","adjustments","RedFilter_HueSaturation"],["filter","adjustments","RedFilter_Invert"],["filter","adjustments","RedFilter_Threshold"],["filter","bloom","RedFilter_Bloom"],["filter","bloom","RedFilter_BloomThreshold"],["filter","blur","RedFilter_Blur"],["filter","blur","RedFilter_BlurX"],["filter","blur","RedFilter_BlurY"],["filter","blur","RedFilter_GaussianBlur"],["filter","pixelate","RedFilter_HalfTone"],["filter","pixelate","RedFilter_Pixelize"],["filter","RedFilterEffectManager"],["filter","RedFilterFrameBuffer"],["filter","RedFilter_Film"],["frameBuffer","RedFrameBuffer"],["geometry","RedBuffer"],["geometry","RedGeometry"],["geometry","RedInterleaveInfo"],["gl-matrix-min.2.4"],["gl-matrix-min"],["launcher","RedGLOffScreen"],["launcher","RedXR"],["light","RedAmbientLight"],["light","RedDirectionalLight"],["light","RedPointLight"],["loader","3ds","Red3DSLoader"],["loader","dae","RedDAELoader"],["loader","gltf","RedGLTFLoader"],["loader","obj","RedMTLLoader"],["loader","obj","RedOBJLoader"],["loader","RedImageLoader"],["material","RedBitmapMaterial"],["material","RedBitmapPointCloudMaterial"],["material","RedColorMaterial"],["material","RedColorPhongMaterial"],["material","RedColorPhongTextureMaterial"],["material","RedEnvironmentMaterial"],["material","RedParticleMaterial"],["material","RedPBRMaterial"],["material","RedSheetMaterial"],["material","RedStandardMaterial"],["material","RedVideoMaterial"],["material","system","RedColorPointCloudMaterial"],["material","system","RedDirectionalShadowMaterial"],["material","system","RedFilterMaterial"],["material","system","RedGridMaterial"],["material","system","RedMouseEventMaterial"],["material","system","RedOutlineMaterial"],["material","system","RedOutlinePlaneMaterial"],["material","system","RedPBRMaterial_System"],["material","system","RedPostEffectMaterial"],["material","system","RedSkyBoxMaterial"],["material","system","RedTextMaterial"],["object3D","RedAxis"],["object3D","RedGrid"],["object3D","RedLatheMesh"],["object3D","RedLine"],["object3D","RedMesh"],["object3D","RedSkyBox"],["object3D","RedSprite3D"],["object3D","RedTransformController"],["object3D","system","RedLathe"],["object3D","system","RedLinePoint"],["particle","RedBitmapPointCloud"],["particle","RedColorPointCloud"],["particle","RedParticleEmitter"],["particle","system","RedParticleUnit"],["particle","system","RedPointCloud"],["postEffect","adjustments","RedPostEffect_BrightnessContrast"],["postEffect","adjustments","RedPostEffect_Gray"],["postEffect","adjustments","RedPostEffect_HueSaturation"],["postEffect","adjustments","RedPostEffect_Invert"],["postEffect","adjustments","RedPostEffect_Threshold"],["postEffect","antialiasing","RedPostEffect_FXAA"],["postEffect","bloom","RedPostEffect_Bloom"],["postEffect","bloom","RedPostEffect_BloomThreshold"],["postEffect","blur","RedPostEffect_Blur"],["postEffect","blur","RedPostEffect_BlurX"],["postEffect","blur","RedPostEffect_BlurY"],["postEffect","blur","RedPostEffect_GaussianBlur"],["postEffect","blur","RedPostEffect_ZoomBlur"],["postEffect","dof","RedPostEffect_DoF"],["postEffect","dof","RedPostEffect_DoF_DepthMaterial"],["postEffect","pixelate","RedPostEffect_HalfTone"],["postEffect","pixelate","RedPostEffect_Pixelize"],["postEffect","RedPostEffectManager"],["postEffect","RedPostEffect_Convolution"],["postEffect","RedPostEffect_Film"],["postEffect","RedPostEffect_Vignetting"],["primitives","RedBox"],["primitives","RedCylinder"],["primitives","RedPlane"],["primitives","RedSphere"],["program","RedProgram"],["program","RedShader"],["program","RedSystemShaderCode"],["README.md"],["RedBoxSelection"],["RedGL"],["RedGLUtil"],["RedScene"],["RedView"],["RedWorld"],["renderer","RedRenderer"],["renderer","system","RedMouseEventManager"],["renderer","system","RedRenderDebuger"],["renderer","system","RedSystemUniformUpdater"],["resources","RedBitmapCubeTexture"],["resources","RedBitmapTexture"],["resources","RedDDSTexture"],["resources","RedVideoTexture"],["resources","system","RedTextureOptionChecker"],["shadow","RedDirectionalShadow"],["shadow","RedShadowManager"],["text","RedText"]] \ No newline at end of file diff --git a/redDoc/docs/material/system/RedFilterMaterial.json b/redDoc/docs/material/system/RedFilterMaterial.json new file mode 100644 index 00000000..353dc28f --- /dev/null +++ b/redDoc/docs/material/system/RedFilterMaterial.json @@ -0,0 +1,30 @@ +[ + { + "code": "PROPERTY", + "title": "diffuseTexture", + "description": "diffuseTexture", + "return": "RedFilterMaterial" + }, + { + "constructorYn": true, + "title": "RedFilterMaterial", + "description": "\n\t 메쉬 필터 최종 이미지를 생성하기 위한재질.\n\t 시스템적으로 사용됨.\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ], + "diffuseTexture": [ + { + "type": "RedBitmapTexture" + }, + "RedBitmapTexture Instance" + ] + }, + "extends": [ + "RedBaseMaterial" + ], + "return": "RedFilterMaterial Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/material/system/RedOutlineMaterial.json b/redDoc/docs/material/system/RedOutlineMaterial.json new file mode 100644 index 00000000..fb9b43c9 --- /dev/null +++ b/redDoc/docs/material/system/RedOutlineMaterial.json @@ -0,0 +1,44 @@ +[ + { + "code": "PROPERTY", + "title": "alpha", + "description": "\n 기본값 : 1\n 최소값 : 0\n 최대값 : 1\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "color", + "description": "기본값 : #ff2211", + "return": "hex" + }, + { + "constructorYn": true, + "title": "RedOutlineMaterial", + "description": "\n\t RedOutlineMaterial Instance 생성\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ], + "hexColor": [ + { + "type": "hex" + }, + "기본값 : #ff0000" + ], + "alpha": [ + { + "type": "number" + }, + "기본값 : 1" + ] + }, + "extends": [ + "RedBaseMaterial" + ], + "demo": "../example/material/RedOutlineMaterial.html", + "example": "\n\t RedOutlineMaterial(RedGL Instance, hex)\n ", + "return": "RedOutlineMaterial Instance" + } +] \ No newline at end of file diff --git a/redDoc/docs/material/system/RedOutlinePlaneMaterial.json b/redDoc/docs/material/system/RedOutlinePlaneMaterial.json new file mode 100644 index 00000000..21606e5f --- /dev/null +++ b/redDoc/docs/material/system/RedOutlinePlaneMaterial.json @@ -0,0 +1,44 @@ +[ + { + "code": "PROPERTY", + "title": "alpha", + "description": "\n 기본값 : 1\n 최소값 : 0\n 최대값 : 1\n ", + "return": "Number" + }, + { + "code": "PROPERTY", + "title": "color", + "description": "기본값 : #ff2211", + "return": "hex" + }, + { + "constructorYn": true, + "title": "RedOutlinePlaneMaterial", + "description": "\n\t RedOutlinePlaneMaterial Instance 생성\n ", + "params": { + "redGL": [ + { + "type": "RedGL" + } + ], + "hexColor": [ + { + "type": "hex" + }, + "기본값 : #ff0000" + ], + "alpha": [ + { + "type": "number" + }, + "기본값 : 1" + ] + }, + "extends": [ + "RedBaseMaterial" + ], + "demo": "../example/material/RedOutlinePlaneMaterial.html", + "example": "\n\t RedOutlinePlaneMaterial(RedGL Instance, hex)\n ", + "return": "RedOutlinePlaneMaterial Instance" + } +] \ No newline at end of file diff --git a/release/RedGL.js b/release/RedGL.js index df286354..ad994515 100644 --- a/release/RedGL.js +++ b/release/RedGL.js @@ -2,7 +2,7 @@ * RedGL - MIT License * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.7.9 12:29:9 + * Last modification time of this file - 2019.8.7 11:52:14 * */ @@ -3254,10 +3254,11 @@ var RedBaseTexture; Object.freeze(RedBaseTexture); })(); /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.7.5 11:49 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * */ "use strict"; var RedBaseObject3D; @@ -3623,9 +3624,81 @@ var RedBaseObject3D; parseInt(Math.random() * 255), parseInt(Math.random() * 255), 255 - ]) + ]); + // 아웃라인 + /*DOC: + { + code : 'PROPERTY', + title :`outlineThickness`, + description : ` + 기본값 : 0 + 최소값 : 0 + `, + return : 'Number' + } + :DOC*/ + this['outlineThickness'] = 0; + this['_outlineAlpha'] = 1; + this['_outlineColor'] = new Float32Array(4) + this['outlineColor'] = '#ff0000'; + this['_filterList'] = []; + }; RedBaseObject3D.prototype = { + /*DOC: + { + title :`addFilter`, + code : 'METHOD', + description : ` + filter 추가 + `, + params : { + filter : [ + {type:'RedBaseFilter Instance'} + ] + }, + return : 'void' + } + :DOC*/ + addFilter: function (filter) { + filter instanceof RedBaseFilter || RedGLUtil.throwFunc('RedFilterEffectManager : addFilter - RedBaseFilter Instance만 허용.', '입력값 : ' + filter); + this['_filterList'].push(filter); + }, + /*DOC: + { + title :`removeFilter`, + code : 'METHOD', + description : ` + filter 제거 + `, + params : { + filter : [ + {type:'RedBaseFilter Instance'} + ] + }, + return : 'void' + } + :DOC*/ + removeFilter: (function () { + var t0; + return function (filter) { + t0 = this['_filterList'].indexOf(filter); + if (t0 != -1) this['_filterList'].splice(t0, 1); + } + })(), + /*DOC: + { + title :`removeAllFilter`, + code : 'METHOD', + description : ` + 모든 filter 제거 + `, + return : 'void' + } + :DOC*/ + removeAllFilter: function () { + this['_filterList'].length = 0; + }, /*DOC: { title :`addLOD`, @@ -4189,6 +4262,48 @@ var RedBaseObject3D; this['_material'] = v } }); + /*DOC: + { + code : 'PROPERTY', + title :`outlineColor`, + description : `기본값 : #ff0000`, + return : 'hex' + } + :DOC*/ + Object.defineProperty(RedBaseObject3D.prototype, 'outlineColor', { + get: function () { + return this['_outlineColorHex'] + }, + set: (function () { + var t0; + return function (hex) { + this['_outlineColorHex'] = hex ? hex : '#ff0000'; + t0 = RedGLUtil.hexToRGB_ZeroToOne.call(this, this['_outlineColorHex']); + this['_outlineColor'][0] = t0[0]; + this['_outlineColor'][1] = t0[1]; + this['_outlineColor'][2] = t0[2]; + this['_outlineColor'][3] = this['_outlineAlpha']; + } + })() + }); + /*DOC: + { + code : 'PROPERTY', + title :`outlineAlpha`, + description : ` + 기본값 : 1 + 최소값 : 0 + 최대값 : 1 + `, + return : 'Number' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedBaseObject3D', 'outlineAlpha', 'number', { + 'min': 0, 'max': 1, + callback: function (v) { + this['_outlineColor'][3] = this['_outlineAlpha'] = v + } + }); Object.freeze(RedBaseObject3D); })(); @@ -10277,119 +10392,445 @@ var RedTextMaterial; Object.freeze(RedTextMaterial); })(); /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.6.13 11:7 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.7.12 14:22:52 + * */ "use strict"; -var RedAmbientLight; +var RedOutlineMaterial; (function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedOutlineMaterialProgram'; + var PROGRAM_OPTION_LIST = []; + var checked; + vSource = function () { + /* @preserve + // 스키닝 + //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# + + // Sprite3D + //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# + void main(void) { + gl_PointSize = uPointSize; + float outlineSize = uOutlineThickness; + + // position 계산 + //#REDGL_DEFINE#skin#true# mat4 targetMatrix = uMMatrix * getSkinMatrix() ; + //#REDGL_DEFINE#skin#false# mat4 targetMatrix = uMMatrix; + vVertexPosition = targetMatrix * vec4(aVertexPosition, 1.0); + float tScaleX = length(vec3(uMMatrix[0][0], uMMatrix[0][1], uMMatrix[0][2])); + float tScaleY = length(vec3(uMMatrix[1][0], uMMatrix[1][1], uMMatrix[1][2])); + float tScaleZ = length(vec3(uMMatrix[2][0], uMMatrix[2][1], uMMatrix[2][2])); + + //#REDGL_DEFINE#sprite3D#true# gl_Position = uPMatrix * getSprite3DMatrix(uCameraMatrix , targetMatrix) * vec4(aVertexPosition, 1.0); + //#REDGL_DEFINE#sprite3D#true# if(!u_PerspectiveScale){ + //#REDGL_DEFINE#sprite3D#true# gl_Position /= gl_Position.w; + //#REDGL_DEFINE#sprite3D#true# gl_Position.xy += aVertexPosition.xy * vec2((uPMatrix * targetMatrix)[0][0],(uPMatrix * targetMatrix)[1][1]); + //#REDGL_DEFINE#sprite3D#true# } + //#REDGL_DEFINE#skin#false#//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition * vec3(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY,1.0+outlineSize/tScaleZ) , 1.0); + //#REDGL_DEFINE#skin#true#//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition + vec3( aVertexNormal * vec3(outlineSize/tScaleX,outlineSize/tScaleY,outlineSize/tScaleZ)), 1.0); + + + //#REDGL_DEFINE#directionalShadow#true# vResolution = uResolution; + //#REDGL_DEFINE#directionalShadow#true# vShadowPos = cTexUnitConverter * uDirectionalShadowLightMatrix * targetMatrix * vec4(aVertexPosition, 1.0); + } + */ + }; + fSource = function () { + /* @preserve + precision mediump float; + // 안개 + //#REDGL_DEFINE#fragmentShareFunc#fogFactor# + //#REDGL_DEFINE#fragmentShareFunc#fog# + + // 그림자 + //#REDGL_DEFINE#fragmentShareFunc#decodeFloatShadow# + //#REDGL_DEFINE#fragmentShareFunc#getShadowColor# + + void main(void) { + vec4 finalColor = uOutlineColor; + //#REDGL_DEFINE#directionalShadow#true# finalColor.rgb *= getShadowColor( vShadowPos, vResolution, uDirectionalShadowTexture); + //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; + //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); + } + */ + }; /*DOC: { constructorYn : true, - title :`RedAmbientLight`, + title :`RedOutlineMaterial`, description : ` - 기본 환경광. - RedAmbientLight Instance 생성자. + RedOutlineMaterial Instance 생성 `, params : { redGL : [ {type:'RedGL'} ], - hex : [ + hexColor : [ {type:'hex'}, - '기본값 : #fff' + '기본값 : #ff0000' ], alpha : [ {type:'number'}, - '기본값 : 0.1', - 'range : 0 ~ 1' - ], - intensity : [ - {type:'number'}, - '기본값 : 1', - 'range : 0 ~ 1' + '기본값 : 1' ] }, - extends : [ - 'RedBaseLight' - ], - demo : '../example/light/RedAmbientLight.html', - example: ` - RedAmbientLight(RedGL Instance, '#fff', 1); + extends : ['RedBaseMaterial'], + demo : '../example/material/RedOutlineMaterial.html', + example : ` + RedOutlineMaterial(RedGL Instance, hex) `, - return : 'RedAmbientLight Instance' + return : 'RedOutlineMaterial Instance' } :DOC*/ - RedAmbientLight = function (redGL, hexColor, alpha, intensity) { - if (!(this instanceof RedAmbientLight)) return new RedAmbientLight(redGL, hexColor, alpha, intensity); - redGL instanceof RedGL || RedGLUtil.throwFunc('RedAmbientLight : RedGL Instance만 허용.', '입력값 : ' + redGL); + RedOutlineMaterial = function (redGL, hexColor, alpha) { + if (!(this instanceof RedOutlineMaterial)) return new RedOutlineMaterial(redGL, hexColor, alpha); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedOutlineMaterial : RedGL Instance만 허용.', '입력값 : ' + redGL); + this.makeProgramList(this, redGL, PROGRAM_NAME, vSource, fSource, PROGRAM_OPTION_LIST); + ///////////////////////////////////////// // 유니폼 프로퍼티 - this['_lightColor'] = new Float32Array(4); + this['_color'] = new Float32Array(4); + this['alpha'] = alpha == undefined ? 1 : alpha; + ///////////////////////////////////////// // 일반 프로퍼티 - this['intensity'] = intensity == undefined ? 1 : intensity; - this['alpha'] = alpha == undefined ? 0.1 : alpha; - this['color'] = hexColor ? hexColor : '#fff'; + this['color'] = hexColor ? hexColor : '#ff0000'; this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } console.log(this); }; + RedOutlineMaterial.prototype = new RedBaseMaterial(); + RedOutlineMaterial['DEFINE_OBJECT_COLOR'] = { + get: function () { + return this['_colorHex'] + }, + set: (function () { + var t0; + return function (hex) { + this['_colorHex'] = hex ? hex : '#ff2211'; + t0 = RedGLUtil.hexToRGB_ZeroToOne.call(this, this['_colorHex']); + this['_color'][0] = t0[0]; + this['_color'][1] = t0[1]; + this['_color'][2] = t0[2]; + this['_color'][3] = this['_alpha']; + } + })() + }; + RedOutlineMaterial['DEFINE_OBJECT_ALPHA'] = { + 'min': 0, 'max': 1, + callback: function (v) { + this['_color'][3] = this['_alpha'] = v + } + }; /*DOC: { - title :`RedAmbientLight.TYPE`, - code : 'CONST', - description : `RedAmbientLight 타입상수`, - return : 'String' + code : 'PROPERTY', + title :`color`, + description : `기본값 : #ff2211`, + return : 'hex' } :DOC*/ - RedAmbientLight['TYPE'] = 'RedAmbientLight'; - RedAmbientLight.prototype = new RedBaseLight(); + Object.defineProperty(RedOutlineMaterial.prototype, 'color', RedOutlineMaterial['DEFINE_OBJECT_COLOR']); /*DOC: { - title :`type`, - code : 'PROPERTY', - description : `인스턴스 생성시 RedAmbientLight['TYPE']값이 자동 주입됨`, - return : 'String' + code : 'PROPERTY', + title :`alpha`, + description : ` + 기본값 : 1 + 최소값 : 0 + 최대값 : 1 + `, + return : 'Number' } :DOC*/ - Object.defineProperty(RedAmbientLight.prototype, 'TYPE', { - configurable: false, - writable: false, - value: RedAmbientLight['TYPE'] - }); - Object.freeze(RedAmbientLight); + RedDefinePropertyInfo.definePrototype('RedOutlineMaterial', 'alpha', 'number', RedOutlineMaterial['DEFINE_OBJECT_ALPHA']); + Object.freeze(RedOutlineMaterial); })(); /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.4.30 18:53 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.7.11 18:28:15 + * */ "use strict"; -var RedDirectionalLight; +var RedOutlinePlaneMaterial; (function () { - /*DOC: - { - constructorYn : true, - title :`RedDirectionalLight`, - description : ` - 기본 직사광. - RedDirectionalLight Instance 생성자. - `, - params : { - redGL : [ - {type:'RedGL'} - ], - hex : [ - {type:'hex'}, - '기본값 : #fff' - ], - alpha : [ - {type:'number'}, - '기본값 : 1', - 'range : 0 ~ 1' + var vSource, fSource; + var PROGRAM_NAME = 'RedOutlinePlaneMaterialProgram'; + var PROGRAM_OPTION_LIST = []; + var checked; + vSource = function () { + /* @preserve + // 스키닝 + //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# + + // Sprite3D + //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# + void main(void) { + gl_PointSize = uPointSize; + float outlineSize = uOutlineThickness; + + // position 계산 + //#REDGL_DEFINE#skin#true# mat4 targetMatrix = uMMatrix * getSkinMatrix() ; + //#REDGL_DEFINE#skin#false# mat4 targetMatrix = uMMatrix; + vVertexPosition = targetMatrix * vec4(aVertexPosition, 1.0); + float tScaleX = length(vec3(targetMatrix[0][0], targetMatrix[0][1], targetMatrix[0][2])); + float tScaleY = length(vec3(targetMatrix[1][0], targetMatrix[1][1], targetMatrix[1][2])); + float tScaleZ = length(vec3(targetMatrix[2][0], targetMatrix[2][1], targetMatrix[2][2])); + + //#REDGL_DEFINE#sprite3D#true# gl_Position = uPMatrix * getSprite3DMatrix(uCameraMatrix , targetMatrix) * vec4(aVertexPosition, 1.0); + //#REDGL_DEFINE#sprite3D#true# if(!u_PerspectiveScale){ + //#REDGL_DEFINE#sprite3D#true# gl_Position /= gl_Position.w; + //#REDGL_DEFINE#sprite3D#true# gl_Position.xy += aVertexPosition.xy * vec2((uPMatrix * targetMatrix)[0][0],(uPMatrix * targetMatrix)[1][1]); + //#REDGL_DEFINE#sprite3D#true# } + //#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition * vec3(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY,1.0+outlineSize/tScaleZ) , 1.0); + vTexcoord = aTexcoord-0.5; + vTexcoord *= vec2(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY); + + + //#REDGL_DEFINE#directionalShadow#true# vResolution = uResolution; + //#REDGL_DEFINE#directionalShadow#true# vShadowPos = cTexUnitConverter * uDirectionalShadowLightMatrix * targetMatrix * vec4(aVertexPosition, 1.0); + } + */ + }; + fSource = function () { + /* @preserve + precision mediump float; + // 안개 + //#REDGL_DEFINE#fragmentShareFunc#fogFactor# + //#REDGL_DEFINE#fragmentShareFunc#fog# + + // 그림자 + //#REDGL_DEFINE#fragmentShareFunc#decodeFloatShadow# + //#REDGL_DEFINE#fragmentShareFunc#getShadowColor# + + void main(void) { + vec4 finalColor = uOutlineColor; + if(-0.495 redGL['detect']['texture']['MAX_TEXTURE_SIZE']) width = redGL['detect']['texture']['MAX_TEXTURE_SIZE']; + if (height > redGL['detect']['texture']['MAX_TEXTURE_SIZE']) height = redGL['detect']['texture']['MAX_TEXTURE_SIZE']; + this['redGL'] = redGL; + this['width'] = width; + this['height'] = height; + this._prevWidth = null + this._prevHeight = null + this['webglFrameBuffer'] = gl.createFramebuffer(); + this['webglRenderBuffer'] = gl.createRenderbuffer(); + this['texture'] = RedBitmapTexture(redGL); + this['_UUID'] = RedGL.makeUUID(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this['webglFrameBuffer']); + // 텍스쳐 세팅 + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this['texture']['webglTexture']); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this['width'], this['height'], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + // gl.generateMipmap(gl.TEXTURE_2D); + // 프레임버퍼 세팅 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this['texture']['webglTexture'], 0); + // + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + console.log(this) + }; + RedFilterFrameBuffer.prototype = { + /*DOC: + { + code : 'METHOD', + title :`bind`, + description : `소유하고있는 webglFrameBuffer, webglTexture, webglRenderBuffer를 binding.`, + params : { + gl : [{type:'WebGL Context'}] + }, + return : 'void' + } + :DOC*/ + bind: function (gl) { + gl.bindFramebuffer(gl.FRAMEBUFFER, this['webglFrameBuffer']); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this['texture']['webglTexture']); + if (this['_prevWidth'] != this['width'] || this['_prevHeight'] != this['height']) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, parseInt(this['width']), parseInt(this['height']), 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } else { + gl.clear(gl.COLOR_BUFFER_BIT) + } + + this._prevWidth = this['width'] + this._prevHeight = this['height'] + + }, + /*DOC: + { + code : 'METHOD', + title :`unbind`, + description : `소유하고있는 webglFrameBuffer, webglTexture, webglRenderBuffer를 unbinding.`, + params : { + gl : [{type:'WebGL Context'}] + }, + return : 'void' + } + :DOC*/ + unbind: function (gl) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilterFrameBuffer', + /*DOC: + { + code:`PROPERTY`, + title :`width`, + description : ` + 기본값 : 1920 or 하드웨어 최대값 + `, + return : 'Number' + } + :DOC*/ + ['width', 'number', {min: 2}], + /*DOC: + { + code:`PROPERTY`, + title :`height`, + description : ` + 기본값 : 1080 or 하드웨어 최대값 + `, + return : 'Number' + } + :DOC*/ + ['height', 'number', {min: 2}] + ); + Object.freeze(RedFilterFrameBuffer); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilterEffectManager; +(function () { + var tRedGL; + /*DOC: + { + constructorYn : true, + title :`RedFilterEffectManager`, + description : ` + RedFilterEffectManager Instance 생성. + RedScene 생성시 내부속성으로 자동생성됨. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + demo : '../example/RedFilters.html', + return : 'RedFilterEffectManager Instance' + } + :DOC*/ + RedFilterEffectManager = function (redGL) { + if (!(this instanceof RedFilterEffectManager)) return new RedFilterEffectManager(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilterEffectManager : RedGL Instance만 허용.', redGL); + /*DOC: + { + title :`frameBuffer`, + code : 'PROPERTY', + description : ` + 이펙트 렌더링시 사용될 프레임버퍼 + `, + return : 'RedFrameBuffer Instance' + } + :DOC*/ + Object.defineProperty(this, 'frameBuffer', {value: RedFilterFrameBuffer(redGL)}); + Object.defineProperty(this, 'finalMaterial', {value: RedFilterMaterial(redGL, this['frameBuffer']['texture'])}); + /*DOC: + { + title :`filterList`, + code : 'PROPERTY', + description : ` + 이펙트 리스트 + `, + return : 'Array' + } + :DOC*/ + this['filterList'] = []; + var quadMesh = RedMesh(redGL, RedPlane(redGL, 1, 1, 1, 1, true), this['finalMaterial']); + quadMesh.useCullFace = false; + Object.defineProperty(this, 'children', {value: [quadMesh]}); + this['_UUID'] = RedGL.makeUUID(); + console.log(this); + }; + RedFilterEffectManager.prototype = { + /*DOC: + { + title :`bind`, + code : 'METHOD', + description : ` + 프레임 버퍼 바인딩. + 렌더러에서 자동호출됨. + `, + params : { + gl : [ + {type:'WebGL Context'} + ] + }, + return : 'void' + } + :DOC*/ + bind: function (gl) { + this['frameBuffer'].bind(gl); + }, + /*DOC: + { + title :`unbind`, + code : 'METHOD', + description : ` + 프레임 버퍼 언바인딩. + 렌더러에서 자동호출됨. + `, + params : { + gl : [ + {type:'WebGL Context'} + ] + }, + return : 'void' + } + :DOC*/ + unbind: function (gl) { + this['frameBuffer'].unbind(gl); + }, + render: (function () { + var tQuadMesh; + var originFrameBufferTexture, lastFrameBufferTexture; + + var drawEffect; + var tCacheSystemUniformInfo; + var tEffectList; + tEffectList = []; + drawEffect = function (redGL, effect, quadChildren, redView, tCamera, redRenderer, time, renderInfo, tMesh, depth, length) { + var tPerspectiveMTX = []; + var tProgram; + var tLocationInfo; + var tSystemUniformLocation; + var tLocation; + var tUUID; + var tValueStr; + var tParentFrameBufferTexture; + var gl; + var i, len; + var tScene, tViewRect; + var tFrameBuffer; + gl = redGL.gl; + tScene = redView['scene']; + tViewRect = redView['_viewRect']; + //////////////////////////////////////////////////////////////////////////// + if (effect['_process'] && effect['_process'].length) { + tParentFrameBufferTexture = lastFrameBufferTexture; + i = 0; + len = effect['_process'].length; + for (i; i < len; i++) { + drawEffect(redGL, effect['_process'][i], quadChildren, redView, tCamera, redRenderer, time, renderInfo, tMesh, depth + 1); + } + } + tFrameBuffer = effect['frameBuffer']; + if (tFrameBuffer) { + // 최종메쉬의 재질을 현재 이펙트로 변경 + tFrameBuffer['_width'] = parseInt(tViewRect[2]); + tFrameBuffer['_height'] = parseInt(tViewRect[3]); + tQuadMesh['_material'] = effect; + // 프로그램을 변경 + tProgram = tQuadMesh['_material']['program']; + gl.useProgram(tProgram['webglProgram']); + // 시스템 유니폼중 업데이트 해야할 목록 처리 + tSystemUniformLocation = tProgram['systemUniformLocation']; + // 퍼스펙티브 매트릭스 처리 + tLocationInfo = tSystemUniformLocation['uPMatrix']; + if (tLocationInfo) { + tLocation = tLocationInfo['location']; + tUUID = tLocationInfo['_UUID']; + if (tLocation) { + if (tCamera['mode2DYn']) { + var x, y, z; + // mat4.ortho( + // tPerspectiveMTX, + // -0.5, // left + // 0.5, // right + // -0.5, // bottom + // 0.5, // top, + // -tCamera['farClipping'], + // tCamera['farClipping'] + // ); + // mat4.translate(tPerspectiveMTX, tPerspectiveMTX, [-0.5, 0.5, 0]); + // mat4.scale(tPerspectiveMTX, tPerspectiveMTX, [1 / parseInt(tViewRect[2]) * tRedGL.renderScale * window.devicePixelRatio, 1 / parseInt(tViewRect[3]) * tRedGL.renderScale * window.devicePixelRatio, 1]) + //ortho + tPerspectiveMTX[0] = 2; + tPerspectiveMTX[1] = 0; + tPerspectiveMTX[2] = 0; + tPerspectiveMTX[3] = 0; + tPerspectiveMTX[4] = 0; + tPerspectiveMTX[5] = 2; + tPerspectiveMTX[6] = 0; + tPerspectiveMTX[7] = 0; + tPerspectiveMTX[8] = 0; + tPerspectiveMTX[9] = 0; + tPerspectiveMTX[10] = 2 * -1 / tCamera['farClipping'] * 2; + tPerspectiveMTX[11] = 0; + tPerspectiveMTX[12] = 0; + tPerspectiveMTX[13] = 0; + tPerspectiveMTX[14] = 0; + tPerspectiveMTX[15] = 1; + x = -0.5, y = 0.5, z = 0; + tPerspectiveMTX[12] = tPerspectiveMTX[0] * x + tPerspectiveMTX[4] * y + tPerspectiveMTX[8] * z + tPerspectiveMTX[12]; + tPerspectiveMTX[13] = tPerspectiveMTX[1] * x + tPerspectiveMTX[5] * y + tPerspectiveMTX[9] * z + tPerspectiveMTX[13]; + tPerspectiveMTX[14] = tPerspectiveMTX[2] * x + tPerspectiveMTX[6] * y + tPerspectiveMTX[10] * z + tPerspectiveMTX[14]; + tPerspectiveMTX[15] = tPerspectiveMTX[3] * x + tPerspectiveMTX[7] * y + tPerspectiveMTX[11] * z + tPerspectiveMTX[15]; + x = 1 / parseInt(tViewRect[2]) * tRedGL.renderScale * window.devicePixelRatio; + y = 1 / parseInt(tViewRect[3]) * tRedGL.renderScale * window.devicePixelRatio; + z = 1; + tPerspectiveMTX[0] = tPerspectiveMTX[0] * x; + tPerspectiveMTX[1] = tPerspectiveMTX[1] * x; + tPerspectiveMTX[2] = tPerspectiveMTX[2] * x; + tPerspectiveMTX[3] = tPerspectiveMTX[3] * x; + tPerspectiveMTX[4] = tPerspectiveMTX[4] * y; + tPerspectiveMTX[5] = tPerspectiveMTX[5] * y; + tPerspectiveMTX[6] = tPerspectiveMTX[6] * y; + tPerspectiveMTX[7] = tPerspectiveMTX[7] * y; + tPerspectiveMTX[8] = tPerspectiveMTX[8] * z; + tPerspectiveMTX[9] = tPerspectiveMTX[9] * z; + tPerspectiveMTX[10] = tPerspectiveMTX[10] * z; + tPerspectiveMTX[11] = tPerspectiveMTX[11] * z; + + + } else { + tPerspectiveMTX = tCamera['perspectiveMTX'] + } + tValueStr = JSON.stringify(tPerspectiveMTX); + if (tCacheSystemUniformInfo[tUUID] != tValueStr) { + gl.uniformMatrix4fv(tLocation, false, tPerspectiveMTX); + tCacheSystemUniformInfo[tUUID] = tValueStr; + } + } + } + ////////////////////////////////////////////////////////////////////// + // if (!tCamera['mode2DYn'] || depth || length > 1) { + gl.bindFramebuffer(gl.FRAMEBUFFER, tFrameBuffer['webglFrameBuffer']); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tFrameBuffer['texture']['webglTexture']); + + if (tFrameBuffer['_prevWidth'] != tFrameBuffer['width'] || tFrameBuffer['_prevHeight'] != tFrameBuffer['height']) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, tFrameBuffer['width'], tFrameBuffer['height'], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } else { + gl.clear(gl.COLOR_BUFFER_BIT) + } + + + tFrameBuffer._prevWidth = tFrameBuffer['width']; + tFrameBuffer._prevHeight = tFrameBuffer['height'] + // } + // 해당 이펙트의 기본 텍스쳐를 지난 이펙트의 최종 텍스쳐로 업로드 + if (effect['_process'] && effect['_process'].length) { + effect.updateTexture( + lastFrameBufferTexture, + tParentFrameBufferTexture + ); + } else { + effect['_diffuseTexture'] = lastFrameBufferTexture; + } + // 해당 이펙트를 렌더링하고 + redRenderer.sceneRender(redGL, tScene, tCamera, tCamera['mode2DYn'], quadChildren, time, renderInfo); + // 해당 이펙트의 프레임 버퍼를 언바인딩한다. + // if (!tCamera['mode2DYn'] || depth || length > 1) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + // } + // 현재 이펙트를 최종 텍스쳐로 기록하고 다음 이펙트가 있을경우 활용한다. + lastFrameBufferTexture = tFrameBuffer['texture']; + } + }; + return function (redGL, gl, redRenderer, redView, time, renderInfo, tMesh) { + var tCamera; + var tScene; + var tViewRect, tWorldRect; + var minX, minY, minZ, maxX, maxY, maxZ, vx, vy, vz, t, i, len; + var tx, ty, tz; + var tMatrix; + var stride; + var currentAABB; + var tRadius; + var tScaleX, tScaleY, tScaleTestX, tScaleTestY; + var prevEffect, tEffect; + prevEffect = null; + tScaleX = tScaleY = 0; + tRedGL = redGL; + tScene = redView['scene']; + tRadius = 0; + tCamera = redView['camera'] instanceof RedBaseController ? redView['camera']['camera'] : redView['camera']; + tViewRect = redView['_viewRect']; + tWorldRect = redRenderer['worldRect']; + tCacheSystemUniformInfo = redRenderer['cacheInfo']['cacheSystemUniformInfo']; + ///////////////////////////////////////////////////////////////////// + // 쿼드메쉬 영역 계산 + tMatrix = tMesh.matrix; + stride = tMesh._geometry['interleaveBuffer']['stride']; + minX = minY = minZ = maxX = maxY = maxZ = 0; + t = tMesh._geometry['interleaveBuffer']['data']; + i = 0; + len = tMesh._geometry['interleaveBuffer']['pointNum']; + for (i; i < len; i++) { + vx = i * stride , vy = vx + 1, vz = vx + 2; + tx = tMatrix[0] * t[vx] + tMatrix[4] * t[vy] + tMatrix[8] * t[vz]; + ty = tMatrix[1] * t[vx] + tMatrix[5] * t[vy] + tMatrix[9] * t[vz]; + tz = tMatrix[2] * t[vx] + tMatrix[6] * t[vy] + tMatrix[10] * t[vz]; + minX = tx < minX ? tx : minX; + maxX = tx > maxX ? tx : maxX; + minY = ty < minY ? ty : minY; + maxY = ty > maxY ? ty : maxY; + minZ = tz < minZ ? tz : minZ; + maxZ = tz > maxZ ? tz : maxZ; + } + currentAABB = [maxX - minX, maxY - minY, maxZ - minZ]; + ///////////////////////////////////////////////////////////////////// + // 렌더링할 이펙트 리스트를 정리한다. + tEffectList.length = 0; + i = 0; + len = this['filterList'].length; + tQuadMesh = this['children'][0]; + for (i; i < len; i++) { + tEffect = this['filterList'][i]; + + if (prevEffect != tEffect) { + // 최종 이펙트 리스트에 등록 + tEffectList[tEffectList.length] = tEffect; + // 스케일 계산 + if (tEffect instanceof RedFilter_Blur) { + tScaleTestX = currentAABB[0] + (tCamera['mode2DYn'] ? 5 : 0) + tScaleTestY = currentAABB[1] + (tCamera['mode2DYn'] ? 5 : 0) + } else if (tEffect instanceof RedFilter_BlurX || tEffect instanceof RedFilter_BlurY) { + tScaleTestX = currentAABB[0] + tEffect['_size'] ; + tScaleTestY = currentAABB[1] + tEffect['_size'] ; + } else if (tEffect instanceof RedFilter_GaussianBlur) { + tScaleTestX = currentAABB[0] + tEffect['_radius']; + tScaleTestY = currentAABB[1] + tEffect['_radius']; + } else if (tEffect instanceof RedFilter_Bloom) { + tScaleTestX = currentAABB[0] + tEffect['_blur']; + tScaleTestY = currentAABB[1] + tEffect['_blur']; + } else { + tScaleTestX = currentAABB[0]; + tScaleTestY = currentAABB[1] + } + + tScaleX = tScaleX < tScaleTestX ? tScaleTestX : tScaleX; + tScaleY = tScaleY < tScaleTestY ? tScaleTestY : tScaleY; + } + + prevEffect = tEffect + } + + // 쿼드메쉬 위치 설정 + tQuadMesh.x = tMesh.x; + tQuadMesh.y = tMesh.y; + tQuadMesh.z = tMesh.z; + // 쿼드메쉬 영역 설정 + if (tCamera['mode2DYn']) { + // 2D 일떄 + tQuadMesh.scaleX = tScaleX; + tQuadMesh.scaleY = tScaleY; + tQuadMesh.scaleZ = 1; + } else { + // 3D 일때 + tRadius = Math.sqrt(currentAABB[0] * currentAABB[0] + currentAABB[1] * currentAABB[1]); + tQuadMesh.scaleY = tQuadMesh.scaleX = tQuadMesh.scaleZ = tRadius + tQuadMesh.lookAt(tCamera.x, tCamera.y, tCamera.z) + + } + //////////////////////////////////////////////////////////////////////////// + // 프레임 버퍼 정보를 캐싱 + lastFrameBufferTexture = originFrameBufferTexture = this['frameBuffer']['texture']; + //////////////////////////////////////////////////////////////////////////// + // 최종결과는 RedView의 사이즈와 동일하게 한다. + this['frameBuffer']['_width'] = tViewRect[2]; + this['frameBuffer']['_height'] = tViewRect[3]; + + if (tCamera['mode2DYn']) { + gl.scissor( + parseInt(tMesh.x * redGL._renderScale * window.devicePixelRatio - tQuadMesh.scaleX / 2 * window.devicePixelRatio)-10, + parseInt(tViewRect[3] - tMesh.y * redGL._renderScale * window.devicePixelRatio - tQuadMesh.scaleY / 2 * window.devicePixelRatio)-10, + parseInt(tQuadMesh.scaleX * window.devicePixelRatio)+20, + parseInt(tQuadMesh.scaleY * window.devicePixelRatio)+20 + ); + } else { + var tScreen_point; + var tScreen_distance; + var tScreen_resultMTX; + var tScreen_resultPosition; + tScreen_resultPosition = {x: 0, y: 0, z: 0, w: 0}; + tScreen_resultMTX = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ]; + ///////////////////////////////////////////////////////////////////////////////// + mat4.multiply(tScreen_resultMTX, tCamera.perspectiveMTX, tCamera.matrix); + mat4.multiply(tScreen_resultMTX, tScreen_resultMTX, tQuadMesh['matrix']); + //////////////////////////////////////////////////////////////////////////////// + tScreen_resultPosition.x = tScreen_resultMTX[12], tScreen_resultPosition.y = tScreen_resultMTX[13], tScreen_resultPosition.z = tScreen_resultMTX[14], tScreen_resultPosition.w = tScreen_resultMTX[15]; + tScreen_resultPosition.x = tScreen_resultPosition.x * 0.5 / tScreen_resultPosition.w + 0.5; + tScreen_resultPosition.y = tScreen_resultPosition.y * 0.5 / tScreen_resultPosition.w + 0.5; + tScreen_point = [ + (tViewRect[0] + tScreen_resultPosition.x * tViewRect[2]) / window.devicePixelRatio, + (tViewRect[1] + (1 - tScreen_resultPosition.y) * tViewRect[3]) / window.devicePixelRatio + ]; + tScreen_distance = vec3.distance([tCamera.x, tCamera.y, tCamera.z], [tMesh.x, tMesh.y, tMesh.z]); + tRadius = tRadius / (tScreen_distance) * tViewRect[3] + if (tRadius > tViewRect[3]) tRadius = tViewRect[3] + gl.scissor( + parseInt(tScreen_point[0] * window.devicePixelRatio - tRadius / 2), + parseInt(tWorldRect[3] - tScreen_point[1] * window.devicePixelRatio - tRadius / 2), + parseInt(tRadius), + parseInt(tRadius) + ); + } + + //////////////////////////////////////////////////////////////////////////// + // 이펙트 렌더 + i = 0; + len = tEffectList.length; + for (i; i < len; i++) drawEffect(redGL, tEffectList[i], this['children'], redView, tCamera, redRenderer, time, renderInfo, tMesh, 0, len); + //////////////////////////////////////////////////////////////////////////// + if (redView['postEffectManager']['postEffectList'].length) { + var tPostEffectManagerFrameBuffer = redView['postEffectManager']['frameBuffer'] + gl.bindFramebuffer(gl.FRAMEBUFFER, tPostEffectManagerFrameBuffer['webglFrameBuffer']); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tPostEffectManagerFrameBuffer['texture']['webglTexture']); + // 렌더버퍼 세팅 + gl.bindRenderbuffer(gl.RENDERBUFFER, tPostEffectManagerFrameBuffer['webglRenderBuffer']); + // 프레임버퍼 세팅 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tPostEffectManagerFrameBuffer['texture']['webglTexture'], 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, tPostEffectManagerFrameBuffer['webglRenderBuffer']); + } + if (lastFrameBufferTexture != originFrameBufferTexture) { + this['finalMaterial']['_diffuseTexture'] = lastFrameBufferTexture; + tQuadMesh._material = this['finalMaterial']; + redRenderer.sceneRender(redGL, tScene, tCamera, tCamera['mode2DYn'], this['children'], time, renderInfo); + } + gl.scissor(tViewRect[0], tWorldRect[3] - tViewRect[3] - tViewRect[1], tViewRect[2], tViewRect[3]); + this['finalMaterial']['_diffuseTexture'] = this['frameBuffer']['texture']; + } + })() + }; + Object.freeze(RedFilterEffectManager); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ +"use strict"; +var RedBaseFilter; +(function () { + var tPrototype; + /*DOC: + { + constructorYn : true, + title :`RedBaseFilter`, + description : ` + 메쉬 필터 정의 사용되는 기저층 + `, + extends:['RedBaseMaterial'], + return : 'RedBaseFilter Instance' + } + :DOC*/ + RedBaseFilter = function () {}; + tPrototype = RedBaseFilter.prototype = new RedBaseMaterial(); + tPrototype['bind'] = RedFilterEffectManager.prototype['bind']; + tPrototype['unbind'] = RedFilterEffectManager.prototype['unbind']; + /*DOC: + { + title :`updateTexture`, + code : 'METHOD', + description : ` + 메쉬 필터 정의시 반드시 재정의 되어야함. + 메쉬 필터 내부에서 사용되는 텍스쳐를 업데이트함. + `, + return : 'void' + } + :DOC*/ + tPrototype['updateTexture'] = function () { + RedGLUtil.throwFunc('RedBaseFilter - updateTexture : 반드시 재정의해야함') + }; + /*DOC: + { + title :`_process`, + code : 'PROPERTY', + description : ` + 해당메쉬 필터 처리전 전처리과정이 필요할 경우 사용. + `, + return : 'void' + } + :DOC*/ + tPrototype['_process'] = []; + RedBaseFilter['baseVertexShaderSource1'] = function () { + /* @preserve + void main(void) { + vTexcoord = aTexcoord; + vResolution = uResolution; + vTime = uTime; + gl_Position = uPMatrix * uCameraMatrix * uMMatrix * vec4(aVertexPosition, 1.0); + } + */ + }; + Object.freeze(RedBaseFilter); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ + +"use strict"; +var RedFilterMaterial; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterMaterialProgram'; + var checked; + vSource = function () { + /* @preserve + void main(void) { + vTexcoord = aTexcoord; + gl_Position = uPMatrix * uCameraMatrix * uMMatrix * vec4(aVertexPosition, 1.0); + vResolution = uResolution; + } + */ + }; + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + void main(void) { + gl_FragColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + // gl_FragColor.r = 1.0; + // gl_FragColor.a = 0.5; + if(gl_FragColor.a == 0.0) discard; + + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilterMaterial`, + description : ` + 메쉬 필터 최종 이미지를 생성하기 위한재질. + 시스템적으로 사용됨. + `, + params : { + redGL : [ + {type:'RedGL'} + ], + diffuseTexture : [ + {type:'RedBitmapTexture'}, + 'RedBitmapTexture Instance' + ] + }, + extends : ['RedBaseMaterial'], + return : 'RedFilterMaterial Instance' + } + :DOC*/ + RedFilterMaterial = function (redGL, diffuseTexture) { + if (!(this instanceof RedFilterMaterial)) return new RedFilterMaterial(redGL, diffuseTexture); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilterMaterial : RedGL Instance만 허용.', redGL); + ///////////////////////////////////////// + // 유니폼 프로퍼티 + this['diffuseTexture'] = diffuseTexture; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilterMaterial.prototype = new RedBaseMaterial(); + /*DOC: + { + code : 'PROPERTY', + title :`diffuseTexture`, + description :`diffuseTexture`, + return : 'RedFilterMaterial' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedFilterMaterial', 'diffuseTexture', 'sampler2D', {essential: true}); + Object.freeze(RedFilterMaterial); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_BrightnessContrast; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBrightnessContrastProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision mediump float; + uniform sampler2D u_diffuseTexture; + uniform float u_brightness_value; + uniform float u_contrast_value; + void main(void) { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution ); + if (u_contrast_value > 0.0) finalColor.rgb = (finalColor.rgb - 0.5) / (1.0 - u_contrast_value) + 0.5; + else finalColor.rgb = (finalColor.rgb - 0.5) * (1.0 + u_contrast_value) + 0.5; + finalColor.rgb += u_brightness_value; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BrightnessContrast`, + description : ` + BrightnessContrast 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_BrightnessContrast.html', + example : ` + var effect; + effect = RedFilter_BrightnessContrast(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BrightnessContrast Instance' + } + :DOC*/ + RedFilter_BrightnessContrast = function (redGL) { + if (!(this instanceof RedFilter_BrightnessContrast)) return new RedFilter_BrightnessContrast(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BrightnessContrast : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['brightness'] = 0; + this['contrast'] = 0; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BrightnessContrast.prototype = new RedBaseFilter(); + RedFilter_BrightnessContrast.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BrightnessContrast', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`brightness`, + description : ` + 밝기 + 기본값 : 0 + min : -150 + max : 150 + `, + return : 'Number' + } + :DOC*/ + ['brightness', 'number', { + min: -150, max: 150, callback: function (v) { + this['_brightness_value'] = v / 255 + } + }], + /*DOC: + { + code : 'PROPERTY', + title :`contrast`, + description : ` + 대조 + 기본값 : 0 + min: -50 + max: 100 + `, + return : 'Number' + } + :DOC*/ + ['contrast', 'number', { + min: -50, max: 100, callback: function (v) { + this['_contrast_value'] = v / 255 + } + }] + ); + Object.freeze(RedFilter_BrightnessContrast); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Gray; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterGrayProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + void main(void) { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution); + highp float gray = (finalColor.r + finalColor.g + finalColor.b)/3.0; + gl_FragColor = vec4( gray, gray, gray, finalColor.a); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Gray`, + description : ` + Gray 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_Gray.html', + example : ` + var effect; + effect = RedFilter_Gray(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Gray Instance' + } + :DOC*/ + RedFilter_Gray = function (redGL) { + if (!(this instanceof RedFilter_Gray)) return new RedFilter_Gray(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Gray : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Gray.prototype = new RedBaseFilter(); + RedFilter_Gray.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Gray', 'diffuseTexture', 'sampler2D'); + Object.freeze(RedFilter_Gray); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 17:36:26 + * + */ + +"use strict"; +var RedFilter_Invert; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterInvertProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + + void main(void) { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution); + if(finalColor.a == 0.0) discard; + finalColor.r = 1.0 - finalColor.r; + finalColor.g = 1.0 - finalColor.g; + finalColor.b = 1.0 - finalColor.b; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Invert`, + description : ` + Invert 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_Invert.html', + example : ` + var effect; + effect = RedFilter_Invert(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Invert Instance' + } + :DOC*/ + RedFilter_Invert = function (redGL) { + if (!(this instanceof RedFilter_Invert)) return new RedFilter_Invert(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Invert : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Invert.prototype = new RedBaseFilter(); + RedFilter_Invert.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Invert', 'diffuseTexture', 'sampler2D'); + Object.freeze(RedFilter_Invert); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_Threshold; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterThresholdProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_threshold_value; + void main() { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + float v; + if(0.2126 * finalColor.r + 0.7152 * finalColor.g + 0.0722 * finalColor.b >= u_threshold_value) v = 1.0; + else v = 0.0; + finalColor.r = finalColor.g = finalColor.b = v; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Threshold`, + description : ` + Threshold 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_Threshold.html', + example : ` + var effect; + effect = RedFilter_Threshold(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Threshold Instance' + } + :DOC*/ + RedFilter_Threshold = function (redGL) { + if (!(this instanceof RedFilter_Threshold)) return new RedFilter_Threshold(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Threshold : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['threshold'] = 50; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Threshold.prototype = new RedBaseFilter(); + RedFilter_Threshold.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Threshold', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`threshold`, + description : ` + 최소 유효값 + 기본값 : 128 + min: 1 + max: 255 + `, + return : 'Number' + } + :DOC*/ + [ + 'threshold', 'number', + { + min: 1, max: 255, callback: function (v) { + this['_threshold_value'] = v / 255 + } + } + ] + ); + + Object.freeze(RedFilter_Threshold); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_HueSaturation; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterHueSaturationProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_hue_value; + uniform float u_saturation_value; + void main(void) { + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 finalColor = texture2D(u_diffuseTexture, testCoord ); + float angle = u_hue_value * 3.1415926535897932384626433832795; + float s = sin(angle), c = cos(angle); + vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0; + float len = length(finalColor.rgb); + + finalColor.rgb = vec3( + dot(finalColor.rgb, weights.xyz), + dot(finalColor.rgb, weights.zxy), + dot(finalColor.rgb, weights.yzx) + ); + + float average = (finalColor.r + finalColor.g + finalColor.b) / 3.0; + if (u_saturation_value > 0.0) finalColor.rgb += (average - finalColor.rgb) * (1.0 - 1.0 / (1.001 - u_saturation_value)); + else finalColor.rgb += (average - finalColor.rgb) * (-u_saturation_value); + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_HueSaturation`, + description : ` + HueSaturation 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_HueSaturation.html', + example : ` + var effect; + effect = RedFilter_HueSaturation(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_HueSaturation Instance' + } + :DOC*/ + RedFilter_HueSaturation = function (redGL) { + if (!(this instanceof RedFilter_HueSaturation)) return new RedFilter_HueSaturation(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_HueSaturation : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['hue'] = 0; + this['saturation'] = 0; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_HueSaturation.prototype = new RedBaseFilter(); + RedFilter_HueSaturation.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_HueSaturation', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`hue`, + description : ` + 색조 + 기본값 : 0 + min: -180 + max: 180 + `, + return : 'Number' + } + :DOC*/ + ['hue', 'number', { + min: -180, max: 180, callback: function (v) { + this['_hue_value'] = v / 180 + } + }], + /*DOC: + { + code : 'PROPERTY', + title :`saturation`, + description : ` + 채도 + 기본값 : 0 + min: -100 + max: 100 + `, + return : 'Number' + } + :DOC*/ + ['saturation', 'number', { + min: -100, max: 100, callback: function (v) { + this['_saturation_value'] = v / 100 + } + }] + ); + Object.freeze(RedFilter_HueSaturation); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Blur; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBlurProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + void main(void) { + vec2 px = vec2(1.0/vResolution.x, 1.0/vResolution.y); + vec4 finalColor = vec4(0.0); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-7.0*px.x, -7.0*px.y))*0.0044299121055113265; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-6.0*px.x, -6.0*px.y))*0.00895781211794; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-5.0*px.x, -5.0*px.y))*0.0215963866053; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-4.0*px.x, -4.0*px.y))*0.0443683338718; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-3.0*px.x, -3.0*px.y))*0.0776744219933; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-2.0*px.x, -2.0*px.y))*0.115876621105; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-1.0*px.x, -1.0*px.y))*0.147308056121; + finalColor += texture2D(u_diffuseTexture, testCoord )*0.159576912161; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 1.0*px.x, 1.0*px.y))*0.147308056121; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 2.0*px.x, 2.0*px.y))*0.115876621105; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 3.0*px.x, 3.0*px.y))*0.0776744219933; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 4.0*px.x, 4.0*px.y))*0.0443683338718; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 5.0*px.x, 5.0*px.y))*0.0215963866053; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 6.0*px.x, 6.0*px.y))*0.00895781211794; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 7.0*px.x, 7.0*px.y))*0.0044299121055113265; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Blur`, + description : ` + 기본 블러 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_Blur.html', + example : ` + var effect; + effect = RedFilter_Blur(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Blur Instance' + } + :DOC*/ + RedFilter_Blur = function (redGL) { + if (!(this instanceof RedFilter_Blur)) return new RedFilter_Blur(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Blur : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Blur.prototype = new RedBaseFilter(); + RedFilter_Blur.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Blur', 'diffuseTexture', 'sampler2D'); + Object.freeze(RedFilter_Blur); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_BlurX; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBlurXProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision mediump float; + uniform sampler2D u_diffuseTexture; + uniform float u_size; + float random(vec3 scale, float seed) { + return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); + } + void main() { + vec4 finalColor = vec4(0.0); + vec2 delta; + float total = 0.0; + float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); + delta = vec2(u_size/vResolution.x,0.0); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + float percent; + float weight; + for (float t = -4.0; t <= 4.0; t+=1.0) { + float percent = (t + offset - 0.5) / 4.0; + float weight = 1.0 - abs(percent); + vec4 sample = texture2D(u_diffuseTexture, testCoord + delta * percent); + sample.rgb *= sample.a; + finalColor += sample * weight; + total += weight; + } + finalColor = finalColor / total; + finalColor.rgb /= finalColor.a + 0.00001; + gl_FragColor = finalColor ; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BlurX`, + description : ` + X축 블러 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_BlurX.html', + example : ` + var effect; + effect = RedFilter_BlurX(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BlurX Instance' + } + :DOC*/ + RedFilter_BlurX = function (redGL) { + if (!(this instanceof RedFilter_BlurX)) return new RedFilter_BlurX(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BlurX : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['size'] = 50; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BlurX.prototype = new RedBaseFilter(); + RedFilter_BlurX.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BlurX', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`size`, + description : ` + 블러 사이즈 + 기본값 : 50 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['size', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_BlurX); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_BlurY; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBlurYProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_size; + float random(vec3 scale, float seed) { + return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); + } + void main() { + vec4 finalColor = vec4(0.0); + vec2 delta; + float total = 0.0; + float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); + delta = vec2(0.0, u_size/vResolution.y); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + + for (float t = -4.0; t <= 4.0; t++) { + float percent = (t + offset - 0.5) / 4.0; + float weight = 1.0 - abs(percent); + vec4 sample = texture2D(u_diffuseTexture, testCoord + delta * percent); + sample.rgb *= sample.a; + finalColor += sample * weight; + total += weight; + } + finalColor = finalColor / total; + finalColor.rgb /= finalColor.a + 0.00001; + gl_FragColor = finalColor ; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BlurY`, + description : ` + X축 블러 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_BlurY.html', + example : ` + var effect; + effect = RedFilter_BlurY(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BlurY Instance' + } + :DOC*/ + RedFilter_BlurY = function (redGL) { + if (!(this instanceof RedFilter_BlurY)) return new RedFilter_BlurY(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BlurY : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['size'] = 25; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BlurY.prototype = new RedBaseFilter(); + RedFilter_BlurY.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BlurY', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`size`, + description : ` + 블러 사이즈 + 기본값 : 50 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['size', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_BlurY); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_GaussianBlur; +(function () { + /*DOC: + { + constructorYn : true, + title :`RedFilter_GaussianBlur`, + description : ` + 가우시안 블러 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_GaussianBlur.html', + example : ` + var effect; + effect = RedFilter_GaussianBlur(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_GaussianBlur Instance' + } + :DOC*/ + RedFilter_GaussianBlur = function (redGL) { + if (!(this instanceof RedFilter_GaussianBlur)) return new RedFilter_GaussianBlur(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_GaussianBlur : RedGL Instance만 허용.', redGL); + ///////////////////////////////////////// + // 일반 프로퍼티 + this['_UUID'] = RedGL.makeUUID(); + this['_process'] = [ + RedFilter_BlurX(redGL), + RedFilter_BlurY(redGL) + ]; + this['radius'] = 1; + console.log(this); + }; + RedFilter_GaussianBlur.prototype = new RedBaseFilter(); + RedFilter_GaussianBlur.prototype['updateTexture'] = function () { + }; + /*DOC: + { + code : 'PROPERTY', + title :`radius`, + description : ` + 가우시간 블러강도 + 기본값 : 1 + min: 0.1 + max: 255 + `, + return : 'Number' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedFilter_GaussianBlur', 'radius', 'number', { + min: 0.1, max: 255, callback: function (v) { + this['_process'][0]['size'] = v; + this['_process'][1]['size'] = v; + } + }); + Object.freeze(RedFilter_GaussianBlur); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Pixelize; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterPixelizeProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_width; + uniform float u_height; + void main(void) { + vec4 finalColor; + float dx = 1.0/vResolution.x * u_width; + float dy = 1.0/vResolution.y * u_height; + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec2 coord = vec2( + dx * (floor(testCoord.x / dx) + 0.5), + dy * (floor(testCoord.y / dy) + 0.5) + ); + finalColor = texture2D(u_diffuseTexture, coord); + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Pixelize`, + description : ` + Pixelize 효과 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/pixelate/RedFilter_Pixelize.html', + example : ` + var effect; + effect = RedFilter_Pixelize(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Pixelize Instance' + } + :DOC*/ + RedFilter_Pixelize = function (redGL) { + if (!(this instanceof RedFilter_Pixelize)) return new RedFilter_Pixelize(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Pixelize : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['width'] = 5; + this['height'] = 5; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Pixelize.prototype = new RedBaseFilter(); + RedFilter_Pixelize.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Pixelize', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`width`, + description : ` + 픽셀화 가로 크기 + 기본값 : 5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['width', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`height`, + description : ` + 픽셀화 세로 크기 + 기본값 : 5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['height', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_Pixelize); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_HalfTone; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterHalfToneProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_centerX; + uniform float u_centerY; + uniform float u_angle; + uniform float u_radius; + uniform bool u_grayMode; + + float pattern(float angle, vec2 testCoord) { + angle = angle * 3.141592653589793/180.0; + float s = sin(angle), c = cos(angle); + vec2 tex = testCoord; + tex.x -= u_centerX + 0.5; + tex.y -= u_centerY + 0.5; + vec2 point = vec2( + c * tex.x - s * tex.y, + s * tex.x + c * tex.y + ) * vResolution / u_radius; + return (sin(point.x) * sin(point.y)) * 4.0; + } + void main(void) { + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 finalColor = texture2D(u_diffuseTexture, testCoord); + if(u_grayMode) { + float average = (finalColor.r + finalColor.g + finalColor.b) / 3.0; + gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern(u_angle,testCoord)), finalColor.a); + }else{ + vec3 cmy = 1.0 - finalColor.rgb; + float k = min(cmy.x, min(cmy.y, cmy.z)); + cmy = (cmy - k) / (1.0 - k); + cmy = clamp(cmy * 10.0 - 3.0 + vec3(pattern(u_angle + 0.26179,testCoord), pattern(u_angle + 1.30899,testCoord), pattern(u_angle,testCoord)), 0.0, 1.0); + k = clamp(k * 10.0 - 5.0 + pattern(u_angle + 0.78539,testCoord), 0.0, 1.0); + gl_FragColor = vec4(1.0 - cmy - k, finalColor.a); + } + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_HalfTone`, + description : ` + HalfTone 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/pixelate/RedFilter_HalfTone.html', + example : ` + var effect; + effect = RedFilter_HalfTone(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_HalfTone Instance' + } + :DOC*/ + RedFilter_HalfTone = function (redGL) { + if (!(this instanceof RedFilter_HalfTone)) return new RedFilter_HalfTone(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_HalfTone : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['centerX'] = 0.0; + this['centerY'] = 0.0; + this['angle'] = 0; + this['radius'] = 2; + this['grayMode'] = false; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_HalfTone.prototype = new RedBaseFilter(); + RedFilter_HalfTone.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_HalfTone', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`centerX`, + description : ` + 기본값 0.0 + `, + return : 'Number' + } + :DOC*/ + ['centerX', 'number'], + /*DOC: + { + code : 'PROPERTY', + title :`centerY`, + description : ` + 기본값 0.0 + `, + return : 'Number' + } + :DOC*/ + ['centerY', 'number'], + /*DOC: + { + code : 'PROPERTY', + title :`angle`, + description : ` + 기본값 0.0 + `, + return : 'Number' + } + :DOC*/ + ['angle', 'number'], + /*DOC: + { + code : 'PROPERTY', + title :`grayMode`, + description : ` + 기본값 false + `, + return : 'Boolean' + } + :DOC*/ + ['grayMode', 'boolean'], + /*DOC: + { + code : 'PROPERTY', + title :`radius`, + description : ` + 기본값 2 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['radius', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_HalfTone); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Bloom; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBloomProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform sampler2D u_blurTexture; + uniform float u_exposure; + uniform float u_bloomStrength; + + void main() { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + vec4 thresholdColor = finalColor; + vec4 blurColor = texture2D(u_blurTexture, gl_FragCoord.xy/vResolution.xy); + finalColor.rgb = (finalColor.rgb + blurColor.rgb * u_bloomStrength) * u_exposure; + gl_FragColor = finalColor ; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Bloom`, + description : ` + Bloom 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/bloom/RedFilter_Bloom.html', + example : ` + var effect; + effect = RedFilter_Bloom(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Bloom Instance' + } + :DOC*/ + RedFilter_Bloom = function (redGL) { + if (!(this instanceof RedFilter_Bloom)) return new RedFilter_Bloom(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Bloom : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['blurTexture'] = null; + this['exposure'] = 1; + this['bloomStrength'] = 1.2; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['_process'] = [ + RedFilter_BloomThreshold(redGL), + RedFilter_BlurX(redGL), + RedFilter_BlurY(redGL) + ]; + this['blur'] = 20; + this['threshold'] = 75; + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Bloom.prototype = new RedBaseFilter(); + RedFilter_Bloom.prototype['updateTexture'] = function (lastFrameBufferTexture, parentFrameBufferTexture) { + this['diffuseTexture'] = parentFrameBufferTexture; + this['blurTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Bloom', + ['diffuseTexture', 'sampler2D'], + ['blurTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`exposure`, + description : ` + 확산 강도. + 기본값 : 1 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['exposure', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`bloomStrength`, + description : ` + 블룸 강도 + 기본값 : 1.2 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['bloomStrength', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`threshold`, + description : ` + 최소 유효값 + 기본값 : 75 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['threshold', 'number', { + min: 0, + callback: function (v) { + this['_process'][0]['threshold'] = v; + this['_threshold'] = this['_process'][0]['threshold'] + } + }], + /*DOC: + { + code : 'PROPERTY', + title :`blur`, + description : ` + blur 정도. + 기본값 : 20 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['blur', 'number', { + min: 0, callback: function (v) { + this['_process'][1]['size'] = v; + this['_process'][2]['size'] = v; + } + }] + ); + Object.freeze(RedFilter_Bloom); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_BloomThreshold; +(function () { + var vSource, fSource; + var PROGRAM_NAME; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_threshold_value; + + void main() { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + if(0.2126 * finalColor.r + 0.7152 * finalColor.g + 0.0722 * finalColor.b < u_threshold_value) finalColor.r = finalColor.g = finalColor.b = 0.0; + gl_FragColor = finalColor; + } + */ + }; + PROGRAM_NAME = 'RedFilterBloomThresholdProgram'; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BloomThreshold`, + description : ` + BloomThreshold 이펙트 + RedFilter_Bloom 내부에서 사용하는 절차 이펙트 + 시스템적으로 사용됨. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + example : ` + var effect; + effect = RedFilter_BloomThreshold(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BloomThreshold Instance' + } + :DOC*/ + RedFilter_BloomThreshold = function (redGL) { + if (!(this instanceof RedFilter_BloomThreshold)) return new RedFilter_BloomThreshold(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BloomThreshold : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['renderScale'] = 0.5 + this['threshold'] = 128; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BloomThreshold.prototype = new RedBaseFilter(); + RedFilter_BloomThreshold.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BloomThreshold', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`threshold`, + description : ` + 최소 유효값 + 기본값 : 128 + `, + return : 'Number' + } + :DOC*/ + [ + 'threshold', 'number', + { + min: 0, max: 255, callback: function (v) { + this['_threshold_value'] = v / 255 + } + } + ] + ); + Object.freeze(RedFilter_BloomThreshold); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ + +"use strict"; +var RedFilter_Film; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterFilmProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform bool u_grayMode; + uniform sampler2D u_diffuseTexture; + uniform float u_noiseIntensity; // noise effect intensity value (0 = no effect, 1 = full effect) + uniform float u_scanlineIntensity; // scanlines effect intensity value (0 = no effect, 1 = full effect) + uniform float u_scanlineCount; // scanlines effect count value (0 = no effect, 4096 = full effect) + + void main() { + // sample the source + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 diffuseColor = texture2D( u_diffuseTexture, testCoord ); + + // make some noise + float x = testCoord.x * testCoord.y * vTime; + x = mod( x, 13.0 ) * mod( x, 123.0 ); + float dx = mod( x, 0.01 ); + + // add noise + vec3 finalColor = diffuseColor.rgb + diffuseColor.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 ); + + // get us a sine and cosine + vec2 sc = vec2( sin( testCoord.y * u_scanlineCount ), cos( testCoord.y * u_scanlineCount ) ); + + // add scanlines + finalColor += diffuseColor.rgb * vec3( sc.x, sc.y, sc.x ) * u_scanlineIntensity; + + // interpolate between source and result by intensity + finalColor = diffuseColor.rgb + clamp( u_noiseIntensity, 0.0, 1.0 ) * ( finalColor - diffuseColor.rgb ); + + // convert to grayscale if desired + if( u_grayMode ) finalColor = vec3( finalColor.r * 0.3 + finalColor.g * 0.59 + finalColor.b * 0.11 ); + gl_FragColor = vec4( finalColor, diffuseColor.a ); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Film`, + description : ` + Film 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/RedFilter_Film.html', + example : ` + var effect; + effect = RedFilter_Film(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Film Instance' + } + :DOC*/ + RedFilter_Film = function (redGL) { + if (!(this instanceof RedFilter_Film)) return new RedFilter_Film(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Film : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['grayMode'] = false; + this['scanlineIntensity'] = 0.5; + this['noiseIntensity'] = 0.5; + this['scanlineCount'] = 2048; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Film.prototype = new RedBaseFilter(); + RedFilter_Film.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Film', + [ 'diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`grayMode`, + description : ` + 그레이모드 + 기본값 : false + `, + return : 'Boolean' + } + :DOC*/ + [ 'grayMode', 'boolean'], + /*DOC: + { + code : 'PROPERTY', + title :`scanlineIntensity`, + description : ` + 스캔라인강도 + 기본값 : 0.5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + [ 'scanlineIntensity', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`noiseIntensity`, + description : ` + 노이즈강도 + 기본값 : 0.5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + [ 'noiseIntensity', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`scanlineCount`, + description : ` + 스캔라인 수 + 기본값 : 2048 + min : 0 + `, + return : 'Number' + } + :DOC*/ + [ 'scanlineCount', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_Film); +})(); +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:32:14 + * + */ + +"use strict"; +var RedFilter_Convolution; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterConvolutionProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision mediump float; + uniform sampler2D u_diffuseTexture; + uniform mat3 u_kernel; + uniform float uKernelWeight; + void main(void) { + vec2 perPX = vec2(1.0/vResolution.x, 1.0/vResolution.y); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 finalColor = vec4(0.0); + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, -1.0)) * u_kernel[0][0] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, -1.0)) * u_kernel[0][1] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, -1.0)) * u_kernel[0][2] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, 0.0)) * u_kernel[1][0] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, 0.0)) * u_kernel[1][1] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, 0.0)) * u_kernel[1][2] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, 1.0)) * u_kernel[2][0] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, 1.0)) * u_kernel[2][1] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, 1.0)) * u_kernel[2][2] ; + gl_FragColor = vec4((finalColor / uKernelWeight).rgb, finalColor.a); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Convolution`, + description : ` + Convolution 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/RedFilter_Convolution.html', + example : ` + var effect; + effect = RedFilter_DoF(RedGL Instance, RedFilter_Convolution.SHARPEN); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Convolution Instance' + } + :DOC*/ + RedFilter_Convolution = function (redGL, kernel) { + if (!(this instanceof RedFilter_Convolution)) return new RedFilter_Convolution(redGL, kernel); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Convolution : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['kernel'] = kernel; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Convolution.prototype = new RedBaseFilter(); + RedFilter_Convolution.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Convolution', 'diffuseTexture', 'sampler2D'); + /*DOC: + { + code : 'PROPERTY', + title :`kernel`, + description : ` + 커널값. + 3 * 3 매트릭스 형식의 배열 + `, + return : 'Array' + } + :DOC*/ + Object.defineProperty(RedFilter_Convolution.prototype, 'kernel', { + get: function () { + if (!this['_kernel']) this['_kernel'] = RedFilter_Convolution['NORMAL']; + return this['_kernel'] + }, + set: function (v) { + this['_kernel'] = v + } + }); + Object.defineProperty(RedFilter_Convolution.prototype, 'kernelWeight', (function () { + var sum; + var k; + return { + get: function () { + sum = 0; + for (k in this['kernel']) sum += this['kernel'][k]; + return sum; + } + } + })()); + /*DOC: + { + title :`RedFilter_Convolution.NORMAL`, + code : 'CONST', + description : ` + + [ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['NORMAL'] = [ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + ]; + /*DOC: + { + title :`RedFilter_Convolution.SHARPEN`, + code : 'CONST', + description : ` + + [ + 0, -1, 0, + -1, 5, -1, + 0, -1, 0 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['SHARPEN'] = [ + 0, -1, 0, + -1, 5, -1, + 0, -1, 0 + ]; + /*DOC: + { + title :`RedFilter_Convolution.BLUR`, + code : 'CONST', + description : ` + + [ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['BLUR'] = [ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + ]; + /*DOC: + { + title :`RedFilter_Convolution.EDGE`, + code : 'CONST', + description : ` + + [ + 0, 1, 0, + 1, -4, 1, + 0, 1, 0 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['EDGE'] = [ + 0, 1, 0, + 1, -4, 1, + 0, 1, 0 + ]; + /*DOC: + { + title :`RedFilter_Convolution.EMBOSS`, + code : 'CONST', + description : ` + + [ + -2, -1, 0, + -1, 1, 1, + 0, 1, 2 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['EMBOSS'] = [ + -2, -1, 0, + -1, 1, 1, + 0, 1, 2 + ]; + Object.freeze(RedFilter_Convolution); +})(); /* * RedGL - MIT License * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) @@ -27379,4 +30446,4 @@ var RedGLOffScreen; }; RedWorkerCode = RedWorkerCode.toString().replace(/^function ?. ?\) ?\{|\}\;?$/g, ''); })(); -})();var RedGL_VERSION = {version : 'RedGL Release. last update( 2019-07-09 12:27:18)' };console.log(RedGL_VERSION); \ No newline at end of file +})();var RedGL_VERSION = {version : 'RedGL Release. last update( 2019-08-07 11:46:16)' };console.log(RedGL_VERSION); \ No newline at end of file diff --git a/release/RedGL.min.js b/release/RedGL.min.js index 734e7e64..549ff927 100644 --- a/release/RedGL.min.js +++ b/release/RedGL.min.js @@ -2,11 +2,11 @@ * RedGL - MIT License * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.7.9 12:29:10 + * Last modification time of this file - 2019.8.7 11:52:14 * */ -var RedDefinePropertyInfo,RedGLDetect,RedGLUtil,RedGL,RedBoxSelection,RedBaseController,RedImageLoader,RedBaseTexture,RedBaseObject3D,RedBaseContainer,RedBaseLight,RedFrameBuffer,RedBuffer,RedGeometry,RedInterleaveInfo,RedBaseMaterial,RedTextureOptionChecker,RedBitmapTexture,RedVideoTexture,RedDDSTexture,RedBitmapCubeTexture,RedColorMaterial,RedColorPhongMaterial,RedColorPhongTextureMaterial,RedEnvironmentMaterial,RedBitmapMaterial,RedParticleMaterial,RedBitmapPointCloudMaterial,RedSheetMaterial,RedStandardMaterial,RedVideoMaterial,RedPBRMaterial,RedColorPointCloudMaterial,RedPBRMaterial_System,RedTextMaterial,RedAmbientLight,RedDirectionalLight,RedPointLight,RedMTLLoader,RedOBJLoader,Red3DSLoader,RedDAELoader,RedGLTFLoader,RedLinePoint,RedLathe,RedAxis,RedGrid,RedMesh,RedLine,RedLatheMesh,RedSkyBox,RedSprite3D,RedTransformController,RedPointCloud,RedParticleUnit,RedColorPointCloud,RedBitmapPointCloud,RedParticleEmitter,RedBox,RedCylinder,RedPlane,RedSphere,RedProgram,RedSystemShaderCode,RedShader,RedRenderer,RedRenderDebuger,RedSystemUniformUpdater,RedView,RedWorld,RedScene,RedCamera,RedBasicController,RedObitController,RedGridMaterial,RedSkyBoxMaterial,RedDirectionalShadowMaterial,RedPostEffectMaterial,RedDirectionalShadow,RedShadowManager,RedText,RedMouseEventManager,RedMouseEventMaterial,RedPostEffectManager,RedBasePostEffect,RedPostEffect_Bloom,RedPostEffect_BloomThreshold,RedPostEffect_Blur,RedPostEffect_BlurX,RedPostEffect_BlurY,RedPostEffect_GaussianBlur,RedPostEffect_ZoomBlur,RedPostEffect_BrightnessContrast,RedPostEffect_Threshold,RedPostEffect_Invert,RedPostEffect_Gray,RedPostEffect_HueSaturation,RedPostEffect_HalfTone,RedPostEffect_Pixelize,RedPostEffect_Convolution,RedPostEffect_DoF,RedPostEffect_DoF_DepthMaterial,RedPostEffect_Film,RedPostEffect_Vignetting,RedPostEffect_FXAA,RedGLOffScreen;!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r=t();for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,function(){return function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,i){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=4)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setMatrixArrayType=function(e){t.ARRAY_TYPE=e},t.toRadian=function(e){return e*n},t.equals=function(e,t){return Math.abs(e-t)<=i*Math.max(1,Math.abs(e),Math.abs(t))};var i=t.EPSILON=1e-6,n=(t.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,t.RANDOM=Math.random,Math.PI/180)},function(e,t,r){"use strict";function i(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],d=t[5],u=t[6],c=t[7],l=t[8],f=r[0],h=r[1],R=r[2],m=r[3],p=r[4],_=r[5],g=r[6],v=r[7],E=r[8];return e[0]=f*i+h*o+R*u,e[1]=f*n+h*s+R*c,e[2]=f*a+h*d+R*l,e[3]=m*i+p*o+_*u,e[4]=m*n+p*s+_*c,e[5]=m*a+p*d+_*l,e[6]=g*i+v*o+E*u,e[7]=g*n+v*s+E*c,e[8]=g*a+v*d+E*l,e}function n(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e[3]=t[3]-r[3],e[4]=t[4]-r[4],e[5]=t[5]-r[5],e[6]=t[6]-r[6],e[7]=t[7]-r[7],e[8]=t[8]-r[8],e}Object.defineProperty(t,"__esModule",{value:!0}),t.sub=t.mul=void 0,t.create=function(){var e=new a.ARRAY_TYPE(9);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat4=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e},t.clone=function(e){var t=new a.ARRAY_TYPE(9);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e},t.fromValues=function(e,t,r,i,n,o,s,d,u){var c=new a.ARRAY_TYPE(9);return c[0]=e,c[1]=t,c[2]=r,c[3]=i,c[4]=n,c[5]=o,c[6]=s,c[7]=d,c[8]=u,c},t.set=function(e,t,r,i,n,a,o,s,d,u){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e[4]=a,e[5]=o,e[6]=s,e[7]=d,e[8]=u,e},t.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.transpose=function(e,t){if(e===t){var r=t[1],i=t[2],n=t[5];e[1]=t[3],e[2]=t[6],e[3]=r,e[5]=t[7],e[6]=i,e[7]=n}else e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8];return e},t.invert=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],d=t[6],u=t[7],c=t[8],l=c*o-s*u,f=-c*a+s*d,h=u*a-o*d,R=r*l+i*f+n*h;return R?(R=1/R,e[0]=l*R,e[1]=(-c*i+n*u)*R,e[2]=(s*i-n*o)*R,e[3]=f*R,e[4]=(c*r-n*d)*R,e[5]=(-s*r+n*a)*R,e[6]=h*R,e[7]=(-u*r+i*d)*R,e[8]=(o*r-i*a)*R,e):null},t.adjoint=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],d=t[6],u=t[7],c=t[8];return e[0]=o*c-s*u,e[1]=n*u-i*c,e[2]=i*s-n*o,e[3]=s*d-a*c,e[4]=r*c-n*d,e[5]=n*a-r*s,e[6]=a*u-o*d,e[7]=i*d-r*u,e[8]=r*o-i*a,e},t.determinant=function(e){var t=e[0],r=e[1],i=e[2],n=e[3],a=e[4],o=e[5],s=e[6],d=e[7],u=e[8];return t*(u*a-o*d)+r*(-u*n+o*s)+i*(d*n-a*s)},t.multiply=i,t.translate=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],d=t[5],u=t[6],c=t[7],l=t[8],f=r[0],h=r[1];return e[0]=i,e[1]=n,e[2]=a,e[3]=o,e[4]=s,e[5]=d,e[6]=f*i+h*o+u,e[7]=f*n+h*s+c,e[8]=f*a+h*d+l,e},t.rotate=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],d=t[5],u=t[6],c=t[7],l=t[8],f=Math.sin(r),h=Math.cos(r);return e[0]=h*i+f*o,e[1]=h*n+f*s,e[2]=h*a+f*d,e[3]=h*o-f*i,e[4]=h*s-f*n,e[5]=h*d-f*a,e[6]=u,e[7]=c,e[8]=l,e},t.scale=function(e,t,r){var i=r[0],n=r[1];return e[0]=i*t[0],e[1]=i*t[1],e[2]=i*t[2],e[3]=n*t[3],e[4]=n*t[4],e[5]=n*t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e},t.fromTranslation=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=t[0],e[7]=t[1],e[8]=1,e},t.fromRotation=function(e,t){var r=Math.sin(t),i=Math.cos(t);return e[0]=i,e[1]=r,e[2]=0,e[3]=-r,e[4]=i,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromScaling=function(e,t){return e[0]=t[0],e[1]=0,e[2]=0,e[3]=0,e[4]=t[1],e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat2d=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=0,e[3]=t[2],e[4]=t[3],e[5]=0,e[6]=t[4],e[7]=t[5],e[8]=1,e},t.fromQuat=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r+r,s=i+i,d=n+n,u=r*o,c=i*o,l=i*s,f=n*o,h=n*s,R=n*d,m=a*o,p=a*s,_=a*d;return e[0]=1-l-R,e[3]=c-_,e[6]=f+p,e[1]=c+_,e[4]=1-u-R,e[7]=h-m,e[2]=f-p,e[5]=h+m,e[8]=1-u-l,e},t.normalFromMat4=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],d=t[6],u=t[7],c=t[8],l=t[9],f=t[10],h=t[11],R=t[12],m=t[13],p=t[14],_=t[15],g=r*s-i*o,v=r*d-n*o,E=r*u-a*o,M=i*d-n*s,b=i*u-a*s,L=n*u-a*d,P=c*m-l*R,T=c*p-f*R,y=c*_-h*R,x=l*p-f*m,w=l*_-h*m,I=f*_-h*p,U=g*I-v*w+E*x+M*y-b*T+L*P;return U?(U=1/U,e[0]=(s*I-d*w+u*x)*U,e[1]=(d*y-o*I-u*T)*U,e[2]=(o*w-s*y+u*P)*U,e[3]=(n*w-i*I-a*x)*U,e[4]=(r*I-n*y+a*T)*U,e[5]=(i*y-r*w-a*P)*U,e[6]=(m*L-p*b+_*M)*U,e[7]=(p*E-R*L-_*v)*U,e[8]=(R*b-m*E+_*g)*U,e):null},t.projection=function(e,t,r){return e[0]=2/t,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/r,e[5]=0,e[6]=-1,e[7]=1,e[8]=1,e},t.str=function(e){return"mat3("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+", "+e[4]+", "+e[5]+", "+e[6]+", "+e[7]+", "+e[8]+")"},t.frob=function(e){return Math.sqrt(Math.pow(e[0],2)+Math.pow(e[1],2)+Math.pow(e[2],2)+Math.pow(e[3],2)+Math.pow(e[4],2)+Math.pow(e[5],2)+Math.pow(e[6],2)+Math.pow(e[7],2)+Math.pow(e[8],2))},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e[4]=t[4]+r[4],e[5]=t[5]+r[5],e[6]=t[6]+r[6],e[7]=t[7]+r[7],e[8]=t[8]+r[8],e},t.subtract=n,t.multiplyScalar=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*r,e[5]=t[5]*r,e[6]=t[6]*r,e[7]=t[7]*r,e[8]=t[8]*r,e},t.multiplyScalarAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e[4]=t[4]+r[4]*i,e[5]=t[5]+r[5]*i,e[6]=t[6]+r[6]*i,e[7]=t[7]+r[7]*i,e[8]=t[8]+r[8]*i,e},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[3],s=e[4],d=e[5],u=e[6],c=e[7],l=e[8],f=t[0],h=t[1],R=t[2],m=t[3],p=t[4],_=t[5],g=t[6],v=t[7],E=t[8];return Math.abs(r-f)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(f))&&Math.abs(i-h)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(h))&&Math.abs(n-R)<=a.EPSILON*Math.max(1,Math.abs(n),Math.abs(R))&&Math.abs(o-m)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(m))&&Math.abs(s-p)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(p))&&Math.abs(d-_)<=a.EPSILON*Math.max(1,Math.abs(d),Math.abs(_))&&Math.abs(u-g)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(g))&&Math.abs(c-v)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(v))&&Math.abs(l-E)<=a.EPSILON*Math.max(1,Math.abs(l),Math.abs(E))};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.mul=i,t.sub=n},function(e,t,r){"use strict";function i(){var e=new R.ARRAY_TYPE(3);return e[0]=0,e[1]=0,e[2]=0,e}function n(e){var t=e[0],r=e[1],i=e[2];return Math.sqrt(t*t+r*r+i*i)}function a(e,t,r){var i=new R.ARRAY_TYPE(3);return i[0]=e,i[1]=t,i[2]=r,i}function o(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e}function s(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e[2]=t[2]*r[2],e}function d(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e[2]=t[2]/r[2],e}function u(e,t){var r=t[0]-e[0],i=t[1]-e[1],n=t[2]-e[2];return Math.sqrt(r*r+i*i+n*n)}function c(e,t){var r=t[0]-e[0],i=t[1]-e[1],n=t[2]-e[2];return r*r+i*i+n*n}function l(e){var t=e[0],r=e[1],i=e[2];return t*t+r*r+i*i}function f(e,t){var r=t[0],i=t[1],n=t[2],a=r*r+i*i+n*n;return a>0&&(a=1/Math.sqrt(a),e[0]=t[0]*a,e[1]=t[1]*a,e[2]=t[2]*a),e}function h(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.len=t.sqrDist=t.dist=t.div=t.mul=t.sub=void 0,t.create=i,t.clone=function(e){var t=new R.ARRAY_TYPE(3);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t},t.length=n,t.fromValues=a,t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e},t.set=function(e,t,r,i){return e[0]=t,e[1]=r,e[2]=i,e},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e},t.subtract=o,t.multiply=s,t.divide=d,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e[2]=Math.ceil(t[2]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e[2]=Math.floor(t[2]),e},t.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e[2]=Math.min(t[2],r[2]),e},t.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e[2]=Math.max(t[2],r[2]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e[2]=Math.round(t[2]),e},t.scale=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e},t.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e},t.distance=u,t.squaredDistance=c,t.squaredLength=l,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e},t.normalize=f,t.dot=h,t.cross=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],d=r[2];return e[0]=n*d-a*s,e[1]=a*o-i*d,e[2]=i*s-n*o,e},t.lerp=function(e,t,r,i){var n=t[0],a=t[1],o=t[2];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e[2]=o+i*(r[2]-o),e},t.hermite=function(e,t,r,i,n,a){var o=a*a,s=o*(2*a-3)+1,d=o*(a-2)+a,u=o*(a-1),c=o*(3-2*a);return e[0]=t[0]*s+r[0]*d+i[0]*u+n[0]*c,e[1]=t[1]*s+r[1]*d+i[1]*u+n[1]*c,e[2]=t[2]*s+r[2]*d+i[2]*u+n[2]*c,e},t.bezier=function(e,t,r,i,n,a){var o=1-a,s=o*o,d=a*a,u=s*o,c=3*a*s,l=3*d*o,f=d*a;return e[0]=t[0]*u+r[0]*c+i[0]*l+n[0]*f,e[1]=t[1]*u+r[1]*c+i[1]*l+n[1]*f,e[2]=t[2]*u+r[2]*c+i[2]*l+n[2]*f,e},t.random=function(e,t){t=t||1;var r=2*R.RANDOM()*Math.PI,i=2*R.RANDOM()-1,n=Math.sqrt(1-i*i)*t;return e[0]=Math.cos(r)*n,e[1]=Math.sin(r)*n,e[2]=i*t,e},t.transformMat4=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[3]*i+r[7]*n+r[11]*a+r[15];return o=o||1,e[0]=(r[0]*i+r[4]*n+r[8]*a+r[12])/o,e[1]=(r[1]*i+r[5]*n+r[9]*a+r[13])/o,e[2]=(r[2]*i+r[6]*n+r[10]*a+r[14])/o,e},t.transformMat3=function(e,t,r){var i=t[0],n=t[1],a=t[2];return e[0]=i*r[0]+n*r[3]+a*r[6],e[1]=i*r[1]+n*r[4]+a*r[7],e[2]=i*r[2]+n*r[5]+a*r[8],e},t.transformQuat=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],d=r[2],u=r[3],c=u*i+s*a-d*n,l=u*n+d*i-o*a,f=u*a+o*n-s*i,h=-o*i-s*n-d*a;return e[0]=c*u+h*-o+l*-d-f*-s,e[1]=l*u+h*-s+f*-o-c*-d,e[2]=f*u+h*-d+c*-s-l*-o,e},t.rotateX=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[0],a[1]=n[1]*Math.cos(i)-n[2]*Math.sin(i),a[2]=n[1]*Math.sin(i)+n[2]*Math.cos(i),e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},t.rotateY=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[2]*Math.sin(i)+n[0]*Math.cos(i),a[1]=n[1],a[2]=n[2]*Math.cos(i)-n[0]*Math.sin(i),e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},t.rotateZ=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[0]*Math.cos(i)-n[1]*Math.sin(i),a[1]=n[0]*Math.sin(i)+n[1]*Math.cos(i),a[2]=n[2],e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},t.angle=function(e,t){var r=a(e[0],e[1],e[2]),i=a(t[0],t[1],t[2]);f(r,r),f(i,i);var n=h(r,i);return n>1?0:n<-1?Math.PI:Math.acos(n)},t.str=function(e){return"vec3("+e[0]+", "+e[1]+", "+e[2]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],a=t[0],o=t[1],s=t[2];return Math.abs(r-a)<=R.EPSILON*Math.max(1,Math.abs(r),Math.abs(a))&&Math.abs(i-o)<=R.EPSILON*Math.max(1,Math.abs(i),Math.abs(o))&&Math.abs(n-s)<=R.EPSILON*Math.max(1,Math.abs(n),Math.abs(s))};var R=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.sub=o,t.mul=s,t.div=d,t.dist=u,t.sqrDist=c,t.len=n,t.sqrLen=l,t.forEach=function(){var e=i();return function(t,r,i,n,a,o){var s,d=void 0;for(r||(r=3),i||(i=0),s=n?Math.min(n*r+i,t.length):t.length,d=i;d0&&(o=1/Math.sqrt(o),e[0]=r*o,e[1]=i*o,e[2]=n*o,e[3]=a*o),e}Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.len=t.sqrDist=t.dist=t.div=t.mul=t.sub=void 0,t.create=i,t.clone=function(e){var t=new h.ARRAY_TYPE(4);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},t.fromValues=function(e,t,r,i){var n=new h.ARRAY_TYPE(4);return n[0]=e,n[1]=t,n[2]=r,n[3]=i,n},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},t.set=function(e,t,r,i,n){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e},t.subtract=n,t.multiply=a,t.divide=o,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e[2]=Math.ceil(t[2]),e[3]=Math.ceil(t[3]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e[2]=Math.floor(t[2]),e[3]=Math.floor(t[3]),e},t.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e[2]=Math.min(t[2],r[2]),e[3]=Math.min(t[3],r[3]),e},t.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e[2]=Math.max(t[2],r[2]),e[3]=Math.max(t[3],r[3]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e[2]=Math.round(t[2]),e[3]=Math.round(t[3]),e},t.scale=s,t.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e},t.distance=d,t.squaredDistance=u,t.length=c,t.squaredLength=l,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e[3]=1/t[3],e},t.normalize=f,t.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]},t.lerp=function(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e[2]=o+i*(r[2]-o),e[3]=s+i*(r[3]-s),e},t.random=function(e,t){return t=t||1,e[0]=h.RANDOM(),e[1]=h.RANDOM(),e[2]=h.RANDOM(),e[3]=h.RANDOM(),f(e,e),s(e,e,t),e},t.transformMat4=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3];return e[0]=r[0]*i+r[4]*n+r[8]*a+r[12]*o,e[1]=r[1]*i+r[5]*n+r[9]*a+r[13]*o,e[2]=r[2]*i+r[6]*n+r[10]*a+r[14]*o,e[3]=r[3]*i+r[7]*n+r[11]*a+r[15]*o,e},t.transformQuat=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],d=r[2],u=r[3],c=u*i+s*a-d*n,l=u*n+d*i-o*a,f=u*a+o*n-s*i,h=-o*i-s*n-d*a;return e[0]=c*u+h*-o+l*-d-f*-s,e[1]=l*u+h*-s+f*-o-c*-d,e[2]=f*u+h*-d+c*-s-l*-o,e[3]=t[3],e},t.str=function(e){return"vec4("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],a=e[3],o=t[0],s=t[1],d=t[2],u=t[3];return Math.abs(r-o)<=h.EPSILON*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(i-s)<=h.EPSILON*Math.max(1,Math.abs(i),Math.abs(s))&&Math.abs(n-d)<=h.EPSILON*Math.max(1,Math.abs(n),Math.abs(d))&&Math.abs(a-u)<=h.EPSILON*Math.max(1,Math.abs(a),Math.abs(u))};var h=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.sub=n,t.mul=a,t.div=o,t.dist=d,t.sqrDist=u,t.len=c,t.sqrLen=l,t.forEach=function(){var e=i();return function(t,r,i,n,a,o){var s,d=void 0;for(r||(r=4),i||(i=0),s=n?Math.min(n*r+i,t.length):t.length,d=i;d0?(i=2*Math.sqrt(r+1),e[3]=.25*i,e[0]=(t[6]-t[9])/i,e[1]=(t[8]-t[2])/i,e[2]=(t[1]-t[4])/i):t[0]>t[5]&t[0]>t[10]?(i=2*Math.sqrt(1+t[0]-t[5]-t[10]),e[3]=(t[6]-t[9])/i,e[0]=.25*i,e[1]=(t[1]+t[4])/i,e[2]=(t[8]+t[2])/i):t[5]>t[10]?(i=2*Math.sqrt(1+t[5]-t[0]-t[10]),e[3]=(t[8]-t[2])/i,e[0]=(t[1]+t[4])/i,e[1]=.25*i,e[2]=(t[6]+t[9])/i):(i=2*Math.sqrt(1+t[10]-t[0]-t[5]),e[3]=(t[1]-t[4])/i,e[0]=(t[8]+t[2])/i,e[1]=(t[6]+t[9])/i,e[2]=.25*i),e},t.fromRotationTranslationScale=function(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3],d=n+n,u=a+a,c=o+o,l=n*d,f=n*u,h=n*c,R=a*u,m=a*c,p=o*c,_=s*d,g=s*u,v=s*c,E=i[0],M=i[1],b=i[2];return e[0]=(1-(R+p))*E,e[1]=(f+v)*E,e[2]=(h-g)*E,e[3]=0,e[4]=(f-v)*M,e[5]=(1-(l+p))*M,e[6]=(m+_)*M,e[7]=0,e[8]=(h+g)*b,e[9]=(m-_)*b,e[10]=(1-(l+R))*b,e[11]=0,e[12]=r[0],e[13]=r[1],e[14]=r[2],e[15]=1,e},t.fromRotationTranslationScaleOrigin=function(e,t,r,i,n){var a=t[0],o=t[1],s=t[2],d=t[3],u=a+a,c=o+o,l=s+s,f=a*u,h=a*c,R=a*l,m=o*c,p=o*l,_=s*l,g=d*u,v=d*c,E=d*l,M=i[0],b=i[1],L=i[2],P=n[0],T=n[1],y=n[2];return e[0]=(1-(m+_))*M,e[1]=(h+E)*M,e[2]=(R-v)*M,e[3]=0,e[4]=(h-E)*b,e[5]=(1-(f+_))*b,e[6]=(p+g)*b,e[7]=0,e[8]=(R+v)*L,e[9]=(p-g)*L,e[10]=(1-(f+m))*L,e[11]=0,e[12]=r[0]+P-(e[0]*P+e[4]*T+e[8]*y),e[13]=r[1]+T-(e[1]*P+e[5]*T+e[9]*y),e[14]=r[2]+y-(e[2]*P+e[6]*T+e[10]*y),e[15]=1,e},t.fromQuat=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r+r,s=i+i,d=n+n,u=r*o,c=i*o,l=i*s,f=n*o,h=n*s,R=n*d,m=a*o,p=a*s,_=a*d;return e[0]=1-l-R,e[1]=c+_,e[2]=f-p,e[3]=0,e[4]=c-_,e[5]=1-u-R,e[6]=h+m,e[7]=0,e[8]=f+p,e[9]=h-m,e[10]=1-u-l,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,r,i,n,a,o){var s=1/(r-t),d=1/(n-i),u=1/(a-o);return e[0]=2*a*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*a*d,e[6]=0,e[7]=0,e[8]=(r+t)*s,e[9]=(n+i)*d,e[10]=(o+a)*u,e[11]=-1,e[12]=0,e[13]=0,e[14]=o*a*2*u,e[15]=0,e},t.perspective=function(e,t,r,i,n){var a=1/Math.tan(t/2),o=1/(i-n);return e[0]=a/r,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=a,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=(n+i)*o,e[11]=-1,e[12]=0,e[13]=0,e[14]=2*n*i*o,e[15]=0,e},t.perspectiveFromFieldOfView=function(e,t,r,i){var n=Math.tan(t.upDegrees*Math.PI/180),a=Math.tan(t.downDegrees*Math.PI/180),o=Math.tan(t.leftDegrees*Math.PI/180),s=Math.tan(t.rightDegrees*Math.PI/180),d=2/(o+s),u=2/(n+a);return e[0]=d,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=u,e[6]=0,e[7]=0,e[8]=-(o-s)*d*.5,e[9]=(n-a)*u*.5,e[10]=i/(r-i),e[11]=-1,e[12]=0,e[13]=0,e[14]=i*r/(r-i),e[15]=0,e},t.ortho=function(e,t,r,i,n,a,o){var s=1/(t-r),d=1/(i-n),u=1/(a-o);return e[0]=-2*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*d,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*u,e[11]=0,e[12]=(t+r)*s,e[13]=(n+i)*d,e[14]=(o+a)*u,e[15]=1,e},t.lookAt=function(e,t,r,i){var n=void 0,o=void 0,s=void 0,d=void 0,u=void 0,c=void 0,l=void 0,f=void 0,h=void 0,R=void 0,m=t[0],p=t[1],_=t[2],g=i[0],v=i[1],E=i[2],M=r[0],b=r[1],L=r[2];return Math.abs(m-M)0&&(c*=h=1/Math.sqrt(h),l*=h,f*=h);var R=d*f-u*l,m=u*c-s*f,p=s*l-d*c;return e[0]=R,e[1]=m,e[2]=p,e[3]=0,e[4]=l*p-f*m,e[5]=f*R-c*p,e[6]=c*m-l*R,e[7]=0,e[8]=c,e[9]=l,e[10]=f,e[11]=0,e[12]=n,e[13]=a,e[14]=o,e[15]=1,e},t.str=function(e){return"mat4("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+", "+e[4]+", "+e[5]+", "+e[6]+", "+e[7]+", "+e[8]+", "+e[9]+", "+e[10]+", "+e[11]+", "+e[12]+", "+e[13]+", "+e[14]+", "+e[15]+")"},t.frob=function(e){return Math.sqrt(Math.pow(e[0],2)+Math.pow(e[1],2)+Math.pow(e[2],2)+Math.pow(e[3],2)+Math.pow(e[4],2)+Math.pow(e[5],2)+Math.pow(e[6],2)+Math.pow(e[7],2)+Math.pow(e[8],2)+Math.pow(e[9],2)+Math.pow(e[10],2)+Math.pow(e[11],2)+Math.pow(e[12],2)+Math.pow(e[13],2)+Math.pow(e[14],2)+Math.pow(e[15],2))},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e[4]=t[4]+r[4],e[5]=t[5]+r[5],e[6]=t[6]+r[6],e[7]=t[7]+r[7],e[8]=t[8]+r[8],e[9]=t[9]+r[9],e[10]=t[10]+r[10],e[11]=t[11]+r[11],e[12]=t[12]+r[12],e[13]=t[13]+r[13],e[14]=t[14]+r[14],e[15]=t[15]+r[15],e},t.subtract=n,t.multiplyScalar=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*r,e[5]=t[5]*r,e[6]=t[6]*r,e[7]=t[7]*r,e[8]=t[8]*r,e[9]=t[9]*r,e[10]=t[10]*r,e[11]=t[11]*r,e[12]=t[12]*r,e[13]=t[13]*r,e[14]=t[14]*r,e[15]=t[15]*r,e},t.multiplyScalarAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e[4]=t[4]+r[4]*i,e[5]=t[5]+r[5]*i,e[6]=t[6]+r[6]*i,e[7]=t[7]+r[7]*i,e[8]=t[8]+r[8]*i,e[9]=t[9]+r[9]*i,e[10]=t[10]+r[10]*i,e[11]=t[11]+r[11]*i,e[12]=t[12]+r[12]*i,e[13]=t[13]+r[13]*i,e[14]=t[14]+r[14]*i,e[15]=t[15]+r[15]*i,e},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[11]===t[11]&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[15]===t[15]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[3],s=e[4],d=e[5],u=e[6],c=e[7],l=e[8],f=e[9],h=e[10],R=e[11],m=e[12],p=e[13],_=e[14],g=e[15],v=t[0],E=t[1],M=t[2],b=t[3],L=t[4],P=t[5],T=t[6],y=t[7],x=t[8],w=t[9],I=t[10],U=t[11],D=t[12],B=t[13],G=t[14],S=t[15];return Math.abs(r-v)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(v))&&Math.abs(i-E)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(E))&&Math.abs(n-M)<=a.EPSILON*Math.max(1,Math.abs(n),Math.abs(M))&&Math.abs(o-b)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(b))&&Math.abs(s-L)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(L))&&Math.abs(d-P)<=a.EPSILON*Math.max(1,Math.abs(d),Math.abs(P))&&Math.abs(u-T)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(T))&&Math.abs(c-y)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(y))&&Math.abs(l-x)<=a.EPSILON*Math.max(1,Math.abs(l),Math.abs(x))&&Math.abs(f-w)<=a.EPSILON*Math.max(1,Math.abs(f),Math.abs(w))&&Math.abs(h-I)<=a.EPSILON*Math.max(1,Math.abs(h),Math.abs(I))&&Math.abs(R-U)<=a.EPSILON*Math.max(1,Math.abs(R),Math.abs(U))&&Math.abs(m-D)<=a.EPSILON*Math.max(1,Math.abs(m),Math.abs(D))&&Math.abs(p-B)<=a.EPSILON*Math.max(1,Math.abs(p),Math.abs(B))&&Math.abs(_-G)<=a.EPSILON*Math.max(1,Math.abs(_),Math.abs(G))&&Math.abs(g-S)<=a.EPSILON*Math.max(1,Math.abs(g),Math.abs(S))};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.mul=i,t.sub=n},function(e,t,r){"use strict";function i(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}function n(){var e=new u.ARRAY_TYPE(4);return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}function a(e,t,r){r*=.5;var i=Math.sin(r);return e[0]=i*t[0],e[1]=i*t[1],e[2]=i*t[2],e[3]=Math.cos(r),e}function o(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=r[0],d=r[1],u=r[2],c=r[3];return e[0]=i*c+o*s+n*u-a*d,e[1]=n*c+o*d+a*s-i*u,e[2]=a*c+o*u+i*d-n*s,e[3]=o*c-i*s-n*d-a*u,e}function s(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3],d=r[0],u=r[1],c=r[2],l=r[3],f=void 0,h=void 0,R=void 0,m=void 0,p=void 0;return(h=n*d+a*u+o*c+s*l)<0&&(h=-h,d=-d,u=-u,c=-c,l=-l),1-h>1e-6?(f=Math.acos(h),R=Math.sin(f),m=Math.sin((1-i)*f)/R,p=Math.sin(i*f)/R):(m=1-i,p=i),e[0]=m*n+p*d,e[1]=m*a+p*u,e[2]=m*o+p*c,e[3]=m*s+p*l,e}function d(e,t){var r=t[0]+t[4]+t[8],i=void 0;if(r>0)i=Math.sqrt(r+1),e[3]=.5*i,i=.5/i,e[0]=(t[5]-t[7])*i,e[1]=(t[6]-t[2])*i,e[2]=(t[1]-t[3])*i;else{var n=0;t[4]>t[0]&&(n=1),t[8]>t[3*n+n]&&(n=2);var a=(n+1)%3,o=(n+2)%3;i=Math.sqrt(t[3*n+n]-t[3*a+a]-t[3*o+o]+1),e[n]=.5*i,i=.5/i,e[3]=(t[3*a+o]-t[3*o+a])*i,e[a]=(t[3*a+n]+t[3*n+a])*i,e[o]=(t[3*o+n]+t[3*n+o])*i}return e}Object.defineProperty(t,"__esModule",{value:!0}),t.setAxes=t.sqlerp=t.rotationTo=t.equals=t.exactEquals=t.normalize=t.sqrLen=t.squaredLength=t.len=t.length=t.lerp=t.dot=t.scale=t.mul=t.add=t.set=t.copy=t.fromValues=t.clone=void 0,t.create=n,t.identity=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},t.setAxisAngle=a,t.getAxisAngle=function(e,t){var r=2*Math.acos(t[3]),i=Math.sin(r/2);return 0!=i?(e[0]=t[0]/i,e[1]=t[1]/i,e[2]=t[2]/i):(e[0]=1,e[1]=0,e[2]=0),r},t.multiply=o,t.rotateX=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),d=Math.cos(r);return e[0]=i*d+o*s,e[1]=n*d+a*s,e[2]=a*d-n*s,e[3]=o*d-i*s,e},t.rotateY=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),d=Math.cos(r);return e[0]=i*d-a*s,e[1]=n*d+o*s,e[2]=a*d+i*s,e[3]=o*d-n*s,e},t.rotateZ=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),d=Math.cos(r);return e[0]=i*d+n*s,e[1]=n*d-i*s,e[2]=a*d+o*s,e[3]=o*d-a*s,e},t.calculateW=function(e,t){var r=t[0],i=t[1],n=t[2];return e[0]=r,e[1]=i,e[2]=n,e[3]=Math.sqrt(Math.abs(1-r*r-i*i-n*n)),e},t.slerp=s,t.invert=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r*r+i*i+n*n+a*a,s=o?1/o:0;return e[0]=-r*s,e[1]=-i*s,e[2]=-n*s,e[3]=a*s,e},t.conjugate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e},t.fromMat3=d,t.fromEuler=function(e,t,r,i){var n=.5*Math.PI/180;t*=n,r*=n,i*=n;var a=Math.sin(t),o=Math.cos(t),s=Math.sin(r),d=Math.cos(r),u=Math.sin(i),c=Math.cos(i);return e[0]=a*d*c-o*s*u,e[1]=o*s*c+a*d*u,e[2]=o*d*u-a*s*c,e[3]=o*d*c+a*s*u,e},t.str=function(e){return"quat("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"};var u=i(r(0)),c=i(r(1)),l=i(r(2)),f=i(r(3)),h=(t.clone=f.clone,t.fromValues=f.fromValues,t.copy=f.copy,t.set=f.set,t.add=f.add,t.mul=o,t.scale=f.scale,t.dot=f.dot,t.lerp=f.lerp,t.length=f.length),R=(t.len=h,t.squaredLength=f.squaredLength),m=(t.sqrLen=R,t.normalize=f.normalize);t.exactEquals=f.exactEquals,t.equals=f.equals,t.rotationTo=function(){var e=l.create(),t=l.fromValues(1,0,0),r=l.fromValues(0,1,0);return function(i,n,o){var s=l.dot(n,o);return s<-.999999?(l.cross(e,t,n),l.len(e)<1e-6&&l.cross(e,r,n),l.normalize(e,e),a(i,e,Math.PI),i):s>.999999?(i[0]=0,i[1]=0,i[2]=0,i[3]=1,i):(l.cross(e,n,o),i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=1+s,m(i,i))}}(),t.sqlerp=function(){var e=n(),t=n();return function(r,i,n,a,o,d){return s(e,i,o,d),s(t,n,a,d),s(r,e,t,2*d*(1-d)),r}}(),t.setAxes=function(){var e=c.create();return function(t,r,i,n){return e[0]=i[0],e[3]=i[1],e[6]=i[2],e[1]=n[0],e[4]=n[1],e[7]=n[2],e[2]=-r[0],e[5]=-r[1],e[8]=-r[2],m(t,d(t,e))}}()},function(e,t,r){"use strict";function i(){var e=new l.ARRAY_TYPE(2);return e[0]=0,e[1]=0,e}function n(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e}function a(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e}function o(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e}function s(e,t){var r=t[0]-e[0],i=t[1]-e[1];return Math.sqrt(r*r+i*i)}function d(e,t){var r=t[0]-e[0],i=t[1]-e[1];return r*r+i*i}function u(e){var t=e[0],r=e[1];return Math.sqrt(t*t+r*r)}function c(e){var t=e[0],r=e[1];return t*t+r*r}Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.sqrDist=t.dist=t.div=t.mul=t.sub=t.len=void 0,t.create=i,t.clone=function(e){var t=new l.ARRAY_TYPE(2);return t[0]=e[0],t[1]=e[1],t},t.fromValues=function(e,t){var r=new l.ARRAY_TYPE(2);return r[0]=e,r[1]=t,r},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e},t.set=function(e,t,r){return e[0]=t,e[1]=r,e},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e},t.subtract=n,t.multiply=a,t.divide=o,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e},t.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e},t.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e},t.scale=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e},t.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e},t.distance=s,t.squaredDistance=d,t.length=u,t.squaredLength=c,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e},t.normalize=function(e,t){var r=t[0],i=t[1],n=r*r+i*i;return n>0&&(n=1/Math.sqrt(n),e[0]=t[0]*n,e[1]=t[1]*n),e},t.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]},t.cross=function(e,t,r){var i=t[0]*r[1]-t[1]*r[0];return e[0]=e[1]=0,e[2]=i,e},t.lerp=function(e,t,r,i){var n=t[0],a=t[1];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e},t.random=function(e,t){t=t||1;var r=2*l.RANDOM()*Math.PI;return e[0]=Math.cos(r)*t,e[1]=Math.sin(r)*t,e},t.transformMat2=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[2]*n,e[1]=r[1]*i+r[3]*n,e},t.transformMat2d=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[2]*n+r[4],e[1]=r[1]*i+r[3]*n+r[5],e},t.transformMat3=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[3]*n+r[6],e[1]=r[1]*i+r[4]*n+r[7],e},t.transformMat4=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[4]*n+r[12],e[1]=r[1]*i+r[5]*n+r[13],e},t.str=function(e){return"vec2("+e[0]+", "+e[1]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]},t.equals=function(e,t){var r=e[0],i=e[1],n=t[0],a=t[1];return Math.abs(r-n)<=l.EPSILON*Math.max(1,Math.abs(r),Math.abs(n))&&Math.abs(i-a)<=l.EPSILON*Math.max(1,Math.abs(i),Math.abs(a))};var l=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.len=u,t.sub=n,t.mul=a,t.div=o,t.dist=s,t.sqrDist=d,t.sqrLen=c,t.forEach=function(){var e=i();return function(t,r,i,n,a,o){var s,d=void 0;for(r||(r=2),i||(i=0),s=n?Math.min(n*r+i,t.length):t.length,d=i;dl&&(e=l),this["_"+r]=e,n.callback&&n.callback.call(this,e)}};break;case"uint":d=n.hasOwnProperty("min"),u=n.hasOwnProperty("max"),c=n.min,l=n.max;d&&c<0&&RedGLUtil.throwFunc(t+" - "+r+" : min옵션은 0보다 커야 함.","입력값 : "+c),u&&l<0&&RedGLUtil.throwFunc(t+" - "+r+" : max옵션은 0보다 커야 함.","입력값 : "+l),d&&u&&l<=c&&RedGLUtil.throwFunc(t+" - "+r+" : max옵션은 min옵션보다 커야 함.","min 입력값 : "+c,"max 입력값 : "+l),a={get:function(){return this["_"+r]},set:function(e){"number"!=typeof e&&RedGLUtil.throwFunc(t+" - "+r+" : uint만 허용함.","입력값 : "+e),d&&el&&(e=l),e>=0&&Math.floor(e)==e||RedGLUtil.throwFunc(t+" - "+r+" : uint만 허용함(소수점은 허용하지 않음).","입력값 : "+e),this["_"+r]=e,n.callback&&n.callback.call(this,e)}};break;case"int":d=n.hasOwnProperty("min"),u=n.hasOwnProperty("max"),c=n.min,l=n.max;d&&u&&l<=c&&RedGLUtil.throwFunc(t+" - "+r+" : max옵션은 min옵션보다 커야 함.","min 입력값 : "+c,"max 입력값 : "+l),a={get:s,set:function(e){"number"!=typeof e&&RedGLUtil.throwFunc(t+" - "+r+" : int만 허용함.","입력값 : "+e),d&&el&&(e=l),Math.floor(e)!=e&&RedGLUtil.throwFunc(t+" - "+r+" : int만 허용함(소수점은 허용하지 않음).","입력값 : "+e),this["_"+r]=e,n.callback&&n.callback.call(this,e)}};break;case"sampler2D":o="RedBaseTexture";break;case"samplerCube":o="RedBitmapCubeTexture";break;case"samplerVideo":o="RedVideoTexture";break;default:RedGLUtil.throwFunc(r+" - type : "+i+" / "+r+" : 정의할수없는 타입입니다.")}if(o){var f=window[o];a=n.essential?{get:s,set:function(e){f==RedBitmapCubeTexture?e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e):!(e instanceof RedBitmapCubeTexture)&&e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e),this["_"+r]=e,n.callback&&n.callback.call(this)}}:{get:s,set:function(e){e&&(f==RedBitmapCubeTexture?e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e):!(e instanceof RedBitmapCubeTexture)&&e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e)),this["_"+r]=e,n.callback&&n.callback.call(this)}}}e["_"+r]=null,Object.defineProperty(e,r,a)},(RedDefinePropertyInfo={}).definePrototype=function(t,r,i,n){e(window[t].prototype,t,r,i,n)},RedDefinePropertyInfo.definePrototypes=function(t){for(var r,i=arguments.length;i-- >1;)r=arguments[i],e(window[t].prototype,t,r[0],r[1],r[2])},Object.freeze(RedDefinePropertyInfo)}(),(RedGLDetect=function(e){if(!(this instanceof RedGLDetect))return new RedGLDetect(e);var t,r,i,n,a,o=this,s=e.gl;for(i in t={basic:["VENDOR","VERSION","SHADING_LANGUAGE_VERSION","RENDERER"],frameBuffer:["MAX_RENDERBUFFER_SIZE","MAX_VIEWPORT_DIMS","RED_BITS","GREEN_BITS","BLUE_BITS","ALPHA_BITS","DEPTH_BITS","STENCIL_BITS"],vertexShader:["MAX_VERTEX_ATTRIBS","MAX_VARYING_VECTORS","MAX_VERTEX_UNIFORM_VECTORS"],fragmentShader:["MAX_FRAGMENT_UNIFORM_VECTORS"],texture:["MAX_TEXTURE_SIZE","MAX_CUBE_MAP_TEXTURE_SIZE","MAX_COMBINED_TEXTURE_IMAGE_UNITS","MAX_TEXTURE_IMAGE_UNITS","MAX_VERTEX_TEXTURE_IMAGE_UNITS"]})for(r=(a=t[i]).length,this[i]={};r--;)this[i][n=a[r]]=s.getParameter(s[n]);this.BROWSER_INFO=RedGLDetect.getBrowserInfo(),"ie"==this.BROWSER_INFO.browser&&(console.table=console.log),requestAnimationFrame(function(){var t=document.createElement("canvas"),r=t.getContext("2d");t.width=10,t.height=20,r.fillStyle="red",r.fillRect(0,0,10,10),r.fillStyle="blue",r.fillRect(0,10,10,10),t.style.cssText="position:fixed;top:0px;left:0px";var i=RedBitmapTexture(e,t),n=s.createFramebuffer();s.bindFramebuffer(s.FRAMEBUFFER,n),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,i.webglTexture,0);var a=new Uint8Array(4);s.readPixels(0,0,1,1,s.RGBA,s.UNSIGNED_BYTE,a),s.bindFramebuffer(s.FRAMEBUFFER,null),o.ableCanvasSourceFlipYonTexture=255===a[0],o.BROWSER_INFO.ableCanvasSourceFlipYonTexture=255===a[0]})}).BROWSER_INFO={},RedGLDetect.getBrowserInfo=function(){var e,t,r,i,n,a=RedGLDetect.BROWSER_INFO,o=window.navigator,s=o.userAgent.toLowerCase(),d=o.platform.toLowerCase(),u=o.appVersion.toLowerCase(),c="pc",l=0,f=function(){return s.indexOf("whale")<0?0:(t=parseFloat(/whale\/([\d]+)/.exec(s)[1]),e="whale")},h=function(){if(!(s.indexOf(n="chrome")<0&&s.indexOf(n="crios")<0))return e="chrome",t=parseFloat(("chrome"===n?/chrome\/([\d]+)/:/crios\/([\d]+)/).exec(s)[1])},R=function(){return s.indexOf("firefox")<0?0:(e="firefox",t=parseFloat(/firefox\/([\d]+)/.exec(s)[1]))},m=function(){return s.indexOf("safari")<0?0:(e="safari",t=parseFloat(/safari\/([\d]+)/.exec(s)[1]))},p=function(){var r;return s.indexOf(r="opera")<0&&s.indexOf(r="opr")<0?0:(e="opera",t="opera"===r?parseFloat(/version\/([\d]+)/.exec(s)[1]):parseFloat(/opr\/([\d]+)/.exec(s)[1]))},_=function(){return s.indexOf("naver")<0?0:e="naver"};if(a||(a={}),s.indexOf("android")>-1)e=r="android",c=-1===s.indexOf("mobile")?(e+="Tablet","tablet"):"mobile",i=(n=/android ([\d.]+)/.exec(s))?(n=n[1].split("."),parseFloat(n[0]+"."+n[1])):0,l=1,f()||_()||p()||h()||R()||(t=n=/safari\/([\d.]+)/.exec(s)?parseFloat(n[1]):0);else if(s.indexOf(n="ipad")>-1||s.indexOf(n="iphone")>-1)c="ipad"===n?"tablet":"mobile",e=r=n,i=(n=/os ([\d_]+)/.exec(s))?(n=n[1].split("_"),parseFloat(n[0]+"."+n[1])):0,l=1,f()||_()||p()||h()||R()||(t=(n=/mobile\/([\S]+)/.exec(s))?parseFloat(n[1]):0);else if(d.indexOf("win")>-1){for(n in g={5.1:"xp","6.0":"vista",6.1:"7",6.2:"8",6.3:"8.1","10.0":"10"})if(s.indexOf("windows nt "+n)>-1){i=g[n];break}r="win",(s.indexOf("edge")>-1?(s.indexOf("iemobile")>-1&&(r="winMobile"),e="edge",t=/edge\/([\d]+)/.exec(s)[1]):s.indexOf("msie")<0&&s.indexOf("trident")<0?void 0:(s.indexOf("iemobile")>-1&&(r="winMobile"),e="ie",t=s.indexOf("msie 7")>-1&&s.indexOf("trident")>-1?-1:s.indexOf("msie")<0?11:parseFloat(/msie ([\d]+)/.exec(s)[1])))||f()||p()||h()||R()||m()}else d.indexOf("mac")>-1?(r="mac",n=/os x ([\d._]+)/.exec(s)[1].replace("_",".").split("."),i=parseFloat(n[0]+"."+n[1]),f()||p()||h()||R()||m()):(r=u.indexOf("x11")>-1?"unix":u.indexOf("linux")>-1?"linux":0,f()||h()||R());for(n in g={device:c,isMobile:l,browser:e,browserVer:t,os:r,osVer:i,down:l?"touchstart":"mousedown",move:l?"touchmove":"mousemove",up:l?"touchend":"mouseup",click:"click",over:"mouseover",out:"mouseout"})g.hasOwnProperty(n)&&(a[n]=g[n]);if(window.OffscreenCanvas){var g=new window.OffscreenCanvas(2,2);try{g.getContext("2d")}catch(e){window.OffscreenCanvas=null}}return a},Object.freeze(RedGLDetect),function(){var e,t,r,i,n,a,o,s,d,u,c,l,f,h;RedGLUtil={throwFunc:function(){throw"RedGL Error : "+Array.prototype.slice.call(arguments).join(" ")},isUint:function(e,t){return"number"==typeof e&&e>=0||RedGLUtil.throwFunc(t,"입력값 : "+e),Math.floor(e)===e||RedGLUtil.throwFunc(t,"입력값 : "+e),!0},hexToRGB_ZeroToOne:function(e){var t,r;if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(e))return r=[],3===(t=e.substring(1).split("")).length&&(t=[t[0],t[0],t[1],t[1],t[2],t[2]]),t="0x"+t.join(""),r[0]=(t>>16&255)/255,r[1]=(t>>8&255)/255,r[2]=(255&t)/255,r;RedGLUtil.throwFunc("RedGLUtil.hexToRGB_ZeroToOne : 잘못된 hex값입니다.",e)},rgb2hex:function(e,t,r){return"#"+(16777216+(r|t<<8|e<<16)).toString(16).slice(1)},regHex:(h=/^#(?:[0-9a-fA-F]{3}){1,2}$/,function(e){return h.test(e)}),getStrFromComment:function(e){if("string"!=typeof e&&RedGLUtil.throwFunc("getStrFromComment : 해석할 값은 문자열만 가능",e),f=e.replace("@preserve","").toString().trim().match(/(\/\*)[\s\S]+(\*\/)/g))return f[0].replace(/\/\*|\*\//g,"").trim();RedGLUtil.throwFunc("getStrFromComment : 해석할 불가능한 값",e)},isPowerOf2:function(e){return 0==(e&e-1)},nextHighestPowerOfTwo:function(e){for(--e,l=1;l<32;l<<=1)e|=e>>l;return e+1},makePowerOf2Source:function(e,t,r){if(c=r,RedGLUtil.isPowerOf2(t.width)&&RedGLUtil.isPowerOf2(t.height))return t;d=RedGLUtil.nextHighestPowerOfTwo(t.width),u=RedGLUtil.nextHighestPowerOfTwo(t.height),d>c&&(d=c),u>c&&(u=c);var i=window.OffscreenCanvas?new OffscreenCanvas(d,u):document.createElement("canvas"),n=i.getContext("2d");return window.OffscreenCanvas||(i.width=d,i.height=u),n.drawImage(t,0,0,d,u),window.OffscreenCanvas?i.transferToImageBitmap():i},calculateNormals:function(e,t){var r,i,n=[];for(r=0;r-1?u=(document.documentElement?document.documentElement.clientWidth:document.body.clientWidth)*parseFloat(u)/100:RedGLUtil.throwFunc("RedGL setSize : width는 0이상의 숫자나 %만 허용.","입력값 :",u)),"number"!=typeof c&&(c.indexOf("%")>-1?c=window.innerHeight*parseFloat(c)/100:RedGLUtil.throwFunc("RedGL setSize : height는 0이상의 숫자나 %만 허용.","입력값 :",c)),R=window.devicePixelRatio||1,m=this._canvas,(l!=u||h!=c||r)&&(m.width=u*R*this._renderScale,m.height=c*R*this._renderScale,m.style.width=u+"px",m.style.height=c+"px",l=u,h=c),this._viewRect[2]=l,this._viewRect[3]=h):(u=this._width=e,c=this._height=t,p[0]=u*this._renderScale,_[0]=c*this._renderScale,this._viewRect[2]=u,this._viewRect[3]=c)}),RedSystemShaderCode.init&&RedSystemShaderCode.init(d),t(d,s),f.push(d),void requestAnimationFrame(function(){r||(RedPBRMaterial_System(d),RedStandardMaterial(d,d._datas.emptyTexture["2d"]),RedEnvironmentMaterial(d,null,d._datas.emptyTexture["3d"])),d._mouseEventInfo=[],[RedGLDetect.BROWSER_INFO.move,RedGLDetect.BROWSER_INFO.down,RedGLDetect.BROWSER_INFO.up].forEach(function(e){var t,r;"ie"===RedGLDetect.BROWSER_INFO.browser&&11===RedGLDetect.BROWSER_INFO.browserVer?(t="offsetX",r="offsetY"):(t="layerX",r="layerY"),d._canvas.addEventListener(e,function(e){e.preventDefault(),RedGLDetect.BROWSER_INFO.isMobile?e.changedTouches[0]&&(d._mouseEventInfo.push({type:e.type,x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY,nativeEvent:e}),d._mouseX=e.changedTouches[0].clientX,d._mouseY=e.changedTouches[0].clientY):(d._mouseEventInfo.push({type:e.type,x:e[t],y:e[r],nativeEvent:e}),d._mouseX=e[t],d._mouseY=e[r])},!1)}),d.setSize(d._width,d._height),n&&n.call(d,!0)})):n?n.call(d,!1):void 0):new RedGL(i,n,a,o);var s,d,u,c,l,h,R,m,p,_}).makeUUID=(l=0,function(){return l++}),RedGL.prototype={},RedDefinePropertyInfo.definePrototype("RedGL","renderScale","number",{min:.1,max:1,callback:function(){this.setSize(this._width,this._height,!0)}}),RedGL.setDoNotPrepareProgram=function(){r=!0},Object.freeze(RedGL)}(),function(){var e,t,r,i,n,a={x:0,y:0},o={x:0,y:0},s=[];n=function(n,d){return RedGLDetect.BROWSER_INFO.isMobile?n.changedTouches?(o.x=n.changedTouches[0].clientX,o.y=n.changedTouches[0].clientY):(o.x=a.x,o.y=a.y):(o.x=n.clientX,o.y=n.clientY),t=o.x-a.x,r=o.y-a.y,s=[a.x,a.y,t,r],t<0&&(s[2]=Math.abs(t),s[0]+=t),r<0&&(s[3]=Math.abs(r),s[1]+=r),e.style.left=s[0]+"px",e.style.top=s[1]+"px",e.style.width=s[2]+"px",e.style.height=s[3]+"px",i(d.scene,d,s)},i=function(e,t,r,n){return n||(n={selectList:[],unSelectList:[]}),e.children.forEach(function(e){var a=e.getScreenPoint(t);r[0]<=a[0]&&r[1]<=a[1]&&r[0]+r[2]>=a[0]&&r[1]+r[3]>=a[1]?n.selectList.push(e):n.unSelectList.push(e),i(e,t,r,n)}),n},RedBoxSelection=function(t,r,i){return this instanceof RedBoxSelection?(t instanceof RedGL||RedGLUtil.throwFunc("RedBoxSelection : RedGL Instance만 허용.",t),r instanceof RedView||RedGLUtil.throwFunc("RedBoxSelection : RedView Instance만 허용.",r),t._datas.RedBoxSelection?this:(t._datas.RedBoxSelection=this,void[RedGLDetect.BROWSER_INFO.move,RedGLDetect.BROWSER_INFO.down,RedGLDetect.BROWSER_INFO.up].forEach(function(s){var d;d=function(e){var t=n(e,r);i&&i(t)},t._canvas.addEventListener(s,function(t){t.type===RedGLDetect.BROWSER_INFO.down&&(o.x=a.x=RedGLDetect.BROWSER_INFO.isMobile?t.changedTouches[0].clientX:t.clientX,o.y=a.y=RedGLDetect.BROWSER_INFO.isMobile?t.changedTouches[0].clientY:t.clientY,e||((e=document.createElement("div")).style.cssText="position:fixed;border:1px dashed red;z-index:0"),e.style.left="0px",e.style.top="0px",e.style.width="0px",e.style.height="0px",document.body.appendChild(e),r.camera&&r.camera.camera&&(r.camera.needUpdate=!1),d({}),window.addEventListener(RedGLDetect.BROWSER_INFO.move,d),window.addEventListener(RedGLDetect.BROWSER_INFO.isMobile?"touchend":"click",function(){r.camera.camera&&(r.camera.needUpdate=!0),e.parentNode&&document.body.removeChild(e),window.removeEventListener(RedGLDetect.BROWSER_INFO.move,d)}))})}))):new RedBoxSelection(t,r,i)}}(),(RedBaseController=function(){if(!(this instanceof RedBaseController))return new RedBaseController}).prototype={update:function(){RedGLUtil.throwFunc("RedBaseController : update - 재정의 해서 써라")}},Object.freeze(RedBaseController),function(){var e=function(e,t){return createImageBitmap(e,t||{imageOrientation:"none"})};RedImageLoader=function(t,r,i,n){var a,o,s,d,u=this;if(!(this instanceof RedImageLoader))return new RedImageLoader(t,r,i,n);("string"!=typeof t&&RedGLUtil.throwFunc("RedImageLoader : src는 문자열 만 허용.","입력값 : "+t),u._src=t,u._onLoad=r,u._onError=i,window&&window.document)?(d=function(e){e.removeEventListener("error",s),e.removeEventListener("load",o)},s=function(e){d(this),u._onError&&u._onError(e)},o=function(e){d(this),u.source=a,u._onLoad&&u._onLoad(e)},(a=new Image).crossOrigin="anonymous",a.src=t,a.addEventListener("error",s),a.addEventListener("load",o)):2===t.split(",").length&&"data:"===t.substr(0,5)?e(function(e,t){t=t||"";for(var r=atob(e),i=r.length,n=Math.ceil(i/1024),a=new Array(n),o=0;o4&&RedGLUtil.throwFunc("RedBaseObject3D - addLOD : level은 0~4 level 까지 허용함"),a={level:e,distance:t,geometry:r||this.geometry,material:i||this.material},s=this._lodLevels.length,o=!0;s--;)this._lodLevels[s].level==e&&(this._lodLevels[s]=a,o=!1);o&&this._lodLevels.push(a)},removeLOD:function(e){RedGLUtil.isUint(e)||RedGLUtil.throwFunc("RedBaseObject3D - removeLOD : level : uint만 허용함");for(var t=this._lodLevels.length;t--;)if(this._lodLevels[t].level==e){this._lodLevels.splice(t,1);break}},localToWorld:(n=mat4.create(),function(e,t,r){return"number"==typeof e||RedGLUtil.throwFunc("RedBaseObject3D - localToWorld : x - number만 허용함","입력값 : ",e),"number"==typeof t||RedGLUtil.throwFunc("RedBaseObject3D - localToWorld : y - number만 허용함","입력값 : ",t),"number"==typeof r||RedGLUtil.throwFunc("RedBaseObject3D - localToWorld : z - number만 허용함","입력값 : ",r),e=e||0,t=t||0,r=r||0,mat4.identity(n),mat4.translate(n,n,[e,t,r]),mat4.multiply(n,this.matrix,n),[n[12],n[13],n[14]]}),worldToLocal:function(){var e,t;return e=mat4.create(),t=mat4.create(),function(r,i,n){return"number"==typeof r||RedGLUtil.throwFunc("RedBaseObject3D - worldToLocal : x - number만 허용함","입력값 : ",r),"number"==typeof i||RedGLUtil.throwFunc("RedBaseObject3D - worldToLocal : y - number만 허용함","입력값 : ",i),"number"==typeof n||RedGLUtil.throwFunc("RedBaseObject3D - worldToLocal : z - number만 허용함","입력값 : ",n),r=r||0,i=i||0,n=n||0,mat4.translate(e,e,[r,i,n]),mat4.multiply(t,e,this.matrix),[t[0]*r+t[1]*i+t[2]*n+t[3],t[4]*r+t[5]*i+t[6]*n+t[7],t[8]*r+t[9]*i+t[10]*n+t[11]]}}(),getScreenPoint:(i=mat4.create(),r={x:0,y:0,z:0,w:0},function(n){return mat4.identity(i),n instanceof RedView||RedGLUtil.throwFunc("RedBaseObject3D - getScreenPoint : redView - RedView Instance 만 허용함","입력값 : ",n),e=n.camera,t=n._viewRect,e instanceof RedBaseController&&(e=e.camera),mat4.multiply(i,e.perspectiveMTX,e.matrix),mat4.multiply(i,i,this.matrix),r.x=i[12],r.y=i[13],r.z=i[14],r.w=i[15],r.x=.5*r.x/r.w+.5,r.y=.5*r.y/r.w+.5,[(t[0]+r.x*t[2])/window.devicePixelRatio,(t[1]+(1-r.y)*t[3])/window.devicePixelRatio]}),disposeAll:function(){this.disposeAllTexture(),this.disposeAllBuffer()},disposeAllTexture:function(){this.material&&this.material.disposeAllTexture()},disposeTexture:function(e){this.material&&this.material.disposeTexture(e)},disposeAllBuffer:function(){this.geometry&&this.geometry.disposeAllBuffer()},disposeBuffer:function(e){this.geometry&&this.geometry.disposeBuffer(e)}},c=function(e){var t,r,i,n,a,o,s,d,u,c,l,f,h,R,m,p,_=e.matrix,g=e.geometry.interleaveBuffer.stride;for(t=r=i=n=a=o=0,c=e.geometry.interleaveBuffer.data,l=0,f=e.geometry.interleaveBuffer.pointNum;ln?h:n,r=(R=_[1]*c[s]+_[5]*c[d]+_[9]*c[u])a?R:a,i=(m=_[2]*c[s]+_[6]*c[d]+_[10]*c[u])o?m:o;return(p=[n-t,a-r,o-i]).minX=t,p.maxX=n,p.minY=r,p.maxY=a,p.minZ=i,p.maxZ=o,p},d=function(e){var t=c(e),r=mat4.create();return mat4.translate(r,r,e.localToWorld(0,0,0)),mat4.scale(r,r,t),{worldMatrix:r,volume:t}},u=function(e){var t=e.geometry.volume,r=mat4.create();return mat4.translate(r,r,e.localToWorld(0,0,0)),mat4.rotateX(r,r,-e.rotationX*Math.PI/180),mat4.rotateY(r,r,-e.rotationY*Math.PI/180),mat4.rotateZ(r,r,-e.rotationZ*Math.PI/180),mat4.scale(r,r,t),mat4.scale(r,r,[e.scaleX,e.scaleY,e.scaleZ]),{worldMatrix:r,volume:c(e)}},RedBaseObject3D.prototype.volumeCalculateAABB=function(){return this.volumeInfo=d(this)},RedBaseObject3D.prototype.volumeCalculateOBB=function(){return this.volumeInfo=u(this)},RedBaseObject3D.prototype.lookAt=(l=new Float32Array([0,1,0]),f=[],h=[],function(e,t,r){f[0]=e,f[1]=t,f[2]=r,mat4.identity(this.matrix),mat4.targetTo(this.matrix,[this.x,this.y,this.z],f,l),h=RedGLUtil.mat4ToEuler(this.matrix,[]),this.rotationX=180*-h[0]/Math.PI,this.rotationY=180*-h[1]/Math.PI,this.rotationZ=180*-h[2]/Math.PI}),Object.defineProperty(RedBaseObject3D.prototype,"geometry",{get:function(){return this._geometry},set:function(e){!e||e instanceof RedGeometry||RedGLUtil.throwFunc("geometry : RedGeometry Instance만 허용.","입력값 : "+e),this._geometry=e}}),Object.defineProperty(RedBaseObject3D.prototype,"material",{get:function(){return this._material},set:function(e){!e||e instanceof RedBaseMaterial||RedGLUtil.throwFunc("material : RedBaseMaterial Instance만 허용.","입력값 : "+e),this._material=e}}),Object.freeze(RedBaseObject3D)}(),function(){var e,t;(e=(RedBaseContainer=function(){if(!(this instanceof RedBaseContainer))return new RedBaseContainer;this.children=[]}).prototype=new RedBaseObject3D).addChild=function(e){e instanceof RedBaseObject3D||RedGLUtil.throwFunc("addChild","RedBaseObject3D Instance만 가능","입력값 : "+e),this.children.indexOf(e)>-1&&this.removeChild(e),this.children.push(e)},e.addChildAt=function(e,t){RedGLUtil.isUint(t,"addChildAt : index는 uint만 입력가능"),e instanceof RedBaseObject3D||RedGLUtil.throwFunc("addChildAt","RedBaseObject3D Instance만 가능","입력값 : "+e),this.children.indexOf(e)>-1&&this.removeChild(e),this.children.lengtht)return 1}return 0})},e.sortMaterial=function(e){if(e)for(var t=this.children.length;t--;)this.children[t].sortMaterial&&this.children[t].sortMaterial(e);this.children.sort(function(e,t){if(e._geometry&&t._geometry){if((e=e._material.program._UUID)<(t=t._material.program._UUID))return-1;if(e>t)return 1}return 0})},e.sortGeometryAndMaterial=function(e){if(e)for(var t=this.children.length;t--;)this.children[t].sortGeometryAndMaterial&&this.children[t].sortGeometryAndMaterial(e);this.children.sort(function(e,t){if(e._geometry&&t._geometry){if((e=e._geometry.interleaveBuffer._UUID)==(t=t._geometry.interleaveBuffer._UUID)){var r=e._material.program._UUID,i=t._material.program._UUID;return ri?1:0}if(et)return 1}return 0})},Object.freeze(RedBaseContainer)}(),function(){var e;(RedBaseLight=function(){if(!(this instanceof RedBaseLight))return new RedBaseLight}).prototype={},RedDefinePropertyInfo.definePrototypes("RedBaseLight",["intensity","number",{min:0}],["alpha","number",{min:0,max:1,callback:function(e){this._lightColor[3]=this._alpha=e}}],["color","hex",{callback:function(){e=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._color),this._lightColor[0]=e[0],this._lightColor[1]=e[1],this._lightColor[2]=e[2],this._lightColor[3]=this._alpha}}]),Object.freeze(RedBaseLight)}(),(RedFrameBuffer=function(e,t,r){if(!(this instanceof RedFrameBuffer))return new RedFrameBuffer(e,t,r);var i;e instanceof RedGL||RedGLUtil.throwFunc("RedFrameBuffer : RedGL Instance만 허용.",e),t&&("number"==typeof t||RedGLUtil.throwFunc("RedFrameBuffer : width - 숫자만 허용","입력값 : ",t)),r&&("number"==typeof r||RedGLUtil.throwFunc("RedFrameBuffer : height - 숫자만 허용","입력값 : ",r)),i=e.gl,r=r||1080,(t=t||1920)>e.detect.texture.MAX_TEXTURE_SIZE&&(t=e.detect.texture.MAX_TEXTURE_SIZE),r>e.detect.texture.MAX_TEXTURE_SIZE&&(r=e.detect.texture.MAX_TEXTURE_SIZE),this.redGL=e,this.width=t,this.height=r,this.webglFrameBuffer=i.createFramebuffer(),this.webglRenderBuffer=i.createRenderbuffer(),this.texture=RedBitmapTexture(e),this._UUID=RedGL.makeUUID(),i.bindFramebuffer(i.FRAMEBUFFER,this.webglFrameBuffer),i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,this.texture.webglTexture),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!1),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.bindRenderbuffer(i.RENDERBUFFER,this.webglRenderBuffer),i.renderbufferStorage(i.RENDERBUFFER,i.DEPTH_COMPONENT16,this.width,this.height),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,this.texture.webglTexture,0),i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_ATTACHMENT,i.RENDERBUFFER,this.webglRenderBuffer),i.bindTexture(i.TEXTURE_2D,null),i.bindRenderbuffer(i.RENDERBUFFER,null),i.bindFramebuffer(i.FRAMEBUFFER,null)}).prototype={bind:function(e){e.bindFramebuffer(e.FRAMEBUFFER,this.webglFrameBuffer),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.texture.webglTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,this.width,this.height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindRenderbuffer(e.RENDERBUFFER,this.webglRenderBuffer),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,this.width,this.height),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.webglTexture,0),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,this.webglRenderBuffer)},unbind:function(e){e.bindTexture(e.TEXTURE_2D,null),e.bindRenderbuffer(e.RENDERBUFFER,null),e.bindFramebuffer(e.FRAMEBUFFER,null)}},RedDefinePropertyInfo.definePrototypes("RedFrameBuffer",["width","number",{min:2}],["height","number",{min:2}]),Object.freeze(RedFrameBuffer),function(){var e,t,r;e=function(e,t,r){switch(t){case RedBuffer.ARRAY_BUFFER:if(r instanceof Float32Array)return e.FLOAT;if(r instanceof Float64Array)return e.FLOAT;RedGLUtil.throwFunc("RedBuffer : 올바른 TypedArray(RedBuffer.ARRAY_BUFFER)형식을 사용해야합니다.","입력값 : "+r);break;case RedBuffer.ELEMENT_ARRAY_BUFFER:if(r instanceof Int8Array)return e.BYTE;if(r instanceof Int16Array)return e.SHORT;if(r instanceof Int32Array)return e.INT;if(r instanceof Uint8Array)return e.UNSIGNED_BYTE;if(r instanceof Uint16Array)return e.UNSIGNED_SHORT;if(r instanceof Uint32Array)return e.UNSIGNED_INT;RedGLUtil.throwFunc("RedBuffer : 올바른 TypedArray(RedBuffer.ELEMENT_ARRAY_BUFFER)형식을 사용해야합니다.","입력값 : "+r);break;default:RedGLUtil.throwFunc("RedBuffer : bufferType - 지원하지 않는 버퍼타입입니다. ","입력값 : "+t)}},t=function(e,t){switch(t){case RedBuffer.ARRAY_BUFFER:return e.ARRAY_BUFFER;case RedBuffer.ELEMENT_ARRAY_BUFFER:return e.ELEMENT_ARRAY_BUFFER;default:RedGLUtil.throwFunc("RedBuffer : bufferType - 지원하지 않는 버퍼타입입니다. ")}},r=function(e,t,r,i){var n,a,o,s,d;switch(r instanceof Float32Array?d=Float32Array.BYTES_PER_ELEMENT:r instanceof Float64Array&&(d=Float64Array.BYTES_PER_ELEMENT),n=0,t){case RedBuffer.ARRAY_BUFFER:if(e.interleaveDefineInfoList=i,i){for(i.length||RedGLUtil.throwFunc("RedBuffer : interleaveDefineInfoList의 정보는 1개이상의 RedInterleaveInfo Instance로 구성되어야함.",i),a=0,o=i.length;ai?u[o]:i,t=u[s]n?u[s]:n,r=u[d]a?u[d]:a;return this._volume=[i-e,n-t,a-r],this._volume.minX=e,this._volume.maxX=i,this._volume.minY=t,this._volume.maxY=n,this._volume.minZ=r,this._volume.maxZ=a,this._volume}},Object.defineProperty(RedGeometry.prototype,"volume",{get:function(){return this._volume||this.volumeCalculate(),this._volume}}),Object.freeze(RedGeometry)}(),RedInterleaveInfo=function(e,t,r){if(!(this instanceof RedInterleaveInfo))return new RedInterleaveInfo(e,t,r);"string"==typeof e||RedGLUtil.throwFunc("RedInterleaveInfo : attributeKey - 문자열만 허용",e),"a"===e.charAt(0)||RedGLUtil.throwFunc("RedInterleaveInfo : attributeKey 첫글자는 a로 시작해야합니다.",e),e.charAt(1)===e.charAt(1).toUpperCase()||RedInterleaveInfo.throwFunc("RedInterleaveInfo : attributeKey 두번째 글자는 대문자 시작해야합니다.",e),"number"==typeof t||RedGLUtil.throwFunc("RedInterleaveInfo : size - 숫자만 허용",t),this.attributeKey=e,this.size=t,this.normalize=void 0!==r,this.offset=null},Object.freeze(RedInterleaveInfo),function(){var e,t,r,i,n,a,o,s;(RedBaseMaterial=function(){}).prototype={makeProgramList:(s=["fog","sprite3D","skin","directionalShadow"],s.sort(),a=function(e,t,r,i,s,d,u){e.basic[t]||(e.basic[t]=new n(r,e,t,i,s)),d.forEach(function(c,l){d.sort(),u.sort();var f=d.join("_");e[f]||(e[f]={}),e[f][t]||(e[f][t]=new n(r,e,t,i,s,d));var h=d.concat();h.splice(l,1),o(e,f,t,r,i,s,d,u),a(e,t,r,i,s,h,u)})},o=function(e,t,r,i,a,o,s,d){function u(e,t){var r,i,n,a,o;if(t>e.length||t<=0)return[];if(t===e.length)return[e];if(1===t){for(n=[],r=0;r1?e.LINEAR_MIPMAP_NEAREST:e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,i.mag?i.mag:e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),n&&n(!0)},s.onerror=function(){n&&n(!1)},s.send(null),o}}(RedDDSTexture.prototype),Object.freeze(RedDDSTexture),function(){var e;e=function(e,t,r,i,n,a){var o,s,d,u,c,l=[];for(n=n||{},o=function(){0===c&&a&&a.call(t,!1),c++},s=function(){if(6==++u){e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_CUBE_MAP,r),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,0),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MIN_FILTER,n.min?n.min:e.LINEAR_MIPMAP_NEAREST),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MAG_FILTER,n.mag?n.mag:e.LINEAR),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_S,n.wrap_s?n.wrap_s:e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_T,n.wrap_t?n.wrap_t:e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,l[0].source),e.texImage2D(e.TEXTURE_CUBE_MAP_NEGATIVE_X,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,l[1].source),e.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_Y,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,l[2].source),e.texImage2D(e.TEXTURE_CUBE_MAP_NEGATIVE_Y,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,l[3].source),e.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_Z,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,l[4].source),e.texImage2D(e.TEXTURE_CUBE_MAP_NEGATIVE_Z,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,l[5].source),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,0);try{e.generateMipmap(e.TEXTURE_CUBE_MAP)}catch(e){}e.bindTexture(e.TEXTURE_CUBE_MAP,null),0===c&&a&&a.call(t,!0)}},d=6,u=0,c=0;d--;)l[d]=RedImageLoader(i[d],s,o,{})},(RedBitmapCubeTexture=function(t,r,i,n){var a;if(!(this instanceof RedBitmapCubeTexture))return new RedBitmapCubeTexture(t,r,i,n);t instanceof RedGL||RedGLUtil.throwFunc("RedBitmapCubeTexture : RedGL Instance만 허용.","입력값 : "+t),n&&"function"==typeof n||!n||RedGLUtil.throwFunc("RedBitmapCubeTexture : callback Function만 허용.",n),a=t.gl,i=i||{};var o=r.toString()+JSON.stringify(i);if(r instanceof Array&&(t._datas.textures||(t._datas.textures={}),t._datas.textures[o]))return n&&setTimeout(function(){n.call(this,!0)},1),t._datas.textures[o];this.webglTexture=a.createTexture(),this.webglTexture.gl=a,this._UUID=RedGL.makeUUID(),this._load=function(t){RedTextureOptionChecker.check("RedBitmapCubeTexture",i,a),t&&this.setEmptyTexture(a,this.webglTexture),this._srcList&&e(a,this,this.webglTexture,this._srcList,this._option,this._callback)},this._option=i,this.callback=n,this.srcList=r,t._datas.textures[o]=this}).prototype=new RedBaseTexture,Object.defineProperty(RedBitmapCubeTexture.prototype,"srcList",{get:function(){return this._srcList},set:function(e){e instanceof Array||RedGLUtil.throwFunc("RedBitmapCubeTexture : srcList는 배열만 허용.","입력값 : "+e),6===e.length||RedGLUtil.throwFunc("RedBitmapCubeTexture : srcList 길이는 6이어야함","입력값 : "+e),this._srcList=e,this._load(!0)}}),Object.defineProperty(RedBitmapCubeTexture.prototype,"option",{get:function(){return this._option},set:function(e){this._option=e,this._load(!1)}}),Object.freeze(RedBitmapCubeTexture)}(),function(){var e,t,r,i,n=[];e=function(){ +var RedDefinePropertyInfo,RedGLDetect,RedGLUtil,RedGL,RedBoxSelection,RedBaseController,RedImageLoader,RedBaseTexture,RedBaseObject3D,RedBaseContainer,RedBaseLight,RedFrameBuffer,RedBuffer,RedGeometry,RedInterleaveInfo,RedBaseMaterial,RedTextureOptionChecker,RedBitmapTexture,RedVideoTexture,RedDDSTexture,RedBitmapCubeTexture,RedColorMaterial,RedColorPhongMaterial,RedColorPhongTextureMaterial,RedEnvironmentMaterial,RedBitmapMaterial,RedParticleMaterial,RedBitmapPointCloudMaterial,RedSheetMaterial,RedStandardMaterial,RedVideoMaterial,RedPBRMaterial,RedColorPointCloudMaterial,RedPBRMaterial_System,RedTextMaterial,RedOutlineMaterial,RedOutlinePlaneMaterial,RedAmbientLight,RedDirectionalLight,RedPointLight,RedMTLLoader,RedOBJLoader,Red3DSLoader,RedDAELoader,RedGLTFLoader,RedLinePoint,RedLathe,RedAxis,RedGrid,RedMesh,RedLine,RedLatheMesh,RedSkyBox,RedSprite3D,RedTransformController,RedPointCloud,RedParticleUnit,RedColorPointCloud,RedBitmapPointCloud,RedParticleEmitter,RedBox,RedCylinder,RedPlane,RedSphere,RedProgram,RedSystemShaderCode,RedShader,RedRenderer,RedRenderDebuger,RedSystemUniformUpdater,RedView,RedWorld,RedScene,RedCamera,RedBasicController,RedObitController,RedGridMaterial,RedSkyBoxMaterial,RedDirectionalShadowMaterial,RedPostEffectMaterial,RedDirectionalShadow,RedShadowManager,RedText,RedMouseEventManager,RedMouseEventMaterial,RedPostEffectManager,RedBasePostEffect,RedPostEffect_Bloom,RedPostEffect_BloomThreshold,RedPostEffect_Blur,RedPostEffect_BlurX,RedPostEffect_BlurY,RedPostEffect_GaussianBlur,RedPostEffect_ZoomBlur,RedPostEffect_BrightnessContrast,RedPostEffect_Threshold,RedPostEffect_Invert,RedPostEffect_Gray,RedPostEffect_HueSaturation,RedPostEffect_HalfTone,RedPostEffect_Pixelize,RedPostEffect_Convolution,RedPostEffect_DoF,RedPostEffect_DoF_DepthMaterial,RedPostEffect_Film,RedPostEffect_Vignetting,RedPostEffect_FXAA,RedFilterFrameBuffer,RedFilterEffectManager,RedBaseFilter,RedFilterMaterial,RedFilter_BrightnessContrast,RedFilter_Gray,RedFilter_Invert,RedFilter_Threshold,RedFilter_HueSaturation,RedFilter_Blur,RedFilter_BlurX,RedFilter_BlurY,RedFilter_GaussianBlur,RedFilter_Pixelize,RedFilter_HalfTone,RedFilter_Bloom,RedFilter_BloomThreshold,RedFilter_Film,RedFilter_Convolution,RedGLOffScreen;!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r=t();for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,function(){return function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,t),n.l=!0,n.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,i){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=4)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.setMatrixArrayType=function(e){t.ARRAY_TYPE=e},t.toRadian=function(e){return e*n},t.equals=function(e,t){return Math.abs(e-t)<=i*Math.max(1,Math.abs(e),Math.abs(t))};var i=t.EPSILON=1e-6,n=(t.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,t.RANDOM=Math.random,Math.PI/180)},function(e,t,r){"use strict";function i(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],d=t[5],l=t[6],u=t[7],c=t[8],f=r[0],h=r[1],R=r[2],m=r[3],p=r[4],_=r[5],g=r[6],v=r[7],E=r[8];return e[0]=f*i+h*o+R*l,e[1]=f*n+h*s+R*u,e[2]=f*a+h*d+R*c,e[3]=m*i+p*o+_*l,e[4]=m*n+p*s+_*u,e[5]=m*a+p*d+_*c,e[6]=g*i+v*o+E*l,e[7]=g*n+v*s+E*u,e[8]=g*a+v*d+E*c,e}function n(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e[3]=t[3]-r[3],e[4]=t[4]-r[4],e[5]=t[5]-r[5],e[6]=t[6]-r[6],e[7]=t[7]-r[7],e[8]=t[8]-r[8],e}Object.defineProperty(t,"__esModule",{value:!0}),t.sub=t.mul=void 0,t.create=function(){var e=new a.ARRAY_TYPE(9);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat4=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[4],e[4]=t[5],e[5]=t[6],e[6]=t[8],e[7]=t[9],e[8]=t[10],e},t.clone=function(e){var t=new a.ARRAY_TYPE(9);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e},t.fromValues=function(e,t,r,i,n,o,s,d,l){var u=new a.ARRAY_TYPE(9);return u[0]=e,u[1]=t,u[2]=r,u[3]=i,u[4]=n,u[5]=o,u[6]=s,u[7]=d,u[8]=l,u},t.set=function(e,t,r,i,n,a,o,s,d,l){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e[4]=a,e[5]=o,e[6]=s,e[7]=d,e[8]=l,e},t.identity=function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.transpose=function(e,t){if(e===t){var r=t[1],i=t[2],n=t[5];e[1]=t[3],e[2]=t[6],e[3]=r,e[5]=t[7],e[6]=i,e[7]=n}else e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8];return e},t.invert=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],d=t[6],l=t[7],u=t[8],c=u*o-s*l,f=-u*a+s*d,h=l*a-o*d,R=r*c+i*f+n*h;return R?(R=1/R,e[0]=c*R,e[1]=(-u*i+n*l)*R,e[2]=(s*i-n*o)*R,e[3]=f*R,e[4]=(u*r-n*d)*R,e[5]=(-s*r+n*a)*R,e[6]=h*R,e[7]=(-l*r+i*d)*R,e[8]=(o*r-i*a)*R,e):null},t.adjoint=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],d=t[6],l=t[7],u=t[8];return e[0]=o*u-s*l,e[1]=n*l-i*u,e[2]=i*s-n*o,e[3]=s*d-a*u,e[4]=r*u-n*d,e[5]=n*a-r*s,e[6]=a*l-o*d,e[7]=i*d-r*l,e[8]=r*o-i*a,e},t.determinant=function(e){var t=e[0],r=e[1],i=e[2],n=e[3],a=e[4],o=e[5],s=e[6],d=e[7],l=e[8];return t*(l*a-o*d)+r*(-l*n+o*s)+i*(d*n-a*s)},t.multiply=i,t.translate=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],d=t[5],l=t[6],u=t[7],c=t[8],f=r[0],h=r[1];return e[0]=i,e[1]=n,e[2]=a,e[3]=o,e[4]=s,e[5]=d,e[6]=f*i+h*o+l,e[7]=f*n+h*s+u,e[8]=f*a+h*d+c,e},t.rotate=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],d=t[5],l=t[6],u=t[7],c=t[8],f=Math.sin(r),h=Math.cos(r);return e[0]=h*i+f*o,e[1]=h*n+f*s,e[2]=h*a+f*d,e[3]=h*o-f*i,e[4]=h*s-f*n,e[5]=h*d-f*a,e[6]=l,e[7]=u,e[8]=c,e},t.scale=function(e,t,r){var i=r[0],n=r[1];return e[0]=i*t[0],e[1]=i*t[1],e[2]=i*t[2],e[3]=n*t[3],e[4]=n*t[4],e[5]=n*t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e},t.fromTranslation=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=t[0],e[7]=t[1],e[8]=1,e},t.fromRotation=function(e,t){var r=Math.sin(t),i=Math.cos(t);return e[0]=i,e[1]=r,e[2]=0,e[3]=-r,e[4]=i,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromScaling=function(e,t){return e[0]=t[0],e[1]=0,e[2]=0,e[3]=0,e[4]=t[1],e[5]=0,e[6]=0,e[7]=0,e[8]=1,e},t.fromMat2d=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=0,e[3]=t[2],e[4]=t[3],e[5]=0,e[6]=t[4],e[7]=t[5],e[8]=1,e},t.fromQuat=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r+r,s=i+i,d=n+n,l=r*o,u=i*o,c=i*s,f=n*o,h=n*s,R=n*d,m=a*o,p=a*s,_=a*d;return e[0]=1-c-R,e[3]=u-_,e[6]=f+p,e[1]=u+_,e[4]=1-l-R,e[7]=h-m,e[2]=f-p,e[5]=h+m,e[8]=1-l-c,e},t.normalFromMat4=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],d=t[6],l=t[7],u=t[8],c=t[9],f=t[10],h=t[11],R=t[12],m=t[13],p=t[14],_=t[15],g=r*s-i*o,v=r*d-n*o,E=r*l-a*o,M=i*d-n*s,b=i*l-a*s,L=n*l-a*d,T=u*m-c*R,P=u*p-f*R,x=u*_-h*R,y=c*p-f*m,w=c*_-h*m,U=f*_-h*p,I=g*U-v*w+E*y+M*x-b*P+L*T;return I?(I=1/I,e[0]=(s*U-d*w+l*y)*I,e[1]=(d*x-o*U-l*P)*I,e[2]=(o*w-s*x+l*T)*I,e[3]=(n*w-i*U-a*y)*I,e[4]=(r*U-n*x+a*P)*I,e[5]=(i*x-r*w-a*T)*I,e[6]=(m*L-p*b+_*M)*I,e[7]=(p*E-R*L-_*v)*I,e[8]=(R*b-m*E+_*g)*I,e):null},t.projection=function(e,t,r){return e[0]=2/t,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/r,e[5]=0,e[6]=-1,e[7]=1,e[8]=1,e},t.str=function(e){return"mat3("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+", "+e[4]+", "+e[5]+", "+e[6]+", "+e[7]+", "+e[8]+")"},t.frob=function(e){return Math.sqrt(Math.pow(e[0],2)+Math.pow(e[1],2)+Math.pow(e[2],2)+Math.pow(e[3],2)+Math.pow(e[4],2)+Math.pow(e[5],2)+Math.pow(e[6],2)+Math.pow(e[7],2)+Math.pow(e[8],2))},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e[4]=t[4]+r[4],e[5]=t[5]+r[5],e[6]=t[6]+r[6],e[7]=t[7]+r[7],e[8]=t[8]+r[8],e},t.subtract=n,t.multiplyScalar=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*r,e[5]=t[5]*r,e[6]=t[6]*r,e[7]=t[7]*r,e[8]=t[8]*r,e},t.multiplyScalarAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e[4]=t[4]+r[4]*i,e[5]=t[5]+r[5]*i,e[6]=t[6]+r[6]*i,e[7]=t[7]+r[7]*i,e[8]=t[8]+r[8]*i,e},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[3],s=e[4],d=e[5],l=e[6],u=e[7],c=e[8],f=t[0],h=t[1],R=t[2],m=t[3],p=t[4],_=t[5],g=t[6],v=t[7],E=t[8];return Math.abs(r-f)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(f))&&Math.abs(i-h)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(h))&&Math.abs(n-R)<=a.EPSILON*Math.max(1,Math.abs(n),Math.abs(R))&&Math.abs(o-m)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(m))&&Math.abs(s-p)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(p))&&Math.abs(d-_)<=a.EPSILON*Math.max(1,Math.abs(d),Math.abs(_))&&Math.abs(l-g)<=a.EPSILON*Math.max(1,Math.abs(l),Math.abs(g))&&Math.abs(u-v)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(v))&&Math.abs(c-E)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(E))};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.mul=i,t.sub=n},function(e,t,r){"use strict";function i(){var e=new R.ARRAY_TYPE(3);return e[0]=0,e[1]=0,e[2]=0,e}function n(e){var t=e[0],r=e[1],i=e[2];return Math.sqrt(t*t+r*r+i*i)}function a(e,t,r){var i=new R.ARRAY_TYPE(3);return i[0]=e,i[1]=t,i[2]=r,i}function o(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e}function s(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e[2]=t[2]*r[2],e}function d(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e[2]=t[2]/r[2],e}function l(e,t){var r=t[0]-e[0],i=t[1]-e[1],n=t[2]-e[2];return Math.sqrt(r*r+i*i+n*n)}function u(e,t){var r=t[0]-e[0],i=t[1]-e[1],n=t[2]-e[2];return r*r+i*i+n*n}function c(e){var t=e[0],r=e[1],i=e[2];return t*t+r*r+i*i}function f(e,t){var r=t[0],i=t[1],n=t[2],a=r*r+i*i+n*n;return a>0&&(a=1/Math.sqrt(a),e[0]=t[0]*a,e[1]=t[1]*a,e[2]=t[2]*a),e}function h(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.len=t.sqrDist=t.dist=t.div=t.mul=t.sub=void 0,t.create=i,t.clone=function(e){var t=new R.ARRAY_TYPE(3);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t},t.length=n,t.fromValues=a,t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e},t.set=function(e,t,r,i){return e[0]=t,e[1]=r,e[2]=i,e},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e},t.subtract=o,t.multiply=s,t.divide=d,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e[2]=Math.ceil(t[2]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e[2]=Math.floor(t[2]),e},t.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e[2]=Math.min(t[2],r[2]),e},t.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e[2]=Math.max(t[2],r[2]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e[2]=Math.round(t[2]),e},t.scale=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e},t.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e},t.distance=l,t.squaredDistance=u,t.squaredLength=c,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e},t.normalize=f,t.dot=h,t.cross=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],d=r[2];return e[0]=n*d-a*s,e[1]=a*o-i*d,e[2]=i*s-n*o,e},t.lerp=function(e,t,r,i){var n=t[0],a=t[1],o=t[2];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e[2]=o+i*(r[2]-o),e},t.hermite=function(e,t,r,i,n,a){var o=a*a,s=o*(2*a-3)+1,d=o*(a-2)+a,l=o*(a-1),u=o*(3-2*a);return e[0]=t[0]*s+r[0]*d+i[0]*l+n[0]*u,e[1]=t[1]*s+r[1]*d+i[1]*l+n[1]*u,e[2]=t[2]*s+r[2]*d+i[2]*l+n[2]*u,e},t.bezier=function(e,t,r,i,n,a){var o=1-a,s=o*o,d=a*a,l=s*o,u=3*a*s,c=3*d*o,f=d*a;return e[0]=t[0]*l+r[0]*u+i[0]*c+n[0]*f,e[1]=t[1]*l+r[1]*u+i[1]*c+n[1]*f,e[2]=t[2]*l+r[2]*u+i[2]*c+n[2]*f,e},t.random=function(e,t){t=t||1;var r=2*R.RANDOM()*Math.PI,i=2*R.RANDOM()-1,n=Math.sqrt(1-i*i)*t;return e[0]=Math.cos(r)*n,e[1]=Math.sin(r)*n,e[2]=i*t,e},t.transformMat4=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[3]*i+r[7]*n+r[11]*a+r[15];return o=o||1,e[0]=(r[0]*i+r[4]*n+r[8]*a+r[12])/o,e[1]=(r[1]*i+r[5]*n+r[9]*a+r[13])/o,e[2]=(r[2]*i+r[6]*n+r[10]*a+r[14])/o,e},t.transformMat3=function(e,t,r){var i=t[0],n=t[1],a=t[2];return e[0]=i*r[0]+n*r[3]+a*r[6],e[1]=i*r[1]+n*r[4]+a*r[7],e[2]=i*r[2]+n*r[5]+a*r[8],e},t.transformQuat=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],d=r[2],l=r[3],u=l*i+s*a-d*n,c=l*n+d*i-o*a,f=l*a+o*n-s*i,h=-o*i-s*n-d*a;return e[0]=u*l+h*-o+c*-d-f*-s,e[1]=c*l+h*-s+f*-o-u*-d,e[2]=f*l+h*-d+u*-s-c*-o,e},t.rotateX=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[0],a[1]=n[1]*Math.cos(i)-n[2]*Math.sin(i),a[2]=n[1]*Math.sin(i)+n[2]*Math.cos(i),e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},t.rotateY=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[2]*Math.sin(i)+n[0]*Math.cos(i),a[1]=n[1],a[2]=n[2]*Math.cos(i)-n[0]*Math.sin(i),e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},t.rotateZ=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[0]*Math.cos(i)-n[1]*Math.sin(i),a[1]=n[0]*Math.sin(i)+n[1]*Math.cos(i),a[2]=n[2],e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},t.angle=function(e,t){var r=a(e[0],e[1],e[2]),i=a(t[0],t[1],t[2]);f(r,r),f(i,i);var n=h(r,i);return n>1?0:n<-1?Math.PI:Math.acos(n)},t.str=function(e){return"vec3("+e[0]+", "+e[1]+", "+e[2]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],a=t[0],o=t[1],s=t[2];return Math.abs(r-a)<=R.EPSILON*Math.max(1,Math.abs(r),Math.abs(a))&&Math.abs(i-o)<=R.EPSILON*Math.max(1,Math.abs(i),Math.abs(o))&&Math.abs(n-s)<=R.EPSILON*Math.max(1,Math.abs(n),Math.abs(s))};var R=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.sub=o,t.mul=s,t.div=d,t.dist=l,t.sqrDist=u,t.len=n,t.sqrLen=c,t.forEach=function(){var e=i();return function(t,r,i,n,a,o){var s,d=void 0;for(r||(r=3),i||(i=0),s=n?Math.min(n*r+i,t.length):t.length,d=i;d0&&(o=1/Math.sqrt(o),e[0]=r*o,e[1]=i*o,e[2]=n*o,e[3]=a*o),e}Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.len=t.sqrDist=t.dist=t.div=t.mul=t.sub=void 0,t.create=i,t.clone=function(e){var t=new h.ARRAY_TYPE(4);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},t.fromValues=function(e,t,r,i){var n=new h.ARRAY_TYPE(4);return n[0]=e,n[1]=t,n[2]=r,n[3]=i,n},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},t.set=function(e,t,r,i,n){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e},t.subtract=n,t.multiply=a,t.divide=o,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e[2]=Math.ceil(t[2]),e[3]=Math.ceil(t[3]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e[2]=Math.floor(t[2]),e[3]=Math.floor(t[3]),e},t.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e[2]=Math.min(t[2],r[2]),e[3]=Math.min(t[3],r[3]),e},t.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e[2]=Math.max(t[2],r[2]),e[3]=Math.max(t[3],r[3]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e[2]=Math.round(t[2]),e[3]=Math.round(t[3]),e},t.scale=s,t.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e},t.distance=d,t.squaredDistance=l,t.length=u,t.squaredLength=c,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e[3]=1/t[3],e},t.normalize=f,t.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]},t.lerp=function(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e[2]=o+i*(r[2]-o),e[3]=s+i*(r[3]-s),e},t.random=function(e,t){return t=t||1,e[0]=h.RANDOM(),e[1]=h.RANDOM(),e[2]=h.RANDOM(),e[3]=h.RANDOM(),f(e,e),s(e,e,t),e},t.transformMat4=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3];return e[0]=r[0]*i+r[4]*n+r[8]*a+r[12]*o,e[1]=r[1]*i+r[5]*n+r[9]*a+r[13]*o,e[2]=r[2]*i+r[6]*n+r[10]*a+r[14]*o,e[3]=r[3]*i+r[7]*n+r[11]*a+r[15]*o,e},t.transformQuat=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],d=r[2],l=r[3],u=l*i+s*a-d*n,c=l*n+d*i-o*a,f=l*a+o*n-s*i,h=-o*i-s*n-d*a;return e[0]=u*l+h*-o+c*-d-f*-s,e[1]=c*l+h*-s+f*-o-u*-d,e[2]=f*l+h*-d+u*-s-c*-o,e[3]=t[3],e},t.str=function(e){return"vec4("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],a=e[3],o=t[0],s=t[1],d=t[2],l=t[3];return Math.abs(r-o)<=h.EPSILON*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(i-s)<=h.EPSILON*Math.max(1,Math.abs(i),Math.abs(s))&&Math.abs(n-d)<=h.EPSILON*Math.max(1,Math.abs(n),Math.abs(d))&&Math.abs(a-l)<=h.EPSILON*Math.max(1,Math.abs(a),Math.abs(l))};var h=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.sub=n,t.mul=a,t.div=o,t.dist=d,t.sqrDist=l,t.len=u,t.sqrLen=c,t.forEach=function(){var e=i();return function(t,r,i,n,a,o){var s,d=void 0;for(r||(r=4),i||(i=0),s=n?Math.min(n*r+i,t.length):t.length,d=i;d0?(i=2*Math.sqrt(r+1),e[3]=.25*i,e[0]=(t[6]-t[9])/i,e[1]=(t[8]-t[2])/i,e[2]=(t[1]-t[4])/i):t[0]>t[5]&t[0]>t[10]?(i=2*Math.sqrt(1+t[0]-t[5]-t[10]),e[3]=(t[6]-t[9])/i,e[0]=.25*i,e[1]=(t[1]+t[4])/i,e[2]=(t[8]+t[2])/i):t[5]>t[10]?(i=2*Math.sqrt(1+t[5]-t[0]-t[10]),e[3]=(t[8]-t[2])/i,e[0]=(t[1]+t[4])/i,e[1]=.25*i,e[2]=(t[6]+t[9])/i):(i=2*Math.sqrt(1+t[10]-t[0]-t[5]),e[3]=(t[1]-t[4])/i,e[0]=(t[8]+t[2])/i,e[1]=(t[6]+t[9])/i,e[2]=.25*i),e},t.fromRotationTranslationScale=function(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3],d=n+n,l=a+a,u=o+o,c=n*d,f=n*l,h=n*u,R=a*l,m=a*u,p=o*u,_=s*d,g=s*l,v=s*u,E=i[0],M=i[1],b=i[2];return e[0]=(1-(R+p))*E,e[1]=(f+v)*E,e[2]=(h-g)*E,e[3]=0,e[4]=(f-v)*M,e[5]=(1-(c+p))*M,e[6]=(m+_)*M,e[7]=0,e[8]=(h+g)*b,e[9]=(m-_)*b,e[10]=(1-(c+R))*b,e[11]=0,e[12]=r[0],e[13]=r[1],e[14]=r[2],e[15]=1,e},t.fromRotationTranslationScaleOrigin=function(e,t,r,i,n){var a=t[0],o=t[1],s=t[2],d=t[3],l=a+a,u=o+o,c=s+s,f=a*l,h=a*u,R=a*c,m=o*u,p=o*c,_=s*c,g=d*l,v=d*u,E=d*c,M=i[0],b=i[1],L=i[2],T=n[0],P=n[1],x=n[2];return e[0]=(1-(m+_))*M,e[1]=(h+E)*M,e[2]=(R-v)*M,e[3]=0,e[4]=(h-E)*b,e[5]=(1-(f+_))*b,e[6]=(p+g)*b,e[7]=0,e[8]=(R+v)*L,e[9]=(p-g)*L,e[10]=(1-(f+m))*L,e[11]=0,e[12]=r[0]+T-(e[0]*T+e[4]*P+e[8]*x),e[13]=r[1]+P-(e[1]*T+e[5]*P+e[9]*x),e[14]=r[2]+x-(e[2]*T+e[6]*P+e[10]*x),e[15]=1,e},t.fromQuat=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r+r,s=i+i,d=n+n,l=r*o,u=i*o,c=i*s,f=n*o,h=n*s,R=n*d,m=a*o,p=a*s,_=a*d;return e[0]=1-c-R,e[1]=u+_,e[2]=f-p,e[3]=0,e[4]=u-_,e[5]=1-l-R,e[6]=h+m,e[7]=0,e[8]=f+p,e[9]=h-m,e[10]=1-l-c,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,r,i,n,a,o){var s=1/(r-t),d=1/(n-i),l=1/(a-o);return e[0]=2*a*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*a*d,e[6]=0,e[7]=0,e[8]=(r+t)*s,e[9]=(n+i)*d,e[10]=(o+a)*l,e[11]=-1,e[12]=0,e[13]=0,e[14]=o*a*2*l,e[15]=0,e},t.perspective=function(e,t,r,i,n){var a=1/Math.tan(t/2),o=1/(i-n);return e[0]=a/r,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=a,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=(n+i)*o,e[11]=-1,e[12]=0,e[13]=0,e[14]=2*n*i*o,e[15]=0,e},t.perspectiveFromFieldOfView=function(e,t,r,i){var n=Math.tan(t.upDegrees*Math.PI/180),a=Math.tan(t.downDegrees*Math.PI/180),o=Math.tan(t.leftDegrees*Math.PI/180),s=Math.tan(t.rightDegrees*Math.PI/180),d=2/(o+s),l=2/(n+a);return e[0]=d,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=l,e[6]=0,e[7]=0,e[8]=-(o-s)*d*.5,e[9]=(n-a)*l*.5,e[10]=i/(r-i),e[11]=-1,e[12]=0,e[13]=0,e[14]=i*r/(r-i),e[15]=0,e},t.ortho=function(e,t,r,i,n,a,o){var s=1/(t-r),d=1/(i-n),l=1/(a-o);return e[0]=-2*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*d,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*l,e[11]=0,e[12]=(t+r)*s,e[13]=(n+i)*d,e[14]=(o+a)*l,e[15]=1,e},t.lookAt=function(e,t,r,i){var n=void 0,o=void 0,s=void 0,d=void 0,l=void 0,u=void 0,c=void 0,f=void 0,h=void 0,R=void 0,m=t[0],p=t[1],_=t[2],g=i[0],v=i[1],E=i[2],M=r[0],b=r[1],L=r[2];return Math.abs(m-M)0&&(u*=h=1/Math.sqrt(h),c*=h,f*=h);var R=d*f-l*c,m=l*u-s*f,p=s*c-d*u;return e[0]=R,e[1]=m,e[2]=p,e[3]=0,e[4]=c*p-f*m,e[5]=f*R-u*p,e[6]=u*m-c*R,e[7]=0,e[8]=u,e[9]=c,e[10]=f,e[11]=0,e[12]=n,e[13]=a,e[14]=o,e[15]=1,e},t.str=function(e){return"mat4("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+", "+e[4]+", "+e[5]+", "+e[6]+", "+e[7]+", "+e[8]+", "+e[9]+", "+e[10]+", "+e[11]+", "+e[12]+", "+e[13]+", "+e[14]+", "+e[15]+")"},t.frob=function(e){return Math.sqrt(Math.pow(e[0],2)+Math.pow(e[1],2)+Math.pow(e[2],2)+Math.pow(e[3],2)+Math.pow(e[4],2)+Math.pow(e[5],2)+Math.pow(e[6],2)+Math.pow(e[7],2)+Math.pow(e[8],2)+Math.pow(e[9],2)+Math.pow(e[10],2)+Math.pow(e[11],2)+Math.pow(e[12],2)+Math.pow(e[13],2)+Math.pow(e[14],2)+Math.pow(e[15],2))},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e[4]=t[4]+r[4],e[5]=t[5]+r[5],e[6]=t[6]+r[6],e[7]=t[7]+r[7],e[8]=t[8]+r[8],e[9]=t[9]+r[9],e[10]=t[10]+r[10],e[11]=t[11]+r[11],e[12]=t[12]+r[12],e[13]=t[13]+r[13],e[14]=t[14]+r[14],e[15]=t[15]+r[15],e},t.subtract=n,t.multiplyScalar=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*r,e[5]=t[5]*r,e[6]=t[6]*r,e[7]=t[7]*r,e[8]=t[8]*r,e[9]=t[9]*r,e[10]=t[10]*r,e[11]=t[11]*r,e[12]=t[12]*r,e[13]=t[13]*r,e[14]=t[14]*r,e[15]=t[15]*r,e},t.multiplyScalarAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e[4]=t[4]+r[4]*i,e[5]=t[5]+r[5]*i,e[6]=t[6]+r[6]*i,e[7]=t[7]+r[7]*i,e[8]=t[8]+r[8]*i,e[9]=t[9]+r[9]*i,e[10]=t[10]+r[10]*i,e[11]=t[11]+r[11]*i,e[12]=t[12]+r[12]*i,e[13]=t[13]+r[13]*i,e[14]=t[14]+r[14]*i,e[15]=t[15]+r[15]*i,e},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[11]===t[11]&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[15]===t[15]},t.equals=function(e,t){var r=e[0],i=e[1],n=e[2],o=e[3],s=e[4],d=e[5],l=e[6],u=e[7],c=e[8],f=e[9],h=e[10],R=e[11],m=e[12],p=e[13],_=e[14],g=e[15],v=t[0],E=t[1],M=t[2],b=t[3],L=t[4],T=t[5],P=t[6],x=t[7],y=t[8],w=t[9],U=t[10],I=t[11],B=t[12],F=t[13],D=t[14],G=t[15];return Math.abs(r-v)<=a.EPSILON*Math.max(1,Math.abs(r),Math.abs(v))&&Math.abs(i-E)<=a.EPSILON*Math.max(1,Math.abs(i),Math.abs(E))&&Math.abs(n-M)<=a.EPSILON*Math.max(1,Math.abs(n),Math.abs(M))&&Math.abs(o-b)<=a.EPSILON*Math.max(1,Math.abs(o),Math.abs(b))&&Math.abs(s-L)<=a.EPSILON*Math.max(1,Math.abs(s),Math.abs(L))&&Math.abs(d-T)<=a.EPSILON*Math.max(1,Math.abs(d),Math.abs(T))&&Math.abs(l-P)<=a.EPSILON*Math.max(1,Math.abs(l),Math.abs(P))&&Math.abs(u-x)<=a.EPSILON*Math.max(1,Math.abs(u),Math.abs(x))&&Math.abs(c-y)<=a.EPSILON*Math.max(1,Math.abs(c),Math.abs(y))&&Math.abs(f-w)<=a.EPSILON*Math.max(1,Math.abs(f),Math.abs(w))&&Math.abs(h-U)<=a.EPSILON*Math.max(1,Math.abs(h),Math.abs(U))&&Math.abs(R-I)<=a.EPSILON*Math.max(1,Math.abs(R),Math.abs(I))&&Math.abs(m-B)<=a.EPSILON*Math.max(1,Math.abs(m),Math.abs(B))&&Math.abs(p-F)<=a.EPSILON*Math.max(1,Math.abs(p),Math.abs(F))&&Math.abs(_-D)<=a.EPSILON*Math.max(1,Math.abs(_),Math.abs(D))&&Math.abs(g-G)<=a.EPSILON*Math.max(1,Math.abs(g),Math.abs(G))};var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.mul=i,t.sub=n},function(e,t,r){"use strict";function i(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}function n(){var e=new l.ARRAY_TYPE(4);return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}function a(e,t,r){r*=.5;var i=Math.sin(r);return e[0]=i*t[0],e[1]=i*t[1],e[2]=i*t[2],e[3]=Math.cos(r),e}function o(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=r[0],d=r[1],l=r[2],u=r[3];return e[0]=i*u+o*s+n*l-a*d,e[1]=n*u+o*d+a*s-i*l,e[2]=a*u+o*l+i*d-n*s,e[3]=o*u-i*s-n*d-a*l,e}function s(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3],d=r[0],l=r[1],u=r[2],c=r[3],f=void 0,h=void 0,R=void 0,m=void 0,p=void 0;return(h=n*d+a*l+o*u+s*c)<0&&(h=-h,d=-d,l=-l,u=-u,c=-c),1-h>1e-6?(f=Math.acos(h),R=Math.sin(f),m=Math.sin((1-i)*f)/R,p=Math.sin(i*f)/R):(m=1-i,p=i),e[0]=m*n+p*d,e[1]=m*a+p*l,e[2]=m*o+p*u,e[3]=m*s+p*c,e}function d(e,t){var r=t[0]+t[4]+t[8],i=void 0;if(r>0)i=Math.sqrt(r+1),e[3]=.5*i,i=.5/i,e[0]=(t[5]-t[7])*i,e[1]=(t[6]-t[2])*i,e[2]=(t[1]-t[3])*i;else{var n=0;t[4]>t[0]&&(n=1),t[8]>t[3*n+n]&&(n=2);var a=(n+1)%3,o=(n+2)%3;i=Math.sqrt(t[3*n+n]-t[3*a+a]-t[3*o+o]+1),e[n]=.5*i,i=.5/i,e[3]=(t[3*a+o]-t[3*o+a])*i,e[a]=(t[3*a+n]+t[3*n+a])*i,e[o]=(t[3*o+n]+t[3*n+o])*i}return e}Object.defineProperty(t,"__esModule",{value:!0}),t.setAxes=t.sqlerp=t.rotationTo=t.equals=t.exactEquals=t.normalize=t.sqrLen=t.squaredLength=t.len=t.length=t.lerp=t.dot=t.scale=t.mul=t.add=t.set=t.copy=t.fromValues=t.clone=void 0,t.create=n,t.identity=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},t.setAxisAngle=a,t.getAxisAngle=function(e,t){var r=2*Math.acos(t[3]),i=Math.sin(r/2);return 0!=i?(e[0]=t[0]/i,e[1]=t[1]/i,e[2]=t[2]/i):(e[0]=1,e[1]=0,e[2]=0),r},t.multiply=o,t.rotateX=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),d=Math.cos(r);return e[0]=i*d+o*s,e[1]=n*d+a*s,e[2]=a*d-n*s,e[3]=o*d-i*s,e},t.rotateY=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),d=Math.cos(r);return e[0]=i*d-a*s,e[1]=n*d+o*s,e[2]=a*d+i*s,e[3]=o*d-n*s,e},t.rotateZ=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),d=Math.cos(r);return e[0]=i*d+n*s,e[1]=n*d-i*s,e[2]=a*d+o*s,e[3]=o*d-a*s,e},t.calculateW=function(e,t){var r=t[0],i=t[1],n=t[2];return e[0]=r,e[1]=i,e[2]=n,e[3]=Math.sqrt(Math.abs(1-r*r-i*i-n*n)),e},t.slerp=s,t.invert=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r*r+i*i+n*n+a*a,s=o?1/o:0;return e[0]=-r*s,e[1]=-i*s,e[2]=-n*s,e[3]=a*s,e},t.conjugate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e},t.fromMat3=d,t.fromEuler=function(e,t,r,i){var n=.5*Math.PI/180;t*=n,r*=n,i*=n;var a=Math.sin(t),o=Math.cos(t),s=Math.sin(r),d=Math.cos(r),l=Math.sin(i),u=Math.cos(i);return e[0]=a*d*u-o*s*l,e[1]=o*s*u+a*d*l,e[2]=o*d*l-a*s*u,e[3]=o*d*u+a*s*l,e},t.str=function(e){return"quat("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"};var l=i(r(0)),u=i(r(1)),c=i(r(2)),f=i(r(3)),h=(t.clone=f.clone,t.fromValues=f.fromValues,t.copy=f.copy,t.set=f.set,t.add=f.add,t.mul=o,t.scale=f.scale,t.dot=f.dot,t.lerp=f.lerp,t.length=f.length),R=(t.len=h,t.squaredLength=f.squaredLength),m=(t.sqrLen=R,t.normalize=f.normalize);t.exactEquals=f.exactEquals,t.equals=f.equals,t.rotationTo=function(){var e=c.create(),t=c.fromValues(1,0,0),r=c.fromValues(0,1,0);return function(i,n,o){var s=c.dot(n,o);return s<-.999999?(c.cross(e,t,n),c.len(e)<1e-6&&c.cross(e,r,n),c.normalize(e,e),a(i,e,Math.PI),i):s>.999999?(i[0]=0,i[1]=0,i[2]=0,i[3]=1,i):(c.cross(e,n,o),i[0]=e[0],i[1]=e[1],i[2]=e[2],i[3]=1+s,m(i,i))}}(),t.sqlerp=function(){var e=n(),t=n();return function(r,i,n,a,o,d){return s(e,i,o,d),s(t,n,a,d),s(r,e,t,2*d*(1-d)),r}}(),t.setAxes=function(){var e=u.create();return function(t,r,i,n){return e[0]=i[0],e[3]=i[1],e[6]=i[2],e[1]=n[0],e[4]=n[1],e[7]=n[2],e[2]=-r[0],e[5]=-r[1],e[8]=-r[2],m(t,d(t,e))}}()},function(e,t,r){"use strict";function i(){var e=new c.ARRAY_TYPE(2);return e[0]=0,e[1]=0,e}function n(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e}function a(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e}function o(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e}function s(e,t){var r=t[0]-e[0],i=t[1]-e[1];return Math.sqrt(r*r+i*i)}function d(e,t){var r=t[0]-e[0],i=t[1]-e[1];return r*r+i*i}function l(e){var t=e[0],r=e[1];return Math.sqrt(t*t+r*r)}function u(e){var t=e[0],r=e[1];return t*t+r*r}Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.sqrDist=t.dist=t.div=t.mul=t.sub=t.len=void 0,t.create=i,t.clone=function(e){var t=new c.ARRAY_TYPE(2);return t[0]=e[0],t[1]=e[1],t},t.fromValues=function(e,t){var r=new c.ARRAY_TYPE(2);return r[0]=e,r[1]=t,r},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e},t.set=function(e,t,r){return e[0]=t,e[1]=r,e},t.add=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e},t.subtract=n,t.multiply=a,t.divide=o,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e},t.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e},t.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e},t.scale=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e},t.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e},t.distance=s,t.squaredDistance=d,t.length=l,t.squaredLength=u,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e},t.normalize=function(e,t){var r=t[0],i=t[1],n=r*r+i*i;return n>0&&(n=1/Math.sqrt(n),e[0]=t[0]*n,e[1]=t[1]*n),e},t.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]},t.cross=function(e,t,r){var i=t[0]*r[1]-t[1]*r[0];return e[0]=e[1]=0,e[2]=i,e},t.lerp=function(e,t,r,i){var n=t[0],a=t[1];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e},t.random=function(e,t){t=t||1;var r=2*c.RANDOM()*Math.PI;return e[0]=Math.cos(r)*t,e[1]=Math.sin(r)*t,e},t.transformMat2=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[2]*n,e[1]=r[1]*i+r[3]*n,e},t.transformMat2d=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[2]*n+r[4],e[1]=r[1]*i+r[3]*n+r[5],e},t.transformMat3=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[3]*n+r[6],e[1]=r[1]*i+r[4]*n+r[7],e},t.transformMat4=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[4]*n+r[12],e[1]=r[1]*i+r[5]*n+r[13],e},t.str=function(e){return"vec2("+e[0]+", "+e[1]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]},t.equals=function(e,t){var r=e[0],i=e[1],n=t[0],a=t[1];return Math.abs(r-n)<=c.EPSILON*Math.max(1,Math.abs(r),Math.abs(n))&&Math.abs(i-a)<=c.EPSILON*Math.max(1,Math.abs(i),Math.abs(a))};var c=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(0));t.len=l,t.sub=n,t.mul=a,t.div=o,t.dist=s,t.sqrDist=d,t.sqrLen=u,t.forEach=function(){var e=i();return function(t,r,i,n,a,o){var s,d=void 0;for(r||(r=2),i||(i=0),s=n?Math.min(n*r+i,t.length):t.length,d=i;dc&&(e=c),this["_"+r]=e,n.callback&&n.callback.call(this,e)}};break;case"uint":d=n.hasOwnProperty("min"),l=n.hasOwnProperty("max"),u=n.min,c=n.max;d&&u<0&&RedGLUtil.throwFunc(t+" - "+r+" : min옵션은 0보다 커야 함.","입력값 : "+u),l&&c<0&&RedGLUtil.throwFunc(t+" - "+r+" : max옵션은 0보다 커야 함.","입력값 : "+c),d&&l&&c<=u&&RedGLUtil.throwFunc(t+" - "+r+" : max옵션은 min옵션보다 커야 함.","min 입력값 : "+u,"max 입력값 : "+c),a={get:function(){return this["_"+r]},set:function(e){"number"!=typeof e&&RedGLUtil.throwFunc(t+" - "+r+" : uint만 허용함.","입력값 : "+e),d&&ec&&(e=c),e>=0&&Math.floor(e)==e||RedGLUtil.throwFunc(t+" - "+r+" : uint만 허용함(소수점은 허용하지 않음).","입력값 : "+e),this["_"+r]=e,n.callback&&n.callback.call(this,e)}};break;case"int":d=n.hasOwnProperty("min"),l=n.hasOwnProperty("max"),u=n.min,c=n.max;d&&l&&c<=u&&RedGLUtil.throwFunc(t+" - "+r+" : max옵션은 min옵션보다 커야 함.","min 입력값 : "+u,"max 입력값 : "+c),a={get:s,set:function(e){"number"!=typeof e&&RedGLUtil.throwFunc(t+" - "+r+" : int만 허용함.","입력값 : "+e),d&&ec&&(e=c),Math.floor(e)!=e&&RedGLUtil.throwFunc(t+" - "+r+" : int만 허용함(소수점은 허용하지 않음).","입력값 : "+e),this["_"+r]=e,n.callback&&n.callback.call(this,e)}};break;case"sampler2D":o="RedBaseTexture";break;case"samplerCube":o="RedBitmapCubeTexture";break;case"samplerVideo":o="RedVideoTexture";break;default:RedGLUtil.throwFunc(r+" - type : "+i+" / "+r+" : 정의할수없는 타입입니다.")}if(o){var f=window[o];a=n.essential?{get:s,set:function(e){f==RedBitmapCubeTexture?e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e):!(e instanceof RedBitmapCubeTexture)&&e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e),this["_"+r]=e,n.callback&&n.callback.call(this)}}:{get:s,set:function(e){e&&(f==RedBitmapCubeTexture?e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e):!(e instanceof RedBitmapCubeTexture)&&e instanceof f||RedGLUtil.throwFunc(t+" - "+r+" : "+o+" Instance만 허용.","입력값 : "+e)),this["_"+r]=e,n.callback&&n.callback.call(this)}}}e["_"+r]=null,Object.defineProperty(e,r,a)},(RedDefinePropertyInfo={}).definePrototype=function(t,r,i,n){e(window[t].prototype,t,r,i,n)},RedDefinePropertyInfo.definePrototypes=function(t){for(var r,i=arguments.length;i-- >1;)r=arguments[i],e(window[t].prototype,t,r[0],r[1],r[2])},Object.freeze(RedDefinePropertyInfo)}(),(RedGLDetect=function(e){if(!(this instanceof RedGLDetect))return new RedGLDetect(e);var t,r,i,n,a,o=this,s=e.gl;for(i in t={basic:["VENDOR","VERSION","SHADING_LANGUAGE_VERSION","RENDERER"],frameBuffer:["MAX_RENDERBUFFER_SIZE","MAX_VIEWPORT_DIMS","RED_BITS","GREEN_BITS","BLUE_BITS","ALPHA_BITS","DEPTH_BITS","STENCIL_BITS"],vertexShader:["MAX_VERTEX_ATTRIBS","MAX_VARYING_VECTORS","MAX_VERTEX_UNIFORM_VECTORS"],fragmentShader:["MAX_FRAGMENT_UNIFORM_VECTORS"],texture:["MAX_TEXTURE_SIZE","MAX_CUBE_MAP_TEXTURE_SIZE","MAX_COMBINED_TEXTURE_IMAGE_UNITS","MAX_TEXTURE_IMAGE_UNITS","MAX_VERTEX_TEXTURE_IMAGE_UNITS"]})for(r=(a=t[i]).length,this[i]={};r--;)this[i][n=a[r]]=s.getParameter(s[n]);this.BROWSER_INFO=RedGLDetect.getBrowserInfo(),"ie"==this.BROWSER_INFO.browser&&(console.table=console.log),requestAnimationFrame(function(){var t=document.createElement("canvas"),r=t.getContext("2d");t.width=10,t.height=20,r.fillStyle="red",r.fillRect(0,0,10,10),r.fillStyle="blue",r.fillRect(0,10,10,10),t.style.cssText="position:fixed;top:0px;left:0px";var i=RedBitmapTexture(e,t),n=s.createFramebuffer();s.bindFramebuffer(s.FRAMEBUFFER,n),s.framebufferTexture2D(s.FRAMEBUFFER,s.COLOR_ATTACHMENT0,s.TEXTURE_2D,i.webglTexture,0);var a=new Uint8Array(4);s.readPixels(0,0,1,1,s.RGBA,s.UNSIGNED_BYTE,a),s.bindFramebuffer(s.FRAMEBUFFER,null),o.ableCanvasSourceFlipYonTexture=255===a[0],o.BROWSER_INFO.ableCanvasSourceFlipYonTexture=255===a[0]})}).BROWSER_INFO={},RedGLDetect.getBrowserInfo=function(){var e,t,r,i,n,a=RedGLDetect.BROWSER_INFO,o=window.navigator,s=o.userAgent.toLowerCase(),d=o.platform.toLowerCase(),l=o.appVersion.toLowerCase(),u="pc",c=0,f=function(){return s.indexOf("whale")<0?0:(t=parseFloat(/whale\/([\d]+)/.exec(s)[1]),e="whale")},h=function(){if(!(s.indexOf(n="chrome")<0&&s.indexOf(n="crios")<0))return e="chrome",t=parseFloat(("chrome"===n?/chrome\/([\d]+)/:/crios\/([\d]+)/).exec(s)[1])},R=function(){return s.indexOf("firefox")<0?0:(e="firefox",t=parseFloat(/firefox\/([\d]+)/.exec(s)[1]))},m=function(){return s.indexOf("safari")<0?0:(e="safari",t=parseFloat(/safari\/([\d]+)/.exec(s)[1]))},p=function(){var r;return s.indexOf(r="opera")<0&&s.indexOf(r="opr")<0?0:(e="opera",t="opera"===r?parseFloat(/version\/([\d]+)/.exec(s)[1]):parseFloat(/opr\/([\d]+)/.exec(s)[1]))},_=function(){return s.indexOf("naver")<0?0:e="naver"};if(a||(a={}),s.indexOf("android")>-1)e=r="android",u=-1===s.indexOf("mobile")?(e+="Tablet","tablet"):"mobile",i=(n=/android ([\d.]+)/.exec(s))?(n=n[1].split("."),parseFloat(n[0]+"."+n[1])):0,c=1,f()||_()||p()||h()||R()||(t=n=/safari\/([\d.]+)/.exec(s)?parseFloat(n[1]):0);else if(s.indexOf(n="ipad")>-1||s.indexOf(n="iphone")>-1)u="ipad"===n?"tablet":"mobile",e=r=n,i=(n=/os ([\d_]+)/.exec(s))?(n=n[1].split("_"),parseFloat(n[0]+"."+n[1])):0,c=1,f()||_()||p()||h()||R()||(t=(n=/mobile\/([\S]+)/.exec(s))?parseFloat(n[1]):0);else if(d.indexOf("win")>-1){for(n in g={5.1:"xp","6.0":"vista",6.1:"7",6.2:"8",6.3:"8.1","10.0":"10"})if(s.indexOf("windows nt "+n)>-1){i=g[n];break}r="win",(s.indexOf("edge")>-1?(s.indexOf("iemobile")>-1&&(r="winMobile"),e="edge",t=/edge\/([\d]+)/.exec(s)[1]):s.indexOf("msie")<0&&s.indexOf("trident")<0?void 0:(s.indexOf("iemobile")>-1&&(r="winMobile"),e="ie",t=s.indexOf("msie 7")>-1&&s.indexOf("trident")>-1?-1:s.indexOf("msie")<0?11:parseFloat(/msie ([\d]+)/.exec(s)[1])))||f()||p()||h()||R()||m()}else d.indexOf("mac")>-1?(r="mac",n=/os x ([\d._]+)/.exec(s)[1].replace("_",".").split("."),i=parseFloat(n[0]+"."+n[1]),f()||p()||h()||R()||m()):(r=l.indexOf("x11")>-1?"unix":l.indexOf("linux")>-1?"linux":0,f()||h()||R());for(n in g={device:u,isMobile:c,browser:e,browserVer:t,os:r,osVer:i,down:c?"touchstart":"mousedown",move:c?"touchmove":"mousemove",up:c?"touchend":"mouseup",click:"click",over:"mouseover",out:"mouseout"})g.hasOwnProperty(n)&&(a[n]=g[n]);if(window.OffscreenCanvas){var g=new window.OffscreenCanvas(2,2);try{g.getContext("2d")}catch(e){window.OffscreenCanvas=null}}return a},Object.freeze(RedGLDetect),function(){var e,t,r,i,n,a,o,s,d,l,u,c,f,h;RedGLUtil={throwFunc:function(){throw"RedGL Error : "+Array.prototype.slice.call(arguments).join(" ")},isUint:function(e,t){return"number"==typeof e&&e>=0||RedGLUtil.throwFunc(t,"입력값 : "+e),Math.floor(e)===e||RedGLUtil.throwFunc(t,"입력값 : "+e),!0},hexToRGB_ZeroToOne:function(e){var t,r;if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(e))return r=[],3===(t=e.substring(1).split("")).length&&(t=[t[0],t[0],t[1],t[1],t[2],t[2]]),t="0x"+t.join(""),r[0]=(t>>16&255)/255,r[1]=(t>>8&255)/255,r[2]=(255&t)/255,r;RedGLUtil.throwFunc("RedGLUtil.hexToRGB_ZeroToOne : 잘못된 hex값입니다.",e)},rgb2hex:function(e,t,r){return"#"+(16777216+(r|t<<8|e<<16)).toString(16).slice(1)},regHex:(h=/^#(?:[0-9a-fA-F]{3}){1,2}$/,function(e){return h.test(e)}),getStrFromComment:function(e){if("string"!=typeof e&&RedGLUtil.throwFunc("getStrFromComment : 해석할 값은 문자열만 가능",e),f=e.replace("@preserve","").toString().trim().match(/(\/\*)[\s\S]+(\*\/)/g))return f[0].replace(/\/\*|\*\//g,"").trim();RedGLUtil.throwFunc("getStrFromComment : 해석할 불가능한 값",e)},isPowerOf2:function(e){return 0==(e&e-1)},nextHighestPowerOfTwo:function(e){for(--e,c=1;c<32;c<<=1)e|=e>>c;return e+1},makePowerOf2Source:function(e,t,r){if(u=r,RedGLUtil.isPowerOf2(t.width)&&RedGLUtil.isPowerOf2(t.height))return t;d=RedGLUtil.nextHighestPowerOfTwo(t.width),l=RedGLUtil.nextHighestPowerOfTwo(t.height),d>u&&(d=u),l>u&&(l=u);var i=window.OffscreenCanvas?new OffscreenCanvas(d,l):document.createElement("canvas"),n=i.getContext("2d");return window.OffscreenCanvas||(i.width=d,i.height=l),n.drawImage(t,0,0,d,l),window.OffscreenCanvas?i.transferToImageBitmap():i},calculateNormals:function(e,t){var r,i,n=[];for(r=0;r-1?l=(document.documentElement?document.documentElement.clientWidth:document.body.clientWidth)*parseFloat(l)/100:RedGLUtil.throwFunc("RedGL setSize : width는 0이상의 숫자나 %만 허용.","입력값 :",l)),"number"!=typeof u&&(u.indexOf("%")>-1?u=window.innerHeight*parseFloat(u)/100:RedGLUtil.throwFunc("RedGL setSize : height는 0이상의 숫자나 %만 허용.","입력값 :",u)),R=window.devicePixelRatio||1,m=this._canvas,(c!=l||h!=u||r)&&(m.width=l*R*this._renderScale,m.height=u*R*this._renderScale,m.style.width=l+"px",m.style.height=u+"px",c=l,h=u),this._viewRect[2]=c,this._viewRect[3]=h):(l=this._width=e,u=this._height=t,p[0]=l*this._renderScale,_[0]=u*this._renderScale,this._viewRect[2]=l,this._viewRect[3]=u)}),RedSystemShaderCode.init&&RedSystemShaderCode.init(d),t(d,s),f.push(d),void requestAnimationFrame(function(){r||(RedPBRMaterial_System(d),RedStandardMaterial(d,d._datas.emptyTexture["2d"]),RedEnvironmentMaterial(d,null,d._datas.emptyTexture["3d"])),d._mouseEventInfo=[],[RedGLDetect.BROWSER_INFO.move,RedGLDetect.BROWSER_INFO.down,RedGLDetect.BROWSER_INFO.up].forEach(function(e){var t,r;"ie"===RedGLDetect.BROWSER_INFO.browser&&11===RedGLDetect.BROWSER_INFO.browserVer?(t="offsetX",r="offsetY"):(t="layerX",r="layerY"),d._canvas.addEventListener(e,function(e){e.preventDefault(),RedGLDetect.BROWSER_INFO.isMobile?e.changedTouches[0]&&(d._mouseEventInfo.push({type:e.type,x:e.changedTouches[0].clientX,y:e.changedTouches[0].clientY,nativeEvent:e}),d._mouseX=e.changedTouches[0].clientX,d._mouseY=e.changedTouches[0].clientY):(d._mouseEventInfo.push({type:e.type,x:e[t],y:e[r],nativeEvent:e}),d._mouseX=e[t],d._mouseY=e[r])},!1)}),d.setSize(d._width,d._height),n&&n.call(d,!0)})):n?n.call(d,!1):void 0):new RedGL(i,n,a,o);var s,d,l,u,c,h,R,m,p,_}).makeUUID=(c=0,function(){return c++}),RedGL.prototype={},RedDefinePropertyInfo.definePrototype("RedGL","renderScale","number",{min:.1,max:1,callback:function(){this.setSize(this._width,this._height,!0)}}),RedGL.setDoNotPrepareProgram=function(){r=!0},Object.freeze(RedGL)}(),function(){var e,t,r,i,n,a={x:0,y:0},o={x:0,y:0},s=[];n=function(n,d){return RedGLDetect.BROWSER_INFO.isMobile?n.changedTouches?(o.x=n.changedTouches[0].clientX,o.y=n.changedTouches[0].clientY):(o.x=a.x,o.y=a.y):(o.x=n.clientX,o.y=n.clientY),t=o.x-a.x,r=o.y-a.y,s=[a.x,a.y,t,r],t<0&&(s[2]=Math.abs(t),s[0]+=t),r<0&&(s[3]=Math.abs(r),s[1]+=r),e.style.left=s[0]+"px",e.style.top=s[1]+"px",e.style.width=s[2]+"px",e.style.height=s[3]+"px",i(d.scene,d,s)},i=function(e,t,r,n){return n||(n={selectList:[],unSelectList:[]}),e.children.forEach(function(e){var a=e.getScreenPoint(t);r[0]<=a[0]&&r[1]<=a[1]&&r[0]+r[2]>=a[0]&&r[1]+r[3]>=a[1]?n.selectList.push(e):n.unSelectList.push(e),i(e,t,r,n)}),n},RedBoxSelection=function(t,r,i){return this instanceof RedBoxSelection?(t instanceof RedGL||RedGLUtil.throwFunc("RedBoxSelection : RedGL Instance만 허용.",t),r instanceof RedView||RedGLUtil.throwFunc("RedBoxSelection : RedView Instance만 허용.",r),t._datas.RedBoxSelection?this:(t._datas.RedBoxSelection=this,void[RedGLDetect.BROWSER_INFO.move,RedGLDetect.BROWSER_INFO.down,RedGLDetect.BROWSER_INFO.up].forEach(function(s){var d;d=function(e){var t=n(e,r);i&&i(t)},t._canvas.addEventListener(s,function(t){t.type===RedGLDetect.BROWSER_INFO.down&&(o.x=a.x=RedGLDetect.BROWSER_INFO.isMobile?t.changedTouches[0].clientX:t.clientX,o.y=a.y=RedGLDetect.BROWSER_INFO.isMobile?t.changedTouches[0].clientY:t.clientY,e||((e=document.createElement("div")).style.cssText="position:fixed;border:1px dashed red;z-index:0"),e.style.left="0px",e.style.top="0px",e.style.width="0px",e.style.height="0px",document.body.appendChild(e),r.camera&&r.camera.camera&&(r.camera.needUpdate=!1),d({}),window.addEventListener(RedGLDetect.BROWSER_INFO.move,d),window.addEventListener(RedGLDetect.BROWSER_INFO.isMobile?"touchend":"click",function(){r.camera.camera&&(r.camera.needUpdate=!0),e.parentNode&&document.body.removeChild(e),window.removeEventListener(RedGLDetect.BROWSER_INFO.move,d)}))})}))):new RedBoxSelection(t,r,i)}}(),(RedBaseController=function(){if(!(this instanceof RedBaseController))return new RedBaseController}).prototype={update:function(){RedGLUtil.throwFunc("RedBaseController : update - 재정의 해서 써라")}},Object.freeze(RedBaseController),function(){var e=function(e,t){return createImageBitmap(e,t||{imageOrientation:"none"})};RedImageLoader=function(t,r,i,n){var a,o,s,d,l=this;if(!(this instanceof RedImageLoader))return new RedImageLoader(t,r,i,n);("string"!=typeof t&&RedGLUtil.throwFunc("RedImageLoader : src는 문자열 만 허용.","입력값 : "+t),l._src=t,l._onLoad=r,l._onError=i,window&&window.document)?(d=function(e){e.removeEventListener("error",s),e.removeEventListener("load",o)},s=function(e){d(this),l._onError&&l._onError(e)},o=function(e){d(this),l.source=a,l._onLoad&&l._onLoad(e)},(a=new Image).crossOrigin="anonymous",a.src=t,a.addEventListener("error",s),a.addEventListener("load",o)):2===t.split(",").length&&"data:"===t.substr(0,5)?e(function(e,t){t=t||"";for(var r=atob(e),i=r.length,n=Math.ceil(i/1024),a=new Array(n),o=0;o4&&RedGLUtil.throwFunc("RedBaseObject3D - addLOD : level은 0~4 level 까지 허용함"),n={level:e,distance:t,geometry:r||this.geometry,material:i||this.material},o=this._lodLevels.length,a=!0;o--;)this._lodLevels[o].level==e&&(this._lodLevels[o]=n,a=!1);a&&this._lodLevels.push(n)},removeLOD:function(e){RedGLUtil.isUint(e)||RedGLUtil.throwFunc("RedBaseObject3D - removeLOD : level : uint만 허용함");for(var t=this._lodLevels.length;t--;)if(this._lodLevels[t].level==e){this._lodLevels.splice(t,1);break}},localToWorld:function(){var e;return e=mat4.create(),function(t,r,i){return"number"==typeof t||RedGLUtil.throwFunc("RedBaseObject3D - localToWorld : x - number만 허용함","입력값 : ",t),"number"==typeof r||RedGLUtil.throwFunc("RedBaseObject3D - localToWorld : y - number만 허용함","입력값 : ",r),"number"==typeof i||RedGLUtil.throwFunc("RedBaseObject3D - localToWorld : z - number만 허용함","입력값 : ",i),t=t||0,r=r||0,i=i||0,mat4.identity(e),mat4.translate(e,e,[t,r,i]),mat4.multiply(e,this.matrix,e),[e[12],e[13],e[14]]}}(),worldToLocal:function(){var e,t;return e=mat4.create(),t=mat4.create(),function(r,i,n){return"number"==typeof r||RedGLUtil.throwFunc("RedBaseObject3D - worldToLocal : x - number만 허용함","입력값 : ",r),"number"==typeof i||RedGLUtil.throwFunc("RedBaseObject3D - worldToLocal : y - number만 허용함","입력값 : ",i),"number"==typeof n||RedGLUtil.throwFunc("RedBaseObject3D - worldToLocal : z - number만 허용함","입력값 : ",n),r=r||0,i=i||0,n=n||0,mat4.translate(e,e,[r,i,n]),mat4.multiply(t,e,this.matrix),[t[0]*r+t[1]*i+t[2]*n+t[3],t[4]*r+t[5]*i+t[6]*n+t[7],t[8]*r+t[9]*i+t[10]*n+t[11]]}}(),getScreenPoint:(i=mat4.create(),r={x:0,y:0,z:0,w:0},function(n){return mat4.identity(i),n instanceof RedView||RedGLUtil.throwFunc("RedBaseObject3D - getScreenPoint : redView - RedView Instance 만 허용함","입력값 : ",n),e=n.camera,t=n._viewRect,e instanceof RedBaseController&&(e=e.camera),mat4.multiply(i,e.perspectiveMTX,e.matrix),mat4.multiply(i,i,this.matrix),r.x=i[12],r.y=i[13],r.z=i[14],r.w=i[15],r.x=.5*r.x/r.w+.5,r.y=.5*r.y/r.w+.5,[(t[0]+r.x*t[2])/window.devicePixelRatio,(t[1]+(1-r.y)*t[3])/window.devicePixelRatio]}),disposeAll:function(){this.disposeAllTexture(),this.disposeAllBuffer()},disposeAllTexture:function(){this.material&&this.material.disposeAllTexture()},disposeTexture:function(e){this.material&&this.material.disposeTexture(e)},disposeAllBuffer:function(){this.geometry&&this.geometry.disposeAllBuffer()},disposeBuffer:function(e){this.geometry&&this.geometry.disposeBuffer(e)}},u=function(e){var t,r,i,n,a,o,s,d,l,u,c,f,h,R,m,p,_=e.matrix,g=e.geometry.interleaveBuffer.stride;for(t=r=i=n=a=o=0,u=e.geometry.interleaveBuffer.data,c=0,f=e.geometry.interleaveBuffer.pointNum;cn?h:n,r=(R=_[1]*u[s]+_[5]*u[d]+_[9]*u[l])a?R:a,i=(m=_[2]*u[s]+_[6]*u[d]+_[10]*u[l])o?m:o;return(p=[n-t,a-r,o-i]).minX=t,p.maxX=n,p.minY=r,p.maxY=a,p.minZ=i,p.maxZ=o,p},d=function(e){var t=u(e),r=mat4.create();return mat4.translate(r,r,e.localToWorld(0,0,0)),mat4.scale(r,r,t),{worldMatrix:r,volume:t}},l=function(e){var t=e.geometry.volume,r=mat4.create();return mat4.translate(r,r,e.localToWorld(0,0,0)),mat4.rotateX(r,r,-e.rotationX*Math.PI/180),mat4.rotateY(r,r,-e.rotationY*Math.PI/180),mat4.rotateZ(r,r,-e.rotationZ*Math.PI/180),mat4.scale(r,r,t),mat4.scale(r,r,[e.scaleX,e.scaleY,e.scaleZ]),{worldMatrix:r,volume:u(e)}},RedBaseObject3D.prototype.volumeCalculateAABB=function(){return this.volumeInfo=d(this)},RedBaseObject3D.prototype.volumeCalculateOBB=function(){return this.volumeInfo=l(this)},RedBaseObject3D.prototype.lookAt=(c=new Float32Array([0,1,0]),f=[],h=[],function(e,t,r){f[0]=e,f[1]=t,f[2]=r,mat4.identity(this.matrix),mat4.targetTo(this.matrix,[this.x,this.y,this.z],f,c),h=RedGLUtil.mat4ToEuler(this.matrix,[]),this.rotationX=180*-h[0]/Math.PI,this.rotationY=180*-h[1]/Math.PI,this.rotationZ=180*-h[2]/Math.PI}),Object.defineProperty(RedBaseObject3D.prototype,"geometry",{get:function(){return this._geometry},set:function(e){!e||e instanceof RedGeometry||RedGLUtil.throwFunc("geometry : RedGeometry Instance만 허용.","입력값 : "+e),this._geometry=e}}),Object.defineProperty(RedBaseObject3D.prototype,"material",{get:function(){return this._material},set:function(e){!e||e instanceof RedBaseMaterial||RedGLUtil.throwFunc("material : RedBaseMaterial Instance만 허용.","입력값 : "+e),this._material=e}}),Object.defineProperty(RedBaseObject3D.prototype,"outlineColor",{get:function(){return this._outlineColorHex},set:function(){var e;return function(t){this._outlineColorHex=t||"#ff0000",e=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._outlineColorHex),this._outlineColor[0]=e[0],this._outlineColor[1]=e[1],this._outlineColor[2]=e[2],this._outlineColor[3]=this._outlineAlpha}}()}),RedDefinePropertyInfo.definePrototype("RedBaseObject3D","outlineAlpha","number",{min:0,max:1,callback:function(e){this._outlineColor[3]=this._outlineAlpha=e}}),Object.freeze(RedBaseObject3D)}(),function(){var e,t;(e=(RedBaseContainer=function(){if(!(this instanceof RedBaseContainer))return new RedBaseContainer;this.children=[]}).prototype=new RedBaseObject3D).addChild=function(e){e instanceof RedBaseObject3D||RedGLUtil.throwFunc("addChild","RedBaseObject3D Instance만 가능","입력값 : "+e),this.children.indexOf(e)>-1&&this.removeChild(e),this.children.push(e)},e.addChildAt=function(e,t){RedGLUtil.isUint(t,"addChildAt : index는 uint만 입력가능"),e instanceof RedBaseObject3D||RedGLUtil.throwFunc("addChildAt","RedBaseObject3D Instance만 가능","입력값 : "+e),this.children.indexOf(e)>-1&&this.removeChild(e),this.children.lengtht)return 1}return 0})},e.sortMaterial=function(e){if(e)for(var t=this.children.length;t--;)this.children[t].sortMaterial&&this.children[t].sortMaterial(e);this.children.sort(function(e,t){if(e._geometry&&t._geometry){if((e=e._material.program._UUID)<(t=t._material.program._UUID))return-1;if(e>t)return 1}return 0})},e.sortGeometryAndMaterial=function(e){if(e)for(var t=this.children.length;t--;)this.children[t].sortGeometryAndMaterial&&this.children[t].sortGeometryAndMaterial(e);this.children.sort(function(e,t){if(e._geometry&&t._geometry){if((e=e._geometry.interleaveBuffer._UUID)==(t=t._geometry.interleaveBuffer._UUID)){var r=e._material.program._UUID,i=t._material.program._UUID;return ri?1:0}if(et)return 1}return 0})},Object.freeze(RedBaseContainer)}(),function(){var e;(RedBaseLight=function(){if(!(this instanceof RedBaseLight))return new RedBaseLight}).prototype={},RedDefinePropertyInfo.definePrototypes("RedBaseLight",["intensity","number",{min:0}],["alpha","number",{min:0,max:1,callback:function(e){this._lightColor[3]=this._alpha=e}}],["color","hex",{callback:function(){e=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._color),this._lightColor[0]=e[0],this._lightColor[1]=e[1],this._lightColor[2]=e[2],this._lightColor[3]=this._alpha}}]),Object.freeze(RedBaseLight)}(),(RedFrameBuffer=function(e,t,r){if(!(this instanceof RedFrameBuffer))return new RedFrameBuffer(e,t,r);var i;e instanceof RedGL||RedGLUtil.throwFunc("RedFrameBuffer : RedGL Instance만 허용.",e),t&&("number"==typeof t||RedGLUtil.throwFunc("RedFrameBuffer : width - 숫자만 허용","입력값 : ",t)),r&&("number"==typeof r||RedGLUtil.throwFunc("RedFrameBuffer : height - 숫자만 허용","입력값 : ",r)),i=e.gl,r=r||1080,(t=t||1920)>e.detect.texture.MAX_TEXTURE_SIZE&&(t=e.detect.texture.MAX_TEXTURE_SIZE),r>e.detect.texture.MAX_TEXTURE_SIZE&&(r=e.detect.texture.MAX_TEXTURE_SIZE),this.redGL=e,this.width=t,this.height=r,this.webglFrameBuffer=i.createFramebuffer(),this.webglRenderBuffer=i.createRenderbuffer(),this.texture=RedBitmapTexture(e),this._UUID=RedGL.makeUUID(),i.bindFramebuffer(i.FRAMEBUFFER,this.webglFrameBuffer),i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,this.texture.webglTexture),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!1),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.bindRenderbuffer(i.RENDERBUFFER,this.webglRenderBuffer),i.renderbufferStorage(i.RENDERBUFFER,i.DEPTH_COMPONENT16,this.width,this.height),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,this.texture.webglTexture,0),i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_ATTACHMENT,i.RENDERBUFFER,this.webglRenderBuffer),i.bindTexture(i.TEXTURE_2D,null),i.bindRenderbuffer(i.RENDERBUFFER,null),i.bindFramebuffer(i.FRAMEBUFFER,null)}).prototype={bind:function(e){e.bindFramebuffer(e.FRAMEBUFFER,this.webglFrameBuffer),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.texture.webglTexture),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,this.width,this.height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindRenderbuffer(e.RENDERBUFFER,this.webglRenderBuffer),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,this.width,this.height),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture.webglTexture,0),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,this.webglRenderBuffer)},unbind:function(e){e.bindTexture(e.TEXTURE_2D,null),e.bindRenderbuffer(e.RENDERBUFFER,null),e.bindFramebuffer(e.FRAMEBUFFER,null)}},RedDefinePropertyInfo.definePrototypes("RedFrameBuffer",["width","number",{min:2}],["height","number",{min:2}]),Object.freeze(RedFrameBuffer),function(){var e,t,r;e=function(e,t,r){switch(t){case RedBuffer.ARRAY_BUFFER:if(r instanceof Float32Array)return e.FLOAT;if(r instanceof Float64Array)return e.FLOAT;RedGLUtil.throwFunc("RedBuffer : 올바른 TypedArray(RedBuffer.ARRAY_BUFFER)형식을 사용해야합니다.","입력값 : "+r);break;case RedBuffer.ELEMENT_ARRAY_BUFFER:if(r instanceof Int8Array)return e.BYTE;if(r instanceof Int16Array)return e.SHORT;if(r instanceof Int32Array)return e.INT;if(r instanceof Uint8Array)return e.UNSIGNED_BYTE;if(r instanceof Uint16Array)return e.UNSIGNED_SHORT;if(r instanceof Uint32Array)return e.UNSIGNED_INT;RedGLUtil.throwFunc("RedBuffer : 올바른 TypedArray(RedBuffer.ELEMENT_ARRAY_BUFFER)형식을 사용해야합니다.","입력값 : "+r);break;default:RedGLUtil.throwFunc("RedBuffer : bufferType - 지원하지 않는 버퍼타입입니다. ","입력값 : "+t)}},t=function(e,t){switch(t){case RedBuffer.ARRAY_BUFFER:return e.ARRAY_BUFFER;case RedBuffer.ELEMENT_ARRAY_BUFFER:return e.ELEMENT_ARRAY_BUFFER;default:RedGLUtil.throwFunc("RedBuffer : bufferType - 지원하지 않는 버퍼타입입니다. ")}},r=function(e,t,r,i){var n,a,o,s,d;switch(r instanceof Float32Array?d=Float32Array.BYTES_PER_ELEMENT:r instanceof Float64Array&&(d=Float64Array.BYTES_PER_ELEMENT),n=0,t){case RedBuffer.ARRAY_BUFFER:if(e.interleaveDefineInfoList=i,i){for(i.length||RedGLUtil.throwFunc("RedBuffer : interleaveDefineInfoList의 정보는 1개이상의 RedInterleaveInfo Instance로 구성되어야함.",i),a=0,o=i.length;ai?l[o]:i,t=l[s]n?l[s]:n,r=l[d]a?l[d]:a;return this._volume=[i-e,n-t,a-r],this._volume.minX=e,this._volume.maxX=i,this._volume.minY=t,this._volume.maxY=n,this._volume.minZ=r,this._volume.maxZ=a,this._volume}},Object.defineProperty(RedGeometry.prototype,"volume",{get:function(){return this._volume||this.volumeCalculate(),this._volume}}),Object.freeze(RedGeometry)}(),RedInterleaveInfo=function(e,t,r){if(!(this instanceof RedInterleaveInfo))return new RedInterleaveInfo(e,t,r);"string"==typeof e||RedGLUtil.throwFunc("RedInterleaveInfo : attributeKey - 문자열만 허용",e),"a"===e.charAt(0)||RedGLUtil.throwFunc("RedInterleaveInfo : attributeKey 첫글자는 a로 시작해야합니다.",e),e.charAt(1)===e.charAt(1).toUpperCase()||RedInterleaveInfo.throwFunc("RedInterleaveInfo : attributeKey 두번째 글자는 대문자 시작해야합니다.",e),"number"==typeof t||RedGLUtil.throwFunc("RedInterleaveInfo : size - 숫자만 허용",t),this.attributeKey=e,this.size=t,this.normalize=void 0!==r,this.offset=null},Object.freeze(RedInterleaveInfo),function(){var e,t,r,i,n,a,o,s;(RedBaseMaterial=function(){}).prototype={makeProgramList:(s=["fog","sprite3D","skin","directionalShadow"],s.sort(),a=function(e,t,r,i,s,d,l){e.basic[t]||(e.basic[t]=new n(r,e,t,i,s)),d.forEach(function(u,c){d.sort(),l.sort();var f=d.join("_");e[f]||(e[f]={}),e[f][t]||(e[f][t]=new n(r,e,t,i,s,d));var h=d.concat();h.splice(c,1),o(e,f,t,r,i,s,d,l),a(e,t,r,i,s,h,l)})},o=function(e,t,r,i,a,o,s,d){function l(e,t){var r,i,n,a,o;if(t>e.length||t<=0)return[];if(t===e.length)return[e];if(1===t){for(n=[],r=0;r1?e.LINEAR_MIPMAP_NEAREST:e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,i.mag?i.mag:e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),n&&n(!0)},s.onerror=function(){n&&n(!1)},s.send(null),o}}(RedDDSTexture.prototype),Object.freeze(RedDDSTexture),function(){var e;e=function(e,t,r,i,n,a){var o,s,d,l,u,c=[];for(n=n||{},o=function(){0===u&&a&&a.call(t,!1),u++},s=function(){if(6==++l){e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_CUBE_MAP,r),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,0),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MIN_FILTER,n.min?n.min:e.LINEAR_MIPMAP_NEAREST),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MAG_FILTER,n.mag?n.mag:e.LINEAR),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_S,n.wrap_s?n.wrap_s:e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_T,n.wrap_t?n.wrap_t:e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c[0].source),e.texImage2D(e.TEXTURE_CUBE_MAP_NEGATIVE_X,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c[1].source),e.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_Y,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c[2].source),e.texImage2D(e.TEXTURE_CUBE_MAP_NEGATIVE_Y,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c[3].source),e.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_Z,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c[4].source),e.texImage2D(e.TEXTURE_CUBE_MAP_NEGATIVE_Z,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,c[5].source),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,0);try{e.generateMipmap(e.TEXTURE_CUBE_MAP)}catch(e){}e.bindTexture(e.TEXTURE_CUBE_MAP,null),0===u&&a&&a.call(t,!0)}},d=6,l=0,u=0;d--;)c[d]=RedImageLoader(i[d],s,o,{})},(RedBitmapCubeTexture=function(t,r,i,n){var a;if(!(this instanceof RedBitmapCubeTexture))return new RedBitmapCubeTexture(t,r,i,n);t instanceof RedGL||RedGLUtil.throwFunc("RedBitmapCubeTexture : RedGL Instance만 허용.","입력값 : "+t),n&&"function"==typeof n||!n||RedGLUtil.throwFunc("RedBitmapCubeTexture : callback Function만 허용.",n),a=t.gl,i=i||{};var o=r.toString()+JSON.stringify(i);if(r instanceof Array&&(t._datas.textures||(t._datas.textures={}),t._datas.textures[o]))return n&&setTimeout(function(){n.call(this,!0)},1),t._datas.textures[o];this.webglTexture=a.createTexture(),this.webglTexture.gl=a,this._UUID=RedGL.makeUUID(),this._load=function(t){RedTextureOptionChecker.check("RedBitmapCubeTexture",i,a),t&&this.setEmptyTexture(a,this.webglTexture),this._srcList&&e(a,this,this.webglTexture,this._srcList,this._option,this._callback)},this._option=i,this.callback=n,this.srcList=r,t._datas.textures[o]=this}).prototype=new RedBaseTexture,Object.defineProperty(RedBitmapCubeTexture.prototype,"srcList",{get:function(){return this._srcList},set:function(e){e instanceof Array||RedGLUtil.throwFunc("RedBitmapCubeTexture : srcList는 배열만 허용.","입력값 : "+e),6===e.length||RedGLUtil.throwFunc("RedBitmapCubeTexture : srcList 길이는 6이어야함","입력값 : "+e),this._srcList=e,this._load(!0)}}),Object.defineProperty(RedBitmapCubeTexture.prototype,"option",{get:function(){return this._option},set:function(e){this._option=e,this._load(!1)}}),Object.freeze(RedBitmapCubeTexture)}(),function(){var e,t,r,i,n=[];e=function(){ /* @preserve //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# @@ -197,7 +197,7 @@ if(finalColor.a == 0.0) discard; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/};var n={callback:function(){this._searchProgram("RedColorPhongTextureMaterialProgram",i)}};(RedColorPhongTextureMaterial=function(n,a,o,s,d,u,c){if(!(this instanceof RedColorPhongTextureMaterial))return new RedColorPhongTextureMaterial(n,a,o,s,d,u,c);n instanceof RedGL||RedGLUtil.throwFunc("RedColorPhongTextureMaterial : RedGL Instance만 허용.","입력값 : "+n),this.makeProgramList(this,n,"RedColorPhongTextureMaterialProgram",e,t,i),this._color=new Float32Array(4),this.normalTexture=s,this.specularTexture=d,this.displacementTexture=u,this.emissiveTexture=c,this.normalPower=1,this.shininess=16,this.specularPower=1,this.emissiveFactor=1,this.displacementPower=.1,this.displacementFlowSpeedX=0,this.displacementFlowSpeedY=0,this.alpha=null==o?1:o,this.color=a||"#ff0000",this.usePreMultiply=!1,this.useFlatMode=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,Object.defineProperty(RedColorPhongTextureMaterial.prototype,"color",RedColorMaterial.DEFINE_OBJECT_COLOR),RedDefinePropertyInfo.definePrototypes("RedColorPhongTextureMaterial",["alpha","number",RedColorMaterial.DEFINE_OBJECT_ALPHA],["normalTexture","sampler2D",n],["specularTexture","sampler2D",n],["displacementTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["normalPower","number",{min:0}],["shininess","number",{min:0}],["specularPower","number",{min:0}],["emissiveFactor","number",{min:0}],["displacementPower","number",{min:0}],["displacementFlowSpeedX","number"],["displacementFlowSpeedY","number"],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedColorPhongTextureMaterial)}(),function(){var e,t,r,i=["diffuseTexture","normalTexture","specularTexture","displacementTexture","emissiveTexture","useFlatMode","usePreMultiply"];e=function(){ +*/};var n={callback:function(){this._searchProgram("RedColorPhongTextureMaterialProgram",i)}};(RedColorPhongTextureMaterial=function(n,a,o,s,d,l,u){if(!(this instanceof RedColorPhongTextureMaterial))return new RedColorPhongTextureMaterial(n,a,o,s,d,l,u);n instanceof RedGL||RedGLUtil.throwFunc("RedColorPhongTextureMaterial : RedGL Instance만 허용.","입력값 : "+n),this.makeProgramList(this,n,"RedColorPhongTextureMaterialProgram",e,t,i),this._color=new Float32Array(4),this.normalTexture=s,this.specularTexture=d,this.displacementTexture=l,this.emissiveTexture=u,this.normalPower=1,this.shininess=16,this.specularPower=1,this.emissiveFactor=1,this.displacementPower=.1,this.displacementFlowSpeedX=0,this.displacementFlowSpeedY=0,this.alpha=null==o?1:o,this.color=a||"#ff0000",this.usePreMultiply=!1,this.useFlatMode=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,Object.defineProperty(RedColorPhongTextureMaterial.prototype,"color",RedColorMaterial.DEFINE_OBJECT_COLOR),RedDefinePropertyInfo.definePrototypes("RedColorPhongTextureMaterial",["alpha","number",RedColorMaterial.DEFINE_OBJECT_ALPHA],["normalTexture","sampler2D",n],["specularTexture","sampler2D",n],["displacementTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["normalPower","number",{min:0}],["shininess","number",{min:0}],["specularPower","number",{min:0}],["emissiveFactor","number",{min:0}],["displacementPower","number",{min:0}],["displacementFlowSpeedX","number"],["displacementFlowSpeedY","number"],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedColorPhongTextureMaterial)}(),function(){var e,t,r,i=["diffuseTexture","normalTexture","specularTexture","displacementTexture","emissiveTexture","useFlatMode","usePreMultiply"];e=function(){ /* @preserve //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# @@ -298,7 +298,7 @@ finalColor.a = texelColor.a * u_alpha; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/},(RedEnvironmentMaterial=function(n,a,o,s,d,u,c){if(!(this instanceof RedEnvironmentMaterial))return new RedEnvironmentMaterial(n,a,o,s,d,u,c);n instanceof RedGL||RedGLUtil.throwFunc("RedEnvironmentMaterial : RedGL Instance만 허용.",n),o instanceof RedBitmapCubeTexture||RedGLUtil.throwFunc("RedEnvironmentMaterial : environmentTexture - RedBitmapCubeTexture Instance만 허용."),this.makeProgramList(this,n,"RedEnvironmentMaterialProgram",e,t,i),this.diffuseTexture=a,this.environmentTexture=o,this.normalTexture=s,this.specularTexture=d,this.displacementTexture=u,this.emissiveTexture=c,this.normalPower=1,this.shininess=8,this.specularPower=1,this.emissiveFactor=1,this.reflectionPower=1,this.displacementPower=.1,this.displacementFlowSpeedX=0,this.displacementFlowSpeedY=0,this.alpha=1,this.useFlatMode=!1,this.usePreMultiply=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial;var n={callback:function(){this._searchProgram("RedEnvironmentMaterialProgram",i)}};RedDefinePropertyInfo.definePrototypes("RedEnvironmentMaterial",["alpha","number",{min:0,max:1}],["diffuseTexture","sampler2D",n],["environmentTexture","samplerCube",{essential:!0,callback:n.callback}],["normalTexture","sampler2D",n],["specularTexture","sampler2D",n],["displacementTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["normalPower","number",{min:0}],["shininess","number",{min:0}],["specularPower","number",{min:0}],["emissiveFactor","number",{min:0}],["reflectionPower","number",{min:0}],["displacementPower","number",{min:0}],["displacementFlowSpeedX","number"],["displacementFlowSpeedY","number"],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedEnvironmentMaterial)}(),function(){var e,t,r,i=["usePreMultiply"];e=function(){ +*/},(RedEnvironmentMaterial=function(n,a,o,s,d,l,u){if(!(this instanceof RedEnvironmentMaterial))return new RedEnvironmentMaterial(n,a,o,s,d,l,u);n instanceof RedGL||RedGLUtil.throwFunc("RedEnvironmentMaterial : RedGL Instance만 허용.",n),o instanceof RedBitmapCubeTexture||RedGLUtil.throwFunc("RedEnvironmentMaterial : environmentTexture - RedBitmapCubeTexture Instance만 허용."),this.makeProgramList(this,n,"RedEnvironmentMaterialProgram",e,t,i),this.diffuseTexture=a,this.environmentTexture=o,this.normalTexture=s,this.specularTexture=d,this.displacementTexture=l,this.emissiveTexture=u,this.normalPower=1,this.shininess=8,this.specularPower=1,this.emissiveFactor=1,this.reflectionPower=1,this.displacementPower=.1,this.displacementFlowSpeedX=0,this.displacementFlowSpeedY=0,this.alpha=1,this.useFlatMode=!1,this.usePreMultiply=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial;var n={callback:function(){this._searchProgram("RedEnvironmentMaterialProgram",i)}};RedDefinePropertyInfo.definePrototypes("RedEnvironmentMaterial",["alpha","number",{min:0,max:1}],["diffuseTexture","sampler2D",n],["environmentTexture","samplerCube",{essential:!0,callback:n.callback}],["normalTexture","sampler2D",n],["specularTexture","sampler2D",n],["displacementTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["normalPower","number",{min:0}],["shininess","number",{min:0}],["specularPower","number",{min:0}],["emissiveFactor","number",{min:0}],["reflectionPower","number",{min:0}],["displacementPower","number",{min:0}],["displacementFlowSpeedX","number"],["displacementFlowSpeedY","number"],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedEnvironmentMaterial)}(),function(){var e,t,r,i=["usePreMultiply"];e=function(){ /* @preserve //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# @@ -439,7 +439,7 @@ if(finalColor.a ==0.0) discard; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/};var n={callback:function(){this._searchProgram("RedSheetMaterialProgram",i)}};(RedSheetMaterial=function(n,a,o,s,d,u){if(!(this instanceof RedSheetMaterial))return new RedSheetMaterial(n,a,o,s,d,u);n instanceof RedGL||RedGLUtil.throwFunc("RedSheetMaterial : RedGL Instance만 허용.",n),o=o||60,s=s||1,d=d||1,u=u||1,this.makeProgramList(this,n,"RedSheetMaterialProgram",e,t,i),this.diffuseTexture=a,this._sheetRect=new Float32Array(4),this.alpha=1,this.usePreMultiply=!1,this._perFrameTime=0,this._nextFrameTime=0,this._playYn=!0,this.segmentW=s,this.segmentH=d,this.totalFrame=u,this.frameRate=o,this.currentIndex=0,this.loop=!0,this._aniMap={},this.__RedSheetMaterialYn=!0,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedSheetMaterial.prototype.addAction=function(e,t){this._aniMap[e]=t},RedSheetMaterial.prototype.setAction=function(e){this.diffuseTexture=this._aniMap[e].texture,this.segmentW=this._aniMap[e].segmentW,this.segmentH=this._aniMap[e].segmentH,this.totalFrame=this._aniMap[e].totalFrame,this.frameRate=this._aniMap[e].frameRate,this.currentIndex=0,this._nextFrameTime=0},RedSheetMaterial.prototype.play=function(){this._playYn=!0},RedSheetMaterial.prototype.stop=function(){this._playYn=!1,this.currentIndex=0},RedSheetMaterial.prototype.pause=function(){this._playYn=!1},RedSheetMaterial.prototype.gotoAndStop=function(e){e>this.totalFrame-1&&(e=this.totalFrame-1),e<0&&(e=0),this._playYn=!1,this.currentIndex=e},RedSheetMaterial.prototype.gotoAndPlay=function(e){e>this.totalFrame-1&&(e=this.totalFrame-1),e<0&&(e=0),this._playYn=!0,this.currentIndex=e,this._nextFrameTime=0},RedDefinePropertyInfo.definePrototypes("RedSheetMaterial",["diffuseTexture","sampler2D",{essential:!0}],["totalFrame","number",{min:1}],["loop","boolean"],["frameRate","number",{min:1,callback:function(){this._perFrameTime=1e3/this._frameRate}}],["segmentW","number",{min:1}],["segmentH","number",{min:1}],["alpha","number",{min:0,max:1}],["usePreMultiply","boolean",n]),Object.freeze(RedSheetMaterial)}(),function(){var e,t,r,i=["diffuseTexture","normalTexture","specularTexture","emissiveTexture","displacementTexture","useFlatMode","usePreMultiply"];e=function(){ +*/};var n={callback:function(){this._searchProgram("RedSheetMaterialProgram",i)}};(RedSheetMaterial=function(n,a,o,s,d,l){if(!(this instanceof RedSheetMaterial))return new RedSheetMaterial(n,a,o,s,d,l);n instanceof RedGL||RedGLUtil.throwFunc("RedSheetMaterial : RedGL Instance만 허용.",n),o=o||60,s=s||1,d=d||1,l=l||1,this.makeProgramList(this,n,"RedSheetMaterialProgram",e,t,i),this.diffuseTexture=a,this._sheetRect=new Float32Array(4),this.alpha=1,this.usePreMultiply=!1,this._perFrameTime=0,this._nextFrameTime=0,this._playYn=!0,this.segmentW=s,this.segmentH=d,this.totalFrame=l,this.frameRate=o,this.currentIndex=0,this.loop=!0,this._aniMap={},this.__RedSheetMaterialYn=!0,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedSheetMaterial.prototype.addAction=function(e,t){this._aniMap[e]=t},RedSheetMaterial.prototype.setAction=function(e){this.diffuseTexture=this._aniMap[e].texture,this.segmentW=this._aniMap[e].segmentW,this.segmentH=this._aniMap[e].segmentH,this.totalFrame=this._aniMap[e].totalFrame,this.frameRate=this._aniMap[e].frameRate,this.currentIndex=0,this._nextFrameTime=0},RedSheetMaterial.prototype.play=function(){this._playYn=!0},RedSheetMaterial.prototype.stop=function(){this._playYn=!1,this.currentIndex=0},RedSheetMaterial.prototype.pause=function(){this._playYn=!1},RedSheetMaterial.prototype.gotoAndStop=function(e){e>this.totalFrame-1&&(e=this.totalFrame-1),e<0&&(e=0),this._playYn=!1,this.currentIndex=e},RedSheetMaterial.prototype.gotoAndPlay=function(e){e>this.totalFrame-1&&(e=this.totalFrame-1),e<0&&(e=0),this._playYn=!0,this.currentIndex=e,this._nextFrameTime=0},RedDefinePropertyInfo.definePrototypes("RedSheetMaterial",["diffuseTexture","sampler2D",{essential:!0}],["totalFrame","number",{min:1}],["loop","boolean"],["frameRate","number",{min:1,callback:function(){this._perFrameTime=1e3/this._frameRate}}],["segmentW","number",{min:1}],["segmentH","number",{min:1}],["alpha","number",{min:0,max:1}],["usePreMultiply","boolean",n]),Object.freeze(RedSheetMaterial)}(),function(){var e,t,r,i=["diffuseTexture","normalTexture","specularTexture","emissiveTexture","displacementTexture","useFlatMode","usePreMultiply"];e=function(){ /* @preserve //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# @@ -532,7 +532,7 @@ finalColor.a = texelColor.a * u_alpha; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/};var n={callback:function(){this._searchProgram("RedStandardMaterialProgram",i)}};(RedStandardMaterial=function(n,a,o,s,d,u){if(!(this instanceof RedStandardMaterial))return new RedStandardMaterial(n,a,o,s,d,u);n instanceof RedGL||RedGLUtil.throwFunc("RedStandardMaterial : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedStandardMaterialProgram",e,t,i),this.diffuseTexture=a,this.normalTexture=o,this.specularTexture=s,this.emissiveTexture=u,this.displacementTexture=d,this.normalPower=1,this.shininess=16,this.specularPower=1,this.emissiveFactor=1,this.displacementPower=.1,this.displacementFlowSpeedX=0,this.displacementFlowSpeedY=0,this.alpha=1,this._UUID=RedGL.makeUUID(),this.useFlatMode=!1,this.usePreMultiply=!1,r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedDefinePropertyInfo.definePrototypes("RedStandardMaterial",["alpha","number",{min:0,max:1}],["diffuseTexture","sampler2D",{essential:!0,callback:n.callback}],["normalTexture","sampler2D",n],["specularTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["displacementTexture","sampler2D",n],["normalPower","number",{min:0}],["shininess","number",{min:0}],["specularPower","number",{min:0}],["emissiveFactor","number",{min:0}],["displacementPower","number",{min:0}],["displacementFlowSpeedX","number"],["displacementFlowSpeedY","number"],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedStandardMaterial)}(),function(){var e,t,r;e=function(){ +*/};var n={callback:function(){this._searchProgram("RedStandardMaterialProgram",i)}};(RedStandardMaterial=function(n,a,o,s,d,l){if(!(this instanceof RedStandardMaterial))return new RedStandardMaterial(n,a,o,s,d,l);n instanceof RedGL||RedGLUtil.throwFunc("RedStandardMaterial : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedStandardMaterialProgram",e,t,i),this.diffuseTexture=a,this.normalTexture=o,this.specularTexture=s,this.emissiveTexture=l,this.displacementTexture=d,this.normalPower=1,this.shininess=16,this.specularPower=1,this.emissiveFactor=1,this.displacementPower=.1,this.displacementFlowSpeedX=0,this.displacementFlowSpeedY=0,this.alpha=1,this._UUID=RedGL.makeUUID(),this.useFlatMode=!1,this.usePreMultiply=!1,r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedDefinePropertyInfo.definePrototypes("RedStandardMaterial",["alpha","number",{min:0,max:1}],["diffuseTexture","sampler2D",{essential:!0,callback:n.callback}],["normalTexture","sampler2D",n],["specularTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["displacementTexture","sampler2D",n],["normalPower","number",{min:0}],["shininess","number",{min:0}],["specularPower","number",{min:0}],["emissiveFactor","number",{min:0}],["displacementPower","number",{min:0}],["displacementFlowSpeedX","number"],["displacementFlowSpeedY","number"],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedStandardMaterial)}(),function(){var e,t,r;e=function(){ /* @preserve //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# @@ -695,7 +695,7 @@ finalColor.a = texelColor.a * u_alpha ; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/},(RedPBRMaterial=function(n,a,o,s,d,u,c){if(!(this instanceof RedPBRMaterial))return new RedPBRMaterial(n,a,o,s,d,u,c);n instanceof RedGL||RedGLUtil.throwFunc("RedPBRMaterial : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedPBRMaterialProgram",e,t,i),this.diffuseTexture=a,this.environmentTexture=o,this.normalTexture=s,this.occlusionTexture=d,this.emissiveTexture=u,this.roughnessTexture=c,this.normalPower=1,this.specularPower=1,this.occlusionPower=1,this.metallicFactor=1,this.roughnessFactor=.1,this.baseColorFactor=[1,1,1,1],this.emissiveFactor=1,this.alpha=1,this.cutOff=0,this.useFlatMode=!1,this.usePreMultiply=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial;var n={callback:function(){this._searchProgram("RedPBRMaterialProgram",i)}};RedDefinePropertyInfo.definePrototypes("RedPBRMaterial",["alpha","number",{min:0,max:1}],["cutOff","number",{min:0,max:1}],["diffuseTexture","sampler2D",n],["environmentTexture","samplerCube",{callback:n.callback}],["normalTexture","sampler2D",n],["occlusionTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["roughnessTexture","sampler2D",n],["normalPower","number",{min:0}],["specularPower","number",{min:0}],["metallicFactor","number",{min:0,max:1}],["emissiveFactor","number",{min:0,max:1}],["roughnessFactor","number",{min:0,max:1}],["occlusionPower","number",{min:0}],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedPBRMaterial)}(),function(){var e,t,r;e=function(){ +*/},(RedPBRMaterial=function(n,a,o,s,d,l,u){if(!(this instanceof RedPBRMaterial))return new RedPBRMaterial(n,a,o,s,d,l,u);n instanceof RedGL||RedGLUtil.throwFunc("RedPBRMaterial : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedPBRMaterialProgram",e,t,i),this.diffuseTexture=a,this.environmentTexture=o,this.normalTexture=s,this.occlusionTexture=d,this.emissiveTexture=l,this.roughnessTexture=u,this.normalPower=1,this.specularPower=1,this.occlusionPower=1,this.metallicFactor=1,this.roughnessFactor=.1,this.baseColorFactor=[1,1,1,1],this.emissiveFactor=1,this.alpha=1,this.cutOff=0,this.useFlatMode=!1,this.usePreMultiply=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial;var n={callback:function(){this._searchProgram("RedPBRMaterialProgram",i)}};RedDefinePropertyInfo.definePrototypes("RedPBRMaterial",["alpha","number",{min:0,max:1}],["cutOff","number",{min:0,max:1}],["diffuseTexture","sampler2D",n],["environmentTexture","samplerCube",{callback:n.callback}],["normalTexture","sampler2D",n],["occlusionTexture","sampler2D",n],["emissiveTexture","sampler2D",n],["roughnessTexture","sampler2D",n],["normalPower","number",{min:0}],["specularPower","number",{min:0}],["metallicFactor","number",{min:0,max:1}],["emissiveFactor","number",{min:0,max:1}],["roughnessFactor","number",{min:0,max:1}],["occlusionPower","number",{min:0}],["useFlatMode","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedPBRMaterial)}(),function(){var e,t,r;e=function(){ /* @preserve void main(void) { vVertexColor = aVertexColor; @@ -888,7 +888,7 @@ finalColor.a = texelColor.a * u_alpha ; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/},(RedPBRMaterial_System=function(n,a,o,s,d,u,c){if(!(this instanceof RedPBRMaterial_System))return new RedPBRMaterial_System(n,a,o,s,d,u,c);n instanceof RedGL||RedGLUtil.throwFunc("RedPBRMaterial_System : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedPBRMaterialSystemProgram",RedGLUtil.getStrFromComment(e.toString()),RedGLUtil.getStrFromComment(t.toString()),i),this.diffuseTexture=a,this.environmentTexture=o,this.normalTexture=s,this.occlusionTexture=d,this.emissiveTexture=u,this.roughnessTexture=c,this.normalPower=1,this.specularPower=1,this.metallicFactor=1,this.roughnessFactor=1,this.diffuseTexCoordIndex=0,this.occlusionTexCoordIndex=0,this.emissiveTexCoordIndex=0,this.roughnessTexCoordIndex=0,this.normalTexCoordIndex=0,this.occlusionPower=1,this.baseColorFactor=null,this.emissiveFactor=null,this.alpha=1,this.cutOff=0,this.useMaterialDoubleSide=!1,this.useVertexColor_0=!1,this.useFlatMode=!1,this.useVertexTangent=!1,this.usePreMultiply=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0),this._needSearchProgram=null}).prototype=new RedBaseMaterial;var n={callback:function(){var e=this;cancelAnimationFrame(this._needSearchProgram),this._needSearchProgram=requestAnimationFrame(function(){e._searchProgram("RedPBRMaterialSystemProgram",i),e._needSearchProgram=null})}};RedDefinePropertyInfo.definePrototypes("RedPBRMaterial_System",["alpha","number",{min:0,max:1}],["cutOff","number",{min:0,max:1}],["diffuseTexture","sampler2D",n],["diffuseTexCoordIndex","number"],["environmentTexture","samplerCube",{callback:n.callback}],["normalTexture","sampler2D",n],["normalTexCoordIndex","number"],["occlusionTexture","sampler2D",n],["occlusionTexCoordIndex","number"],["emissiveTexture","sampler2D",n],["emissiveTexCoordIndex","number"],["roughnessTexture","sampler2D",n],["roughnessTexCoordIndex","number"],["normalPower","number",{min:0}],["specularPower","number",{min:0}],["metallicFactor","number",{min:0,max:1}],["roughnessFactor","number",{min:0,max:1}],["occlusionPower","number",{min:0}],["useFlatMode","boolean",n],["useMaterialDoubleSide","boolean",n],["useVertexColor_0","boolean",n],["useVertexTangent","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedPBRMaterial_System)}(),function(){var e,t,r,i=[];e=function(){ +*/},(RedPBRMaterial_System=function(n,a,o,s,d,l,u){if(!(this instanceof RedPBRMaterial_System))return new RedPBRMaterial_System(n,a,o,s,d,l,u);n instanceof RedGL||RedGLUtil.throwFunc("RedPBRMaterial_System : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedPBRMaterialSystemProgram",RedGLUtil.getStrFromComment(e.toString()),RedGLUtil.getStrFromComment(t.toString()),i),this.diffuseTexture=a,this.environmentTexture=o,this.normalTexture=s,this.occlusionTexture=d,this.emissiveTexture=l,this.roughnessTexture=u,this.normalPower=1,this.specularPower=1,this.metallicFactor=1,this.roughnessFactor=1,this.diffuseTexCoordIndex=0,this.occlusionTexCoordIndex=0,this.emissiveTexCoordIndex=0,this.roughnessTexCoordIndex=0,this.normalTexCoordIndex=0,this.occlusionPower=1,this.baseColorFactor=null,this.emissiveFactor=null,this.alpha=1,this.cutOff=0,this.useMaterialDoubleSide=!1,this.useVertexColor_0=!1,this.useFlatMode=!1,this.useVertexTangent=!1,this.usePreMultiply=!1,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0),this._needSearchProgram=null}).prototype=new RedBaseMaterial;var n={callback:function(){var e=this;cancelAnimationFrame(this._needSearchProgram),this._needSearchProgram=requestAnimationFrame(function(){e._searchProgram("RedPBRMaterialSystemProgram",i),e._needSearchProgram=null})}};RedDefinePropertyInfo.definePrototypes("RedPBRMaterial_System",["alpha","number",{min:0,max:1}],["cutOff","number",{min:0,max:1}],["diffuseTexture","sampler2D",n],["diffuseTexCoordIndex","number"],["environmentTexture","samplerCube",{callback:n.callback}],["normalTexture","sampler2D",n],["normalTexCoordIndex","number"],["occlusionTexture","sampler2D",n],["occlusionTexCoordIndex","number"],["emissiveTexture","sampler2D",n],["emissiveTexCoordIndex","number"],["roughnessTexture","sampler2D",n],["roughnessTexCoordIndex","number"],["normalPower","number",{min:0}],["specularPower","number",{min:0}],["metallicFactor","number",{min:0,max:1}],["roughnessFactor","number",{min:0,max:1}],["occlusionPower","number",{min:0}],["useFlatMode","boolean",n],["useMaterialDoubleSide","boolean",n],["useVertexColor_0","boolean",n],["useVertexTangent","boolean",n],["usePreMultiply","boolean",n]),Object.freeze(RedPBRMaterial_System)}(),function(){var e,t,r,i=[];e=function(){ /* @preserve //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# uniform float u_width; @@ -939,7 +939,84 @@ if(finalColor.a == 0.0) discard; //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); } -*/},(RedTextMaterial=function(n,a){if(!(this instanceof RedTextMaterial))return new RedTextMaterial(n,a);n instanceof RedGL||RedGLUtil.throwFunc("RedTextMaterial : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedTextMaterialProgram",e,t,i),this.diffuseTexture=a,this.alpha=1,this.width=2,this.height=2,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedDefinePropertyInfo.definePrototypes("RedTextMaterial",["diffuseTexture","sampler2D",{essential:!0}],["alpha","number",{min:0,max:1}],["width","number",{min:2,callback:function(e){this._width=e}}],["height","number",{min:2,callback:function(e){this._height=e}}]),Object.freeze(RedTextMaterial)}(),(RedAmbientLight=function(e,t,r,i){if(!(this instanceof RedAmbientLight))return new RedAmbientLight(e,t,r,i);e instanceof RedGL||RedGLUtil.throwFunc("RedAmbientLight : RedGL Instance만 허용.","입력값 : "+e),this._lightColor=new Float32Array(4),this.intensity=null==i?1:i,this.alpha=null==r?.1:r,this.color=t||"#fff",this._UUID=RedGL.makeUUID()}).TYPE="RedAmbientLight",RedAmbientLight.prototype=new RedBaseLight,Object.defineProperty(RedAmbientLight.prototype,"TYPE",{configurable:!1,writable:!1,value:RedAmbientLight.TYPE}),Object.freeze(RedAmbientLight),(RedDirectionalLight=function(e,t,r,i){if(!(this instanceof RedDirectionalLight))return new RedDirectionalLight(e,t,r,i);e instanceof RedGL||RedGLUtil.throwFunc("RedDirectionalLight : RedGL Instance만 허용.","입력값 : "+e),this._lightColor=new Float32Array(4),this.intensity=null==i?1:i,this.alpha=null==r?1:r,this.color=t||"#fff",this.x=0,this.y=-1,this.z=0,this._UUID=RedGL.makeUUID(),this.debug=!1,this._debugObject=RedSprite3D(e,RedBitmapMaterial(e,RedBitmapTexture(e,"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA25pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDozQjcyMEREMTUyMDYxMUU4OTRDNTgzQTBBMEY2MkFFNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDODA1NTI0RjUyMDYxMUU4QkVBQTg3NjZCN0M1OUI2OCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDODA1NTI0RTUyMDYxMUU4QkVBQTg3NjZCN0M1OUI2OCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNyAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowNmFjYmZjZi05YjBkLThlNGItODZiNy1kNWViYWNjZDg4OGMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6M0I3MjBERDE1MjA2MTFFODk0QzU4M0EwQTBGNjJBRTQiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4vVcpuAAAHNUlEQVR42uxbeWyURRT/tiw9OAJYUekfeBCFNmqlkAgRtURQaTywWIhGSfDAAzmkggcoKopKRQXFKKZqNGmkqGAkGEQFhaQenGrAI3iUpKilaiPSytKt74XfF6evM/vN7n67+xn6kl/Sb3bmvTdvZt68eTMNtbe3O8cyhboM0GWALgN0LKkJpUv2lYQFBFbgYcI7aZF6bcf+ZmXI8L0IlYShhBLCbELPTCiSKQOcTRimfA8nFP/fDTCEMJrQw2bpEVqV71ZLXXpARmHQDDCZ8DnhI8IrFkZoI0SVb/77iEXnX4WMzyAzEAbIJSwk9Mb3RMKMFMzWmYQK/N0bMnODYAB2q42i7B5CkY+dZ153i7JGyM64Af4hVIk13cdjFoQsy1yaAZ6qz6iC7ED4gJWEjaLsRkKpoX53MX1zUaajUvBSaSNkBmoXuI/QonyHCXMIeZq6PxJ+Vb5/I/ykqZcHHmGljGXcG8RtcCfhRVFWpjgulfahEzvQjn1GvaZeBXio9AJhV1ADoUcITaJsmKHuKvxWgr91NFx8N0FG2gOhbpb1WMGbxXRd6SE/lg61wrneRPjdT51tDkOTELe3YvrVWPC9CnH+h4SPlfKLCKMQChco/oEN1UD4krAF7Vy6EO14uay2kH0N4XZCDmFJpwEQhyEvAwxF1OV66MOEd8G4znIkuJNTCNcjhO3jUb+ZsIfwOqLKFks5IzFQlxOyURYhnAvjJXQa7Cu2J2Y8gbCBsJhwskf7SzCizxJGWHTejSFGoM0W8IhFA6HLBuiWLbbbvsn4gJ2GKd8T29NWeGodHx6NdXByWQn6pxLwqDT8XgEd5hiO0zXog5HCHkr8QbiO8AMOHwPF78fDUZWL9cmeep6B527CNsK3hAMKn8HYFYo0HX2S0I8wXyRUag0y6nFwWuBl5bDFSPCiuR/WvItwg6bO+YoB7jR0fjthBXxIg0FWAdbwVIy+SvOwyzytyNTRyzDYnlSlxEYh6hunePCLsV75t82aNrx7PCiiv1h0IurfajC2K+t9ZSd5j7AIv1mnxBLNCXJK61KMEiuxCdvOds0U5o48lGCcsgDt5RIqwUGoFMbfAQMcjDcn6GdSlPfe5aJsKWFWksHaM8gFqDSN8HxC3FKUFM3CulXpa2xPydJi8FJpql+6+2WACwiDNCPX4APvBvBSaRBkBsYAY+AXXOItbo2PZ5Y14Kn6oDF+MA7HyPMVI5I6IrI2XPY9Yb9SfpZoX6c5FSZDTeA5OIZM3jnOgL7t4lDUhiN0i40BLkNkVYjGUc0pqxGxQS1m0QBR5xvHf5I8B0A268eJWL5d6q/RNwSD7EYaba2XAZZrIj5J/bA9rYbFszUj5jdJntnoWHfoMtjCT50iDZCpm6HAkG4GTMMSKFKmjzRaI6wewfdhUSc/BbpKnoehXwS6LMQSaNPo24bQuMrGAGuRkChWHIi6nrjNd0pYGxUOkWlICgwgee5X1nstQvDTYZB20ccInGCr7S7A3vLTOJT7inCFSE7k++gL8sFTypQG2Z+pOOADEYezQxrv4+iPF07uIGQGJhD6hLBXlM3C8TZZKtCcJ/ZCZmAMEMVZX6UzCXN94D0XvFRaodnv02qAXkhHLXL+u/6qRrCh0kybrIzHcXim5jhcjb9LocPVIhS3pmM+IRLPDCiE5TcrnXegQDn+ZuGzNW25I5zcvMXDLxSgzjpD52crHSx3Ot47joNu1U4cL0hsZkAIcfbkGCFyKpOiLj3qdEyK8uXL24a65qRonBkhjvmf42YGQQeQCXpL45QqkcxI1tFG4QiXaPzXBJxd+hvaciL3DudodjuhJXCOofN/I6zky8tVBo/MCvPN7vYEPXYUbcs0nXd/XwUdqqBTp/FGHxLeBf5EGOkSJyLfJIzFqPzs0X49nNV0RJbNFh1vRt3paLveo349dBmLmaieSyLoQ1I+QL0c5UTkGxad4PVZgmjNj8vRMfAbNlkmvhy9DUmdpC9H1ZliO41V59SKkTFtTe4Vdpvh9/NgxFyFt22qrZuWb4LboG3n+dDykkitTfTgG4v3JKfjW6LqOI7abekMhV2ar1Fwq6FuBZzcNkf/jEbX9jixFSZNfl6McP6gTgQn6xCmymQkxxP80us05XDDT2D3iXp5cLpl4qg+0kn0nVAKX4s/Jjp/BNuT7oED5+ZOEKHvqYa8RJXTMTOdB1m+kF8GmIQRdMR63WSoH3E6P5aOGOpuUg4/Lo2GzEAYIAc5xFyxly+L0abdssylZSKGyIXMnCAYIKQJRZ/QHI2TIeb1uCjr74f+fhiApy9fkvyFbw5Plzr+E88C90UIy3rAsX9AZaSwT8q9RviCcJJz9FXZIQu5WWIgvN71Mc8pyC384li+AEmXARwoZKtU1On8WNrm6fshp/Oj7EDsAvHSLhHkbMM5IO0UzpAB+Oj6FPJ4IRxaDmZCka5/nOwyQJcBjm0D/CvAAF/S81D+EWScAAAAAElFTkSuQmCC")))}).TYPE="RedDirectionalLight",RedDirectionalLight.prototype=new RedBaseLight,Object.defineProperty(RedDirectionalLight.prototype,"TYPE",{configurable:!1,writable:!1,value:RedDirectionalLight.TYPE}),Object.freeze(RedDirectionalLight),(RedPointLight=function(e,t,r,i,n){if(!(this instanceof RedPointLight))return new RedPointLight(e,t,r,i,n);e instanceof RedGL||RedGLUtil.throwFunc("RedPointLight : RedGL Instance만 허용.","입력값 : "+e),this._lightColor=new Float32Array(4),this.intensity=null==n?1:n,this.alpha=null==r?1:r,this.radius=null==i?1:i,this.color=t||"#fff",this.x=0,this.y=0,this.z=0,this.radius=1,this.debug=!1,this._debugObject=RedMesh(e,RedSphere(e,1,16,16,16),RedColorMaterial(e)),this._debugObject.drawMode=e.gl.LINE_STRIP,this._UUID=RedGL.makeUUID()}).TYPE="RedPointLight",RedPointLight.prototype=new RedBaseLight,Object.defineProperty(RedPointLight.prototype,"TYPE",{configurable:!1,writable:!1,value:RedPointLight.TYPE}),RedDefinePropertyInfo.definePrototype("RedPointLight","radius","number",{min:0}),Object.freeze(RedPointLight),function(){var e,t;t=function(){},RedMTLLoader=function(r,i,n,a){if(!(this instanceof RedMTLLoader))return new RedMTLLoader(r,i,n,a);var o=this,s=new XMLHttpRequest;s.open("GET",i+n,!0),s.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),s.onreadystatechange=function(){if(4==s.readyState){var i;if(o.complete=!0,200==s.status)i=e(o,r,s.responseText),o.parseData=i;else o.parseData=new t;a&&a(o.parseData)}},s.addEventListener("error",function(e){}),s.send(),this.path=i,this.fileName=n,this.complete=!1,this.parseData=null},e=function(e,r,i){var n,a,o,s,d,u,c,l,f,h,R,m,p,_;for(var g in n={},o=/^(newmtl )/,s=/^(Ns )/,d=/^(Ka )/,u=/^(Kd )/,c=/^(Ks )/,l=/^(Ni )/,f=/^(d )/,h=/^(illum )/,R=/^(map_Kd )/,/^(map_Ks )/,m=/^(map_Ns )/,p=/^(map_bump )/,(i=i.replace(/^\#[\s\S]+?\n/g,"")).split("\n").forEach(function(t){var r;o.test(t)?(r=t.replace("newmtl ","").trim(),_={name:r},n[r]=_):d.test(t)?_.Ka=t.replace("Ka ","").split(" "):u.test(t)?_.Kd=t.replace("Kd ","").split(" "):c.test(t)?_.Ks=t.replace("Ks ","").split(" "):s.test(t)?_.Ns=+t.replace("Ns ",""):l.test(t)?_.Ni=+t.replace("Ni ",""):f.test(t)?_.d=+t.replace("d ",""):h.test(t)?(_.illum=+t.replace("illum ",""),_.illum):R.test(t)?_.map_Kd=e.path+t.replace("map_Kd ",""):m.test(t)?_.map_Ns=e.path+t.replace("map_Ns ",""):p.test(t)&&(_.map_bump=e.path+t.replace("map_bump ","").split(" ")[2])}),a=new t,n)a[g]=n[g];return a},Object.freeze(RedMTLLoader)}(),function(){var e,t,r,i,n,a,o,s,d,u,c,l,f,h,R;RedOBJLoader=function(t,r,i,n){if(!(this instanceof RedOBJLoader))return new RedOBJLoader(t,r,i,n);var a=this,o=new XMLHttpRequest;o.open("GET",r+i,!0),o.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),o.onreadystatechange=function(){4===o.readyState&&(a.result=e(a,t,o.responseText),a.modelParsingComplete=!0,a.resultMesh=void 0,n&&(a.mtlLoader?a.mtlLoader.complete&&n(a.result):n(a.result)))},o.send(),this.path=r,this.fileName=i,this.mtlLoader=null,this.modelParsingComplete=!1,this.callback=n,this.resultMesh=RedMesh(t),this.resultMesh.name="instanceOfRedOBJLoader_"+RedGL.makeUUID(),this.result=null},r=function(e,t,r){var i,n,a,o;for(i in o={},t){var s,d,u,c,l,f;if((a=t[i]).mesh,a.use&&a.resultInterleave.length)f=a.ableLight,(n=r.parseData[a.materialKey])&&(n.map_Kd?(o[n.map_Kd]?d=o[n.map_Kd]:(d=RedBitmapTexture(e,n.map_Kd),o[n.map_Kd]=d),s=f?RedStandardMaterial(e,d):RedBitmapMaterial(e,d)):n.Kd&&(u=255*n.Kd[0],c=255*n.Kd[1],l=255*n.Kd[2],s=f?RedColorPhongTextureMaterial(e,RedGLUtil.rgb2hex(u,c,l)):a.ableNormal?RedColorPhongMaterial(e,RedGLUtil.rgb2hex(u,c,l)):RedColorMaterial(e,RedGLUtil.rgb2hex(u,c,l))),s&&(n.map_Ns&&(o[n.map_Ns]?d=o[n.map_Ns]:(d=RedBitmapTexture(e,n.map_Ns),o[n.map_Ns]=d),s.specularTexture=d),n.map_bump&&(o[n.map_bump]?d=o[n.map_bump]:(d=RedBitmapTexture(e,n.map_bump),o[n.map_bump]=d),s.normalTexture=d),void 0!==n.Ns&&(s.shininess=n.Ns),a.mesh.material=s))}},t=function(e,r,i){for(var n in i){var a,o;if((a=i[n]).use){var s,d,u,c=[];a.resultPosition.length&&c.push(RedInterleaveInfo("aVertexPosition",3)),a.resultNormal.length&&c.push(RedInterleaveInfo("aVertexNormal",3)),a.resultUV.length&&c.push(RedInterleaveInfo("aTexcoord",2)),s=RedBuffer(e,n+"_interleave",RedBuffer.ARRAY_BUFFER,new Float32Array(a.resultInterleave.length?a.resultInterleave:a.resultPosition),c),a.index.length&&a.index.length&&(d=RedBuffer(e,n+"_index",RedBuffer.ELEMENT_ARRAY_BUFFER,new Uint16Array(a.index))),u=a.resultUV.length&&a.resultNormal.length?RedColorPhongTextureMaterial(e,"#00ff00"):a.resultNormal?RedColorPhongMaterial(e,"#00ff00"):RedColorMaterial(e,"#0000ff"),o=RedMesh(e,RedGeometry(s,d),u),a.ableUV=!!a.resultUV.length,a.ableNormal=!!a.resultNormal.length,a.ableLight=!!(a.ableUV&a.ableNormal)}else o=RedMesh(e);o.name=n,a.mesh=o,r.addChild(o),t(e,o,a.childrenInfo)}},h=/^(mtllib )/,R=/^(usemtl )/,n=/^o /,a=/^g /,o=/v( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/,s=/vn( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/,d=/vt( +[\d|\.|\+|\-|e|E]+)( +[\d|\.|\+|\-|e|E]+)/,u=/f\s+(([\d]{1,}[\s]?){3,})+/,c=/f\s+((([\d]{1,}\/[\d]{1,}[\s]?){3,})+)/,l=/f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/,f=/f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/,i=function(e,t,i){var m,p,_,g,v,E,M,b,L,P;for(_={position:[],normal:[],uv:[],points:[],normalPoints:[],uvPoints:[]},p={},m={},M=i.length;M--;)if(n.test(i[M])){b=!0;break}return b||(P={name:L="objModel"+RedGL.makeUUID(),groupName:L,index:[],position:[],resultPosition:[],resultNormal:[],resultUV:[],resultInterleave:[],use:!0,childrenInfo:{}},p[L]=g=P,m[L]=g,v=L),i.forEach(function(i){if(h.test(i))return E=RedMTLLoader(e,t.path,i.split(" ")[1],function(i){t.mtlLoader=i,t.modelParsingComplete&&t.callback&&(r(e,m,E),t.callback(t.result))}),void(t.mtlLoader=E);var M;if(R.test(i))b=i.split(" ").slice(1).join("").trim(),m[v].materialKey=b;else if(a.test(i))b=i.split(" ").slice(1).join("").trim(),p[v].use=!1,L={name:b,groupName:v,materialKey:b.replace(v+"_",""),index:[],position:g.position,resultPosition:[],resultNormal:[],resultUV:[],resultInterleave:[],use:!0,childrenInfo:{}},m[b]=g=L,p[v].childrenInfo[b]=g;else if(n.test(i)){var b,L;L={name:b=i.split(" ").slice(1).join("").trim(),groupName:b,materialKey:b,index:[],position:[],resultPosition:[],resultNormal:[],resultUV:[],resultInterleave:[],use:!0,childrenInfo:{}},p[b]=g=L,m[b]=g,v=b}if(o.test(i))M=i.split(" "),_.position.push(+M[1],+M[2],+M[3]),g.position.push(+M[1],+M[2],+M[3]),_.points[_.points.length]=[+M[1],+M[2],+M[3]];else if(s.test(i)){var P;P=i.split(" "),_.normal.push(+P[1],+P[2],+P[3]),_.normalPoints[_.normalPoints.length]=[+P[1],+P[2],+P[3]]}else if(d.test(i)){var T;T=i.split(" "),_.uv.push(+T[1],1-T[2]),_.uvPoints[_.uvPoints.length]=[+T[1],1-T[2]]}else if(f.test(i))(w=i.split(" ").slice(1,4)).forEach(function(e){var t,r,i;i=0,e=e.split("/"),U=+e[0]-1,y=+e[2]-1,t=_.points[U],r=_.normalPoints[y],_.position.length&&(i+=3),_.normal.length&&(i+=3),g.index.push(g.resultInterleave.length/i),_.position.length&&(g.resultPosition.push(t[0],t[1],t[2]),g.resultInterleave.push(t[0],t[1],t[2])),_.normal.length&&(g.resultNormal.push(r[0],r[1],r[2]),g.resultInterleave.push(r[0],r[1],r[2]))});else if(l.test(i)){var y;if(4===(w=i.split(" ").slice(1,5)).length){var x=w[3];w[3]=w[0],w[4]=w[2],w[5]=x}w.forEach(function(e){var t,r,i,n;n=0,e=e.split("/"),U=+e[0]-1,I=+e[1]-1,y=+e[2]-1,t=_.points[U],i=_.uvPoints[I],r=_.normalPoints[y],_.position.length&&(n+=3),_.normal.length&&(n+=3),_.uv.length&&(n+=2),g.index.push(g.resultInterleave.length/n),_.position.length&&(g.resultPosition.push(t[0],t[1],t[2]),g.resultInterleave.push(t[0],t[1],t[2])),_.normal.length&&(g.resultNormal.push(r[0],r[1],r[2]),g.resultInterleave.push(r[0],r[1],r[2])),_.uv.length&&(g.resultUV.push(i[0],i[1]),g.resultInterleave.push(i[0],i[1]))})}else if(c.test(i)){var w,I;(w=i.split(" ").slice(1,4)).forEach(function(e){var t,r,i;i=0,e=e.split("/"),U=+e[0]-1,I=+e[1]-1,t=_.points[U],r=_.uvPoints[I],_.position.length&&(i+=3),_.uv.length&&(i+=2),g.index.push(g.resultInterleave.length/i),_.position.length&&(g.resultPosition.push(t[0],t[1],t[2]),g.resultInterleave.push(t[0],t[1],t[2])),_.uv.length&&(g.resultUV.push(r[0],r[1]),g.resultInterleave.push(r[0],r[1]))})}else if(u.test(i)){var U;U=i.split(" "),g.resultInterleave=g.resultPosition=g.position,g.index.push(+U[1]-1,+U[2]-1,+U[3]-1),g.index.push(+U[1]-1,+U[3]-1,+U[4]-1)}}),{info:m,infoHierarchy:p}},e=function(e,r,n){n=n.replace(/^\#[\s\S]+?\n/g,"");var a=i(r,e,n.split("\n"));return t(r,e.resultMesh,a.infoHierarchy),new function(e){for(var t in e)this[t]=e[t]}({fileName:e.fileName,path:e.path,resultMesh:e.resultMesh,parseRawInfo:a.info,parseInfoHierarchy:a.infoHierarchy,parseInfoMaterial:e.mtlLoader})},Object.freeze(RedOBJLoader)}(),function(){var e,t,r,i,n,a,o,s,d,u,c,l,f,h,R,m,p,_,g;Red3DSLoader=function(t,r,i,n){if(!(this instanceof Red3DSLoader))return new Red3DSLoader(t,r,i,n);var a=this,o=new XMLHttpRequest;o.open("GET",r+i,!0),o.responseType="arraybuffer",o.onreadystatechange=function(){4==o.readyState&&200===o.status&&(a.result=e(a,t,o.response),n&&n(a.result))},o.send(),this.redGL=t,this.position=0,this.materials={},this.meshs=[],this.path=r,this.fileName=i,this.callback=n,this.resultMesh=RedMesh(t),this.resultMesh.name="instanceOfRed3DSLoader_"+RedGL.makeUUID(),this.result=null},r=function(e,t){var r={};return r.cur=e.position,r.id=a(e,t),r.size=o(e,t),r.end=r.cur+r.size,r.cur+=6,r},i=function(e,t,i){if(i.cur>=i.end)return 0;e.position=i.cur;try{var n=r(e,t);return i.cur+=n.size,n.id}catch(e){return 0}},n=function(e,t){e.position=t.end},a=function(e,t){var r=t.getUint16(e.position,!0);return e.position+=2,r},o=function(e,t){var r=t.getUint32(e.position,!0);return e.position+=4,r},d=function(e,t){var r=t.getUint8(e.position,!0);return e.position+=1,r},s=function(e,t,r){var i,n,a="";for(i=0;i-1){var l;l=function(e){var t="";return e.map(function(e){t+=String.fromCharCode(e)}),t},n(r+o,function(r){for(var i=null,n=null,a=null,o=null,d=0,u=0,f=null,h=new DataView(r.response,12),R=(l(new Uint8Array(r.response,0,4)),h.getUint32(4,!0),h.getUint32(8,!0),new DataView(r.response,12));d-1&&a.splice(a.indexOf(f),1)},this.playAnimation=function(e){a.push(f={startTime:performance.now(),targetAnimationData:e})}},RedDefinePropertyInfo.definePrototype("RedGLTFLoader","environmentTexture","samplerCube",{callback:function(e){this.parsingResult.materials.forEach(function(t){"environmentTexture"in t&&(t.environmentTexture=e)})}});var a=[];RedGLTFLoader.animationLooper=function(e){for(var t,r,i,n,o,s,d,u,c,l,f,h,R,m,p,_,g,v,E,M,b,L,P,T,y,x,w,I,U,D,B,G,S,A,F,C,O,N,k,Y,X,j,z,V,Z,W,H,q,J,K,Q,$,ee,te,re,ie,ne=a.length;ne--;)for(w=(T=(x=a[ne]).targetAnimationData).length;w--;){for(I=T[w],t=(e-x.startTime)%(1e3*T.maxTime)/1e3,U=I.target,G=I.time,S=I.time,A=G.length,F=0,D=0,r=G[B=G.length-1],i=G[D];Fae){r=G[B=0],i=G[D=A-1],t=ae;break}}if("CUBICSPLINE"==I.interpolation){"NaN"==(y=i-r).toString()&&(y=0);var oe=(t-r)/y;"NaN"==oe.toString()&&(oe=0);var se=oe*oe,de=se*oe,ue=-2*de+3*se,ce=de-se,le=1-ue,fe=ce-se+oe;if(U){var he,Re,me,pe,_e=I.data;switch(I.key){case"rotation":if((P=(E=_e[12*B+4])*E+(M=_e[12*B+5])*M+(b=_e[12*B+6])*b+(L=_e[12*B+7])*L)>0&&(P=1/Math.sqrt(P)),f=E*P,h=M*P,R=b*P,m=L*P,(P=(E=_e[12*D+4])*E+(M=_e[12*D+5])*M+(b=_e[12*D+6])*b+(L=_e[12*D+7])*L)>0&&(P=1/Math.sqrt(P)),n=E*P,o=M*P,s=b*P,d=L*P,(P=(E=_e[12*B+8])*E+(M=_e[12*B+9])*M+(b=_e[12*B+10])*b+(L=_e[12*B+11])*L)>0&&(P=1/Math.sqrt(P)),p=E*P,_=M*P,g=b*P,v=L*P,(P=(E=_e[12*B+0])*E+(M=_e[12*B+1])*M+(b=_e[12*B+2])*b+(L=_e[12*B+3])*L)>0&&(P=1/Math.sqrt(P)),B!=A-1){var ge=[0,0,0],ve=(E=le*(he=f)+fe*(Re=p*y)+ue*(me=n)+ce*(pe=E*P*y))*(Ne=E+E),Ee=E*(ke=(M=le*(he=h)+fe*(Re=_*y)+ue*(me=o)+ce*(pe=M*P*y))+M),Me=E*(Ye=(b=le*(he=R)+fe*(Re=g*y)+ue*(me=s)+ce*(pe=b*P*y))+b),be=M*Ye,Le=(L=le*(he=m)+fe*(Re=v*y)+ue*(me=d)+ce*(pe=L*P*y))*Ne,Pe=L*ke,Te=L*Ye;(Oe=[])[0]=1-((Xe=M*ke)+(je=b*Ye)),Oe[4]=Ee-Te,Oe[8]=Me+Pe,Oe[1]=Ee+Te,Oe[5]=1-(ve+je),Oe[9]=be-Le,Oe[2]=Me-Pe,Oe[6]=be+Le,Oe[10]=1-(ve+Xe),Oe[3]=0,Oe[7]=0,Oe[11]=0,Oe[12]=0,Oe[13]=0,Oe[14]=0,Oe[15]=1;var ye=Oe[0],xe=Oe[4],we=Oe[8],Ie=(Oe[1],Oe[5]),Ue=Oe[9],De=(Oe[2],Oe[6]),Be=Oe[10];ge[1]=Math.asin(Math.max(-1,Math.min(1,we))),Math.abs(we)<.99999?(ge[0]=Math.atan2(-Ue,Be),ge[2]=Math.atan2(-xe,ye)):(ge[0]=Math.atan2(De,Ie),ge[2]=0),ge[0]=-180*ge[0]/Math.PI,ge[1]=-180*ge[1]/Math.PI,ge[2]=-180*ge[2]/Math.PI,U.rotationX=ge[0],U.rotationY=ge[1],U.rotationZ=ge[2]}break;case"translation":n=_e[9*B+3],o=_e[9*B+4],s=_e[9*B+5],f=_e[9*D+3],h=_e[9*D+4],R=_e[9*D+5],p=_e[9*B+6],_=_e[9*B+7],g=_e[9*B+8],u=_e[9*D+0],c=_e[9*D+1],l=_e[9*D+2],B!=A-1&&(he=f,Re=p*y,me=n,pe=u*y,U.x=le*he+fe*Re+ue*me+ce*pe,he=h,Re=_*y,me=o,pe=c*y,U.y=le*he+fe*Re+ue*me+ce*pe,he=R,Re=g*y,me=s,pe=l*y,U.z=le*he+fe*Re+ue*me+ce*pe);break;case"scale":n=_e[9*B+3],o=_e[9*B+4],s=_e[9*B+5],f=_e[9*D+3],h=_e[9*D+4],R=_e[9*D+5],p=_e[9*B+6],_=_e[9*B+7],g=_e[9*B+8],u=_e[9*D+0],c=_e[9*D+1],l=_e[9*D+2],B!=A-1&&(he=f,Re=p*y,me=n,pe=u*y,U.scaleX=le*he+fe*Re+ue*me+ce*pe,he=h,Re=_*y,me=o,pe=c*y,U.scaleY=le*he+fe*Re+ue*me+ce*pe,he=R,Re=g*y,me=s,pe=l*y,U.scaleZ=le*he+fe*Re+ue*me+ce*pe);break;case"weights":for(C=I.targets.length;C--;){for(N=(O=I.targets[C]).geometry.interleaveBuffer.data,k=O._morphInfo.origin,Y=O.geometry.interleaveBuffer.stride,j=N.length/Y,K=O._morphInfo.list.length,S=I.data,(Q=O._morphInfo.list).cacheData||(Q.cacheData={}),X=0;X0&&(P=1/Math.sqrt(P)),f=E*P,h=M*P,R=b*P,m=L*P,(P=(E=_e[4*D])*E+(M=_e[4*D+1])*M+(b=_e[4*D+2])*b+(L=_e[4*D+3])*L)>0&&(P=1/Math.sqrt(P)),(Se=f*(n=E*P)+h*(o=M*P)+R*(s=b*P)+m*(d=L*P))<0&&(Se=-Se,n=-n,o=-o,s=-s,d=-d),1-Se>glMatrix.EPSILON?(Ge=Math.acos(Se),Ae=Math.sin(Ge),Fe=Math.sin((1-y)*Ge)/Ae,Ce=Math.sin(y*Ge)/Ae):(Fe=1-y,Ce=y);var Oe,Ne,ke,Ye,Xe,je;ge=[0,0,0],ve=(E=Fe*f+Ce*n)*(Ne=E+E),Ee=E*(ke=(M=Fe*h+Ce*o)+M),Me=E*(Ye=(b=Fe*R+Ce*s)+b),be=M*Ye,Le=(L=Fe*m+Ce*d)*Ne,Pe=L*ke,Te=L*Ye;(Oe=[])[0]=1-((Xe=M*ke)+(je=b*Ye)),Oe[4]=Ee-Te,Oe[8]=Me+Pe,Oe[1]=Ee+Te,Oe[5]=1-(ve+je),Oe[9]=be-Le,Oe[2]=Me-Pe,Oe[6]=be+Le,Oe[10]=1-(ve+Xe),Oe[3]=0,Oe[7]=0,Oe[11]=0,Oe[12]=0,Oe[13]=0,Oe[14]=0,Oe[15]=1;ye=Oe[0],xe=Oe[4],we=Oe[8],Oe[1],Ie=Oe[5],Ue=Oe[9],Oe[2],De=Oe[6],Be=Oe[10];ge[1]=Math.asin(Math.max(-1,Math.min(1,we))),Math.abs(we)<.99999?(ge[0]=Math.atan2(-Ue,Be),ge[2]=Math.atan2(-xe,ye)):(ge[0]=Math.atan2(De,Ie),ge[2]=0),ge[0]=-180*ge[0]/Math.PI,ge[1]=-180*ge[1]/Math.PI,ge[2]=-180*ge[2]/Math.PI,U.rotationX=ge[0],U.rotationY=ge[1],U.rotationZ=ge[2];break;case"translation":n=_e[3*D],o=_e[3*D+1],s=_e[3*D+2],f=_e[3*B],h=_e[3*B+1],R=_e[3*B+2],U.x=f+y*(n-f),U.y=h+y*(o-h),U.z=R+y*(s-R);break;case"scale":n=_e[3*D],o=_e[3*D+1],s=_e[3*D+2],f=_e[3*B],h=_e[3*B+1],R=_e[3*B+2],U.scaleX=f+y*(n-f),U.scaleY=h+y*(o-h),U.scaleZ=R+y*(s-R);break;case"weights":for(C=I.targets.length;C--;){var ze;for(N=(O=I.targets[C]).geometry.interleaveBuffer.data,k=O._morphInfo.origin,Y=O.geometry.interleaveBuffer.stride,j=N.length/Y,K=O._morphInfo.list.length,S=I.data,(Q=O._morphInfo.list).cacheData||(Q.cacheData={}),X=0;X-1?t.images[r].uri:(t.images[r].uri.indexOf(";base64,")>-1?"":e.path)+t.images[r].uri},v=function(e,t,r){var i={};if(t.samplers){var n=t.samplers[r];"magFilter"in n&&(i.mag=n.magFilter),"minFilter"in n&&(i.min=n.minFilter),"wrapS"in n&&(i.wrap_s=n.wrapS),"wrapT"in n&&(i.wrap_t=n.wrapT)}return i.string=JSON.stringify(i),i},function(e,t,r){var i,n,a=!1,o=.5;if("material"in r){var s,d,u,c,l,f=r.material,h=t.materials[f];if("doubleSided"in h&&(a=!!h.doubleSided),"alphaMode"in h&&(n=h.alphaMode),"alphaCutoff"in h&&(o=h.alphaCutoff),"baseColorTexture"in h.pbrMetallicRoughness){var R=h.pbrMetallicRoughness.baseColorTexture.index,m=t.textures[R],p=m.source,_=g(e,t,p),E=m.sampler,M=_+(S=v(0,t,E)).string;s=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,S)}if("metallicRoughnessTexture"in h.pbrMetallicRoughness){var b=h.pbrMetallicRoughness.metallicRoughnessTexture.index,L=t.textures[b],P=L.source;_=g(e,t,P),E=L.sampler,M=_+(S=v(0,t,E)).string,u=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,S)}var T=h.normalTexture;if(null!=T){T=T.index;var y=t.textures[T],x=y.source;_=g(e,t,x),E=y.sampler,M=_+(S=v(0,t,E)).string,d=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,S)}var w=h.emissiveTexture;if(null!=w){w=w.index;var I=t.textures[w],U=I.source;_=g(e,t,U),E=I.sampler,M=_+(S=v(0,t,E)).string,c=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,S)}var D,B,G=h.occlusionTexture;if(null!=G){G=G.index;var S,A=t.textures[G],F=A.source;_=g(e,t,F),E=A.sampler,M=_+(S=v(0,t,E)).string,l=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,S)}"metallicFactor"in h.pbrMetallicRoughness&&(D=h.pbrMetallicRoughness.metallicFactor),"roughnessFactor"in h.pbrMetallicRoughness&&(B=h.pbrMetallicRoughness.roughnessFactor);var C=e.environmentTexture;i=RedPBRMaterial_System(e.redGL,s,C,d,l,c,u,null),O=h.pbrMetallicRoughness&&h.pbrMetallicRoughness.baseColorFactor?h.pbrMetallicRoughness.baseColorFactor:[1,1,1,1],i.baseColorFactor=new Float32Array(O),h.pbrMetallicRoughness&&(i.metallicFactor=null!=D?D:1,i.roughnessFactor=null!=B?B:1),i.emissiveFactor=null!=h.emissiveFactor?h.emissiveFactor:new Float32Array([1,1,1]),h.pbrMetallicRoughness&&(h.pbrMetallicRoughness.metallicRoughnessTexture&&(i.roughnessTexCoordIndex=h.pbrMetallicRoughness.metallicRoughnessTexture.texCoord||0),h.pbrMetallicRoughness.baseColorTexture&&(i.diffuseTexCoordIndex=h.pbrMetallicRoughness.baseColorTexture.texCoord||0)),h.occlusionTexture&&(i.occlusionTexCoordIndex=h.occlusionTexture.texCoord||0,i.occlusionPower=h.occlusionTexture.strength||1),h.emissiveTexture&&(i.emissiveTexCoordIndex=h.emissiveTexture.texCoord||0),h.normalTexture&&(i.normalTexCoordIndex=h.normalTexture.texCoord||0)}else{var O=[Math.random(),Math.random(),Math.random(),1];(i=RedPBRMaterial_System(e.redGL)).baseColorFactor=new Float32Array(O)}return[i,a,n,o]}),y=function(e,t,r,i,n,a,o,s,d){for(var u=0,c=t.length/3,l=0;u-1&&e.parsingOption[A](c);switch(c.drawMode=f||e.redGL.gl.TRIANGLES,n&&(c.useCullFace=!1,l.useMaterialDoubleSide=!0),a){case"BLEND":c.useTransparentSort=!0;break;case"MASK":c.useBlendMode=!1,l.cutOff=o;break;default:c.useBlendMode=!1,l._cutOff=-.1}p.length&&(l.useVertexColor_0=!0),w.length&&(l.useVertexTangent=!0);var F=new P(e,t,d,r.weights);F.list.forEach(function(e){var t;t=e.normals.length?e.normals:RedGLUtil.calculateNormals(e.vertices,R);var r=[];y(r,e.vertices,e.verticesColor_0,t,e.uvs,e.uvs1,e.jointWeights,e.joints,e.tangents),e.interleaveData=r}),c._morphInfo=F,c._morphInfo.origin=new Float32Array(G);var C=c.geometry.interleaveBuffer.data,O=0;S.forEach(function(e){O+=e.size});c._morphInfo.list.forEach(function(e,t){for(var r=0,i=C.length/O,n=null==c._morphInfo.list.weights[t]?.5:c._morphInfo.list.weights[t];rf.time[0]&&(s.minTime=f.time[0]),s.maxTime0){var e=parseFloat(c);if(l.push(e),2===l.length){if(s&&(l[0]+=f[0],l[1]+=f[1]),o.push(l),d&&(h=l.slice()),!--u){if("l"===i){var t=o.pop(),r=o.pop(),n=vec2.lerp([0,0],r,t,.25),a=vec2.lerp([0,0],r,t,.75);o.push(r,n,a,t)}f=h}l=[]}c=""}}var m,p=e.split("");for(n=0,a=p.length;n="0"&&m<="9"||"."===m?c+=m:"-"===m?(R(),c="-"):"m"===m?(R(),d=!0,u=1,s=!0,i="m"):"c"===m?(R(),d=!0,u=3,s=!0,i="c"):"l"===m?(R(),d=!0,u=1,s=!1,i="l"):"M"===m?(R(),d=!0,u=1,s=!1,i="m"):"C"===m?(R(),d=!0,u=3,s=!1,i="c"):"L"===m?(R(),d=!0,u=1,s=!1,i="l"):"Z"===m||(","===m?R():" "===m&&R());R();var _=o[0].slice(),g=o[0].slice();for(n=1,a=o.length;nU&&vec3.add(A,A,t)}),vec3.normalize(A,A);var F=3*B,C=2*B;I.push(w(i[F+0],i[F+1],i[F+2],A[0],A[1],A[2],n[C+0],n[C+1]))}}return{position:T,texcoord:y,normal:x,indices:I}},e=function(e,t,r){var i,n=[],a=r.position,o=r.normal,s=r.texcoord;i=r.indices;for(var d,u=0,c=a.length/3;uc&&(c=h,l=f)}return Math.sqrt(c)>i?(o(e,t,l+1,i,a),o(e,l,r,i,a)):a.push(d,u),a},e=function(e,t){null==t&&(t=1);for(var r,i,n,a,o=e.length,s=o-2,d=0;d1){var u=e(i.points,a);i._serializedPoints=r(u),u=t(i._serializedPoints,s);for(var c=0,l=(u=o(u,0,u.length,d)).length;c1){i._serializedPoints=r(i.points),u=t(i._serializedPoints,s);for(c=0,l=(u=o(u,0,u.length,d)).length;ch.max&&(u=h.max-d);u--;)m=this.list[d+u]=new RedParticleUnit(h.lifeTime),this._interleaveData.push(this.x,this.y,this.z),this._interleaveData.push(0),h.tint==RedParticleEmitter.TINT_RANDOM?this._interleaveData.push(Math.random(),Math.random(),Math.random(),1):this._interleaveData.push(h.tint[0],h.tint[1],h.tint[2],1),h.particle&&(R.movementX&&m.addRule("movementX",R.movementX),R.movementY&&m.addRule("movementY",R.movementY),R.movementZ&&m.addRule("movementZ",R.movementZ),R.scale&&m.addRule("scale",R.scale),R.alpha&&m.addRule("alpha",R.alpha));for(d=this.list.length,_="movementX,movementY,movementZ,scale,alpha".split(",");d--;)if((c=this.list[d]).startTime||(c.startTime=e,c.age=0),c.age=e-c.startTime,f=8*d,(l=c.age/c.lifeTime)<1)for(E=l,c.startCenter||(c.startCenter=[this.x,this.y,this.z]),u=_.length;u--;)E=l,(p=c[g=_[u]].ease)&&(1==p?E*=E*E*E*E:2==p?E=(E-=1)*E*E*E*E+1:3==p?E=(E*=2)<1?E*E*E*E*E*.5:.5*((E-=2)*E*E*E*E+2):4==p?E=E*E*(1.70158*E+E-1.70158):5==p?E=(E-=1)*E*(1.70158*E+E+1.70158)+1:6==p?E=(E*=2)<1?.5*E*E*(1.70158*E+E-1.70158):.5*(E-=2)*E*(1.70158*E+E+1.70158)+1:7==p?E=-1*(n(1-E*E)-1):8==p?E=n(1-(E-=1)*E):9==p?E=(E*=2)<1?-.5*(n(1-E*E)-1):.5*n(1-(E-=2)*E)+.5:10==p?E*=E*E:11==p?E=(E-=1)*E*E+1:12==p?E=(E*=2)<1?E*E*E*.5:.5*((E-=2)*E*E+2):13==p?E=0==E?0:t(2,10*(E-1)):14==p?E=1==E?1:1-t(2,-10*E):15==p?E=(E*=2)<1?0==E?0:.5*t(2,10*(E-1)):2==E?1:-.5*t(2,-10*(E-1))+1:16==p?E*=E:17==p?E*=2-E:18==p?E=(E*=2)<1?E*E*.5:.5*((2-(E-=1))*E+1):19==p?E*=E*E*E:20==p?E=1-(E-=1)*E*E*E:21==p?E=(E*=2)<1?E*E*E*E*.5:1-(E-=2)*E*E*E*.5:22==p?E=1-i(E*s):23==p?E=r(E*s):24==p?E=.5*(1-i(E*a)):25==p?E=0===E?0:1===E?1:-1*t(2,10*(E-=1))*r((E-.075)*o/.3):26==p?E=0===E?0:1===E?1:t(2,-10*E)*r((E-.075)*o/.3)+1:27==p&&(0===E||1===E||(E*=2),E=E<1?-.5*t(2,10*(E-=1))*r((E-.075)*o/.3):.5*t(2,-10*(E-=1))*r((E-.075)*o/.3)+1)),"movementX"==g&&(v=0),"movementY"==g&&(v=1),"movementZ"==g&&(v=2),"scale"==g&&(v=3),"alpha"==g&&(v=7),this._interleaveData[f+v]=v<3?c.startCenter[v]+c[g].start+c[g].gap*E:c[g].start+c[g].gap*E,h.gravity&&(c._gravitySum-=h.gravity),this._interleaveData[f+1]+=c._gravitySum;else this._interleaveData[f+0]=c.startCenter[0]=this.x,this._interleaveData[f+1]=c.startCenter[1]=this.y,this._interleaveData[f+2]=c.startCenter[2]=this.z,this._interleaveData[f+3]=c.scale.start,h.tint==RedParticleEmitter.TINT_RANDOM?(this._interleaveData[f+4]=Math.random(),this._interleaveData[f+5]=Math.random(),this._interleaveData[f+6]=Math.random()):(this._interleaveData[f+4]=h.tint[0],this._interleaveData[f+5]=h.tint[1],this._interleaveData[f+6]=h.tint[2]),this._interleaveData[f+7]=0,c._gravitySum=0,c.startTime=null,c.age=-1;this._geometry.interleaveBuffer.upload(new Float32Array(this._interleaveData))},RedDefinePropertyInfo.definePrototype("RedParticleEmitter","diffuseTexture","sampler2D",{callback:function(e){this.material.diffuseTexture=e}}),Object.freeze(RedParticleEmitter),function(){var e,t,r;r=function(e,r,i,n,a,o,s,d,u,c,l,f){var h,R,m=d/l,p=u/f,_=d/2,g=u/2,v=c/2,E=l+1,M=f+1,b=0,L=[];for(R=0;R0?1:-1,e.push(L.x,L.y,L.z),e.push(h/l,R/f),b+=1}}for(R=0;R0&&t(!0),n>0&&t(!1)),{interleaveData:l,indexData:f,type:r,interleaveBuffer:RedBuffer(e,r+"_interleaveBuffer",RedBuffer.ARRAY_BUFFER,new Float32Array(l),[RedInterleaveInfo("aVertexPosition",3),RedInterleaveInfo("aVertexNormal",3),RedInterleaveInfo("aTexcoord",2)]),indexBuffer:RedBuffer(e,r+"_indexBuffer",RedBuffer.ELEMENT_ARRAY_BUFFER,new Uint16Array(f))}},(RedCylinder=function(t,r,i,n,a,o,s,d,u){return this instanceof RedCylinder?(t instanceof RedGL||RedGLUtil.throwFunc("RedPrimitive : RedGL Instance만 허용.",t),c="RedCylinder_"+(r=void 0!==r?r:1)+"_"+(i=void 0!==i?i:1)+"_"+(n=void 0!==n?n:1)+"_"+(a=Math.floor(a)||8)+"_"+(o=Math.floor(o)||1)+"_"+(s=void 0!==s&&s)+"_"+(d=void 0!==d?d:0)+"_"+(u=void 0!==u?u:2*Math.PI),t._datas.Primitives||(t._datas.Primitives={}),t._datas.Primitives[c]?t._datas.Primitives[c]:(t._datas.Primitives[c]=this,l=e(t,c,r,i,n,a,o,s,d,u),this.interleaveBuffer=l.interleaveBuffer,this.indexBuffer=l.indexBuffer,this.interleaveBuffer.isPrimitiveBuffer=!0,this.indexBuffer.isPrimitiveBuffer=!0,void(this._UUID=RedGL.makeUUID()))):new RedCylinder(t,r,i,n,a,o,s,d,u);var c,l}).prototype=Object.create(RedGeometry.prototype),Object.freeze(RedCylinder)}(),function(){var e,t,r,i,n,a,o,s,d,u,c,l,f,h,R,m,p;e=function(e,_,g,v,E,M,b){t=g/2,r=v/2,i=Math.floor(E)||1,n=Math.floor(M)||1,a=i+1,o=n+1,s=g/i,d=v/n;var L=[],P=[];for(c=0;c0)&&M.push(a,o,d),(i!==m-1||t-1&&RedGLUtil.throwFunc("RedProgram : 프로그램이름에 _ 는 허용하지 않음.","입력값 : "+t),r="string"==typeof r?r:RedGLUtil.getStrFromComment(r.toString()),i="string"==typeof i?i:RedGLUtil.getStrFromComment(i.toString());var o=!1,s=!1,d=!1,u=!1;for(var c in RedSystemShaderCode.vertexShareFunc)a=new RegExp("//#REDGL_DEFINE#vertexShareFunc#"+c+"#","gi"),r=r.replace(a,RedSystemShaderCode.vertexShareFunc[c]);for(var c in RedSystemShaderCode.fragmentShareFunc)a=new RegExp("//#REDGL_DEFINE#fragmentShareFunc#"+c+"#","gi"),i=i.replace(a,RedSystemShaderCode.fragmentShareFunc[c]);if(n){n.sort(),t+="_"+n.join("_");for(var l=n.length;l--;)"fog"===n[l]&&(o=!0),"sprite3D"===n[l]&&(s=!0),"directionalShadow"===n[l]&&(d=!0),"skin"===n[l]&&(u=!0),"fog"!==n[l]&&"sprite3D"!=n[l]&&"directionalShadow"!=n[l]&&"skin"!=n[l]&&(a=new RegExp("//#REDGL_DEFINE#"+n[l]+"#","gi"),r=r.replace(a,""),i=i.replace(a,""))}return a=new RegExp("//#REDGL_DEFINE#fog#"+(o?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),a=new RegExp("//#REDGL_DEFINE#sprite3D#"+(s?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),a=new RegExp("//#REDGL_DEFINE#directionalShadow#"+(d?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),a=new RegExp("//#REDGL_DEFINE#skin#"+(u?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),RedProgram(e,t,r,i,n)},Object.freeze(RedProgram)}(),(RedSystemShaderCode={}).init=function(e){var t,r,i=e.detect;r=parseInt(Math.floor(Math.min((i.vertexShader.MAX_VERTEX_UNIFORM_VECTORS-64)/8,128))),t=parseInt(Math.floor(Math.min((i.fragmentShader.MAX_FRAGMENT_UNIFORM_VECTORS-64)/4,128))),(RedSystemShaderCode={vertexShareDeclare:["attribute vec3 aVertexPosition","attribute vec3 aVertexNormal","attribute vec4 aVertexColor","attribute vec4 aVertexWeight","attribute vec4 aVertexJoint","varying vec4 vVertexPosition","varying vec3 vVertexNormal","varying vec4 vVertexColor","attribute float aPointSize","uniform float uPointSize","attribute vec2 aTexcoord","attribute vec2 aTexcoord1","varying vec2 vTexcoord","varying vec2 vTexcoord1","uniform bool uMode2DYn","uniform float uTime","varying float vTime","uniform vec2 uResolution","varying vec2 vResolution","uniform mat4 uMMatrix","uniform mat4 uNMatrix","uniform mat4 uPMatrix","uniform mat4 uCameraMatrix","uniform bool u_PerspectiveScale","uniform mat4 uDirectionalShadowLightMatrix","varying highp vec4 vShadowPos","const mat4 cTexUnitConverter = mat4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0)","uniform mat4 uJointMatrix["+r+"]","uniform mat4 uInverseBindMatrixForJoint["+r+"]","uniform mat4 uGlobalTransformOfNodeThatTheMeshIsAttachedTo"],fragmentShareDeclare:["varying vec4 vVertexPosition","varying vec3 vVertexNormal","varying vec4 vVertexColor","varying vec2 vTexcoord","varying vec2 vTexcoord1","varying float vTime","varying vec2 vResolution","uniform vec3 uCameraPosition","uniform float u_FogDistance","uniform float u_FogDensity","uniform vec4 uFogColor","const int cDIRETIONAL_MAX = 3","uniform vec3 uDirectionalLightPositionList[3]","uniform vec4 uDirectionalLightColorList[3]","uniform float uDirectionalLightIntensityList[3]","uniform int uDirectionalLightNum","const int cPOINT_MAX = "+t,"uniform vec3 uPointLightPositionList["+t+"]","uniform vec4 uPointLightColorList["+t+"]","uniform float uPointLightRadiusList["+t+"]","uniform float uPointLightIntensityList["+t+"]","uniform int uPointLightNum","uniform vec4 uAmbientLightColor","uniform float uAmbientIntensity","uniform sampler2D uDirectionalShadowTexture","varying highp vec4 vShadowPos"],systemUniform:{},vertexShareFunc:{getSkinMatrix:["//#REDGL_DEFINE#skin#true# mat4 getSkinMatrix(){","//#REDGL_DEFINE#skin#true# mat4 skinMat =","//#REDGL_DEFINE#skin#true# aVertexWeight.x * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.x) ] * uInverseBindMatrixForJoint[int(aVertexJoint.x)]+","//#REDGL_DEFINE#skin#true# aVertexWeight.y * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.y) ] * uInverseBindMatrixForJoint[int(aVertexJoint.y)]+","//#REDGL_DEFINE#skin#true# aVertexWeight.z * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.z) ] * uInverseBindMatrixForJoint[int(aVertexJoint.z)]+","//#REDGL_DEFINE#skin#true# aVertexWeight.w * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.w) ] * uInverseBindMatrixForJoint[int(aVertexJoint.w)];","//#REDGL_DEFINE#skin#true# return skinMat;","//#REDGL_DEFINE#skin#true# }"].join("\n"),getSprite3DMatrix:["mat4 getSprite3DMatrix(mat4 cameraMTX, mat4 mvMatrix){"," mat4 cacheScale = mat4("," mvMatrix[0][0], 0.0, 0.0, 0.0,"," 0.0, mvMatrix[1][1], 0.0, 0.0,"," 0.0, 0.0, 1.0, mvMatrix[2][2],"," 0.0, 0.0, 0.0, 1.0"," );"," mat4 tMTX = cameraMTX * mvMatrix;"," tMTX[0][0] = 1.0, tMTX[0][1] = 0.0, tMTX[0][2] = 0.0,"," tMTX[1][0] = 0.0, tMTX[1][1] = 1.0, tMTX[1][2] = 0.0,"," tMTX[2][0] = 0.0, tMTX[2][1] = 0.0, tMTX[2][2] = 1.0;"," return tMTX * cacheScale;","}"].join("\n")},fragmentShareFunc:{getFlatNormal:["vec3 getFlatNormal(vec3 vertexPosition){"," vec3 dx = dFdx(vVertexPosition.xyz);"," vec3 dy = dFdy(vVertexPosition.xyz);"," return normalize(cross(normalize(dx), normalize(dy)));","}"].join("\n"),getDirectionalLightColor:["vec4 getDirectionalLightColor( vec4 texelColor, vec3 N, float shininess, vec4 specularLightColor, float specularTextureValue, float specularPower) {"," vec3 L;"," float specular;"," float lambertTerm;"," vec4 ld = vec4(0.0, 0.0, 0.0, 1.0);"," vec4 ls = vec4(0.0, 0.0, 0.0, 1.0);"," for(int i=0; i 0.0){"," ld += uDirectionalLightColorList[i] * texelColor * lambertTerm * uDirectionalLightIntensityList[i];"," specular = pow( max(dot(reflect(L, N), -L), 0.0), shininess) * specularPower * specularTextureValue;"," ls += specularLightColor * specular * uDirectionalLightIntensityList[i] * uDirectionalLightColorList[i].a;"," }"," }"," return ld + ls;","}"].join("\n"),getPointLightColor:["vec4 getPointLightColor( vec4 texelColor, vec3 N, float shininess, vec4 specularLightColor, float specularTextureValue, float specularPower) {"," vec3 L;"," float specular;"," float lambertTerm;"," vec4 ld = vec4(0.0, 0.0, 0.0, 1.0);"," vec4 ls = vec4(0.0, 0.0, 0.0, 1.0);"," float distanceLength;"," float attenuation;"," for(int i=0;i distanceLength){"," attenuation = 1.0 / (0.01 + 0.02 * distanceLength + 0.03 * distanceLength * distanceLength) * 0.5;"," L = normalize(L);"," lambertTerm = dot(N,-L);"," if(lambertTerm > 0.0){"," ld += uPointLightColorList[i] * texelColor * lambertTerm * attenuation * uPointLightIntensityList[i] ;"," specular = pow( max(dot( reflect(L, N), -N), 0.0), shininess) * specularPower * specularTextureValue;"," ls += specularLightColor * specular * uPointLightIntensityList[i] * uPointLightColorList[i].a ;"," }"," }"," }"," return ld + ls;","}"].join("\n"),fogFactor:["float fogFactor(float perspectiveFar, float density){"," float flog_cord = gl_FragCoord.z / gl_FragCoord.w / perspectiveFar;"," float fog = flog_cord * density;"," if(1.0 - fog < 0.0) discard;"," return clamp(1.0 - fog, 0.0, 1.0);","}"].join("\n"),fog:["vec4 fog(float fogFactor, vec4 fogColor, vec4 currentColor) {"," return mix(fogColor, currentColor, fogFactor);","}"].join("\n"),decodeFloatShadow:["float decodeFloatShadow (vec4 color) {"," const vec4 cBitShift = vec4("," 1.0 / (256.0 * 256.0 * 256.0),"," 1.0 / (256.0 * 256.0),"," 1.0 / 256.0,"," 1.0"," );"," return dot(color, cBitShift);","}"].join("\n"),getShadowColor:["float getShadowColor ( vec4 shadowPos, vec2 resolution, sampler2D directionalShadowTexture ) {"," vec3 fragmentDepth = shadowPos.xyz;"," fragmentDepth.z -= 0.007; // cShadowAcneRemover"," float amountInLight = 0.0;"," for (int x = -1; x <= 1; x++) {"," for (int y = -1; y <= 1; y++) {"," vec2 tUV = fragmentDepth.xy + vec2( float(x)/resolution.x, float(y)/resolution.y );"," if(tUV.x<0.0) return 1.0;"," if(tUV.x>1.0) return 1.0;"," if(tUV.y<0.0) return 1.0;"," if(tUV.y>1.0) return 1.0;"," float texelDepth = decodeFloatShadow( texture2D(directionalShadowTexture, tUV) );"," if (fragmentDepth.z < texelDepth ) amountInLight += 1.0;"," }"," }"," amountInLight /= 9.0;"," amountInLight = amountInLight;"," return amountInLight;","}"].join("\n"),cotangent_frame:["mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)","{"," vec3 dp1 = dFdx( p );"," vec3 dp2 = dFdy( p );"," vec2 duv1 = dFdx( uv );"," vec2 duv2 = dFdy( uv );"," "," vec3 dp2perp = cross( dp2, N );"," vec3 dp1perp = cross( N, dp1 );"," vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;"," vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;"," "," float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );"," return mat3( T * invmax, B * invmax, N );","}"].join("\n"),perturb_normal:["vec3 perturb_normal( vec3 N, vec3 V, vec2 texcoord, vec3 normalColor )"," {"," "," vec3 map = normalColor;"," map = map * 255./127. - 128./127.;"," map.xy *= u_normalPower;"," mat3 TBN = cotangent_frame(N, V, texcoord);"," return normalize(TBN * map);","}"].join("\n")}}).MAX_DIRECTIONAL_LIGHT=3,RedSystemShaderCode.MAX_POINT_LIGHT=t,RedSystemShaderCode.MAX_JOINT=r,[RedSystemShaderCode.vertexShareDeclare,RedSystemShaderCode.fragmentShareDeclare].forEach(function(e){e.forEach(function(e){"uniform"===(e=e.split(" "))[0]&&(RedSystemShaderCode.systemUniform[e[2]]=1)})});var n=[],a=[],o={bool:4,float:4,int:4,uint:4,sampler2D:4,samplerCube:4,vec2:4,vec3:4,vec4:4,mat2:4,mat3:8,mat4:16};RedSystemShaderCode.vertexShareDeclare.forEach(function(e){var t;"uniform"===(e=e.split(" "))[0]&&(t={value:e,type:e[1],num:e[2].indexOf("[")>-1?+e[2].split("[")[1].replace("]","")*o[e[1]]:o[e[1]]},n.push(t))}),a=[],RedSystemShaderCode.fragmentShareDeclare.forEach(function(e){var t;"uniform"===(e=e.split(" "))[0]&&(t={value:e,type:e[1],num:e[2].indexOf("[")>-1?+e[2].split("[")[1].replace("]","")*o[e[1]]:o[e[1]]},a.push(t))}),Object.freeze(RedSystemShaderCode)},function(){var e,t,r,i,n,a,o,s,d,u;e=function(e,t,r){switch(r){case RedShader.VERTEX:return(n=e.createShader(e.VERTEX_SHADER))||(e.isContextLost()?RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - WebGL 컨텍스트가 손실"):RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - GPU메모리가 부족일 가능성이 큼")),n.key=t,n.type=r,n;case RedShader.FRAGMENT:return(n=e.createShader(e.FRAGMENT_SHADER))||(e.isContextLost()?RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - WebGL 컨텍스트가 손실"):RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - GPU메모리가 부족일 가능성이 큼")),n.key=t,n.type=r,n;default:RedGLUtil.throwFunc("RedShader : 쉐이더 타입을 확인하세요. RedShader.VERTEX or RedShader.FRAGMENT 만 허용")}},t=function(e,t,r,i){e.shaderSource(r,i.lastSource),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)||RedGLUtil.throwFunc("RedShader : 쉐이더 컴파일에 실패하였습니다.\n",e.getShaderInfoLog(r))},i=function(e,t){var r;switch(e){case RedShader.VERTEX:r=RedSystemShaderCode.vertexShareDeclare.concat();break;case RedShader.FRAGMENT:r=RedSystemShaderCode.fragmentShareDeclare.concat();break;default:RedGLUtil.throwFunc("RedShader : 쉐이더 타입을 확인하세요. RedShader.VERTEX or RedShader.FRAGMENT 만 허용")}for(a=t.length;a--;)o=(o=t[a]).replace(";",""),-1===r.indexOf(o)?r.push(o):RedGLUtil.throwFunc("RedShader : ","\n1. 중복 선언 이거나","\n2. RedSystemShaderCode에 정의된 선언\n","입력값 : "+o);return r},r=function(e,t){return t=(t=t.replace(/\s+$/,"")).replace(/ /g,"").trim(),s={etc:""},d=t.match(/attribute[\s\S]+?\;|uniform[\s\S]+?\;|varying[\s\S]+?\;|const[\s\S]+?\;|precision[\s\S]+?\;/g),(d=i(e,d=d||[])).sort(),d.forEach(function(e){var r,i,n,a,o,d,u,c,l;if(e=e.trim(),t=t.replace(e+";",""),("highp"===(r=e.split(" "))[1]||"mediump"===r[1]||"lowp"===r[1])&&(l=r[1],r.splice(1,1),r.push(l),c=l),r[2])switch(i=r[0],a=r[1],n=r[2].replace(";","").split("["),d=(d=e.split("="))[1]?d[1].trim().replace(";",""):null,o=n.length>1?+n[1].split("]")[0]:0,n=n[0],i){case"precision":break;case"attribute":"a"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : attribute의 첫글자는 a로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : attribute의 두번째 글자는 대문자 시작해야합니다.",n,r);break;case"uniform":"u"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : uniform의 첫글자는 u로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : uniform의 두번째 글자는 대문자 시작해야합니다.",n,r);break;case"varying":"v"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : varying의 첫글자는 v로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : varying의 두번째 글자는 대문자 시작해야합니다.",n,r);break;case"const":"c"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : const의 첫글자는 c로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : const의 두번째 글자는 대문자 시작해야합니다.",n,r);break;default:RedGLUtil.throwFunc("RedShader : 체크되지 못하는값인데 뭐냐",n,r)}else RedGLUtil.throwFunc("RedShader : 체크되지 못하는값인데 뭐냐",r);s[i]||(s[i]={},s[i].list=[],s[i].map={},s[i].source=""),u={name:n,arrayNum:o,value:d,precision:c,systemUniformYn:!!RedSystemShaderCode.systemUniform[o?n+"["+o+"]":n]},"uniform"===i&&(u.uniformType=a),"attribute"===i&&(u.attributeType=a),"varying"===i&&(u.varyingType=a),s[i].list.push(u),s[i].map[n]=e,s[i].source+=e+";\n"}),t=(t+="\n").trim(),s.etc=t+"\n",u=e===RedShader.FRAGMENT?"#extension GL_OES_standard_derivatives : enable\n":"",s.precision&&(u+=s.precision.source+"\n//const\n"),s.const&&(u+=s.const.source+"\n//attribute\n"),s.attribute&&(u+=s.attribute.source+"\n//uniform\n"),s.uniform&&(u+=s.uniform.source+"\n//varying\n"),s.varying&&(u+=s.varying.source+"\n//etc\n"),s.etc&&(u+=s.etc),s.lastSource=u,e!==RedShader.FRAGMENT||s.precision||RedGLUtil.throwFunc("RedShader : FRAGMENT Shader는 precision를 반드시 선언해야함"),s},(RedShader=function(i,n,a,o){var s;if(!(this instanceof RedShader))return new RedShader(i,n,a,o);if(i instanceof RedGL||RedGLUtil.throwFunc("RedShader : RedGL Instance만 허용.","입력값 : "+i),"string"==typeof n||RedGLUtil.throwFunc("RedShader : key - 문자열만 허용.","입력값 : "+n),a!==RedShader.VERTEX&&a!==RedShader.FRAGMENT&&RedGLUtil.throwFunc("RedShader : type - RedShader.VERTEX or RedShader.FRAGMENT 만 허용.","입력값 : "+a),i._datas.RedShader||(i._datas.RedShader={},i._datas.RedShader[RedShader.VERTEX]={},i._datas.RedShader[RedShader.FRAGMENT]={}),o)"string"==typeof o||RedGLUtil.throwFunc("RedShader : source - 문자열만 허용."),RedShader.hasKey(i,n,a)?RedGLUtil.throwFunc("RedShader : key - 이미 정의된 키로 생성을 시도.","\n키 :",n,"\n타입 :"+a):i._datas.RedShader[a][n]=this;else{if(RedShader.hasKey(i,n,a))return i._datas.RedShader[a][n];RedGLUtil.throwFunc("RedShader : "+a+" 타입에 존재하지 않는 key를 검색하려고합니다.","입력값 : "+n)}s=i.gl,this.webglShader=e(s,n,a),this.parseData=r(a,o),this.originSource=o,t(s,0,this.webglShader,this.parseData),this.key=n,this.type=a,this._UUID=RedGL.makeUUID(),Object.freeze(this)}).hasKey=function(e,t,r){return!!e._datas.RedShader[r][t]},RedShader.FRAGMENT="fragmentShader",RedShader.VERTEX="vertexShader",Object.freeze(RedShader)}(),function(){var e,t,r,i=[];e=function(t){for(var r,n=i.length;n--;)(r=i[n]).worldRender(r._redGL,t),r._callback&&r._callback(t);requestAnimationFrame(e)},requestAnimationFrame(e),(RedRenderer=function(){if(!(this instanceof RedRenderer))return new RedRenderer;this.world=null,this._tickKey=null,this._callback=null,this._UUID=RedGL.makeUUID(),this.renderInfo={},this.cacheState=[],this.cacheInfo={cacheUniformInfo:[],cacheAttrInfo:[],cacheSamplerIndex:[],cacheTexture:[],cacheSystemUniformInfo:[]},this.renderDebuger=RedRenderDebuger(),this.worldRect=[],this._glInitialized=!1}).prototype={start:function(e,t){e instanceof RedGL||RedGLUtil.throwFunc("RedGL Instance만 허용"),e.world instanceof RedWorld||RedGLUtil.throwFunc("RedWorld Instance만 허용");this.stop(),this.world=e.world,this._redGL=e,this._callback=t,i.push(this)},setDebugButton:function(){var e,t=this;window.document&&(document.body.appendChild(e=document.createElement("button")),e.style.cssText="position:fixed;left:10px;top:10px;background:rgb(91, 82, 170);color:#fff;z-index:10001;border:0;outline:none;cursor:pointer;padding:8px;font-size:11px;border-radius:5px",e.innerHTML="debugRenderInfo - "+RedGL_VERSION.version,e.addEventListener("click",function(){t.renderDebuger.visible=!t.renderDebuger.visible}))},render:function(e,t){e instanceof RedGL||RedGLUtil.throwFunc("RedGL Instance만 허용"),t=t||0,this.world=e.world,this.worldRender(e,t)},stop:function(){-1===(t=i.indexOf(this))||i.splice(t,1)}};var n,a,o,s,d,u,c,l,f,h,R,m=[];u=[],o=function(e){for(c=e.length;c--;)"number"==typeof e[c]?e[c]=e[c]:e[c]=c<2?n[c+2]*parseFloat(e[c])/100:n[c]*parseFloat(e[c])/100;return e},s=function(e,t,i){r=RedSystemUniformUpdater.update(e,this,t,i,r,u)},d=function(e){e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.frontFace(e.CCW),e.enable(e.CULL_FACE),e.cullFace(e.BACK),e.enable(e.SCISSOR_TEST),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.disable(e.DITHER),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!1)},RedRenderer.prototype.worldRender=function(e,t){var r,i,c,l,f,h,R,p,_;for(r=e.gl,a=this,window.RedGLTFLoader&&RedGLTFLoader.animationLooper(t),(n=a.worldRect)[0]=0,n[1]=0,n[2]=r.drawingBufferWidth,n[3]=r.drawingBufferHeight,r.viewport(0,0,r.drawingBufferWidth,r.drawingBufferHeight),r.scissor(0,0,r.drawingBufferWidth,r.drawingBufferHeight),r.clear(r.COLOR_BUFFER_BIT|r.DEPTH_BUFFER_BIT),m.length=0,a._glInitialized||(d(r),a._glInitialized=!0),a.renderInfo={},a.cacheInfo.cacheAttrInfo.length=0,e.gl.activeTexture(e.gl.TEXTURE0),e.gl.bindTexture(e.gl.TEXTURE_2D,e._datas.emptyTexture["2d"].webglTexture),e.gl.activeTexture(e.gl.TEXTURE0+1),e.gl.bindTexture(e.gl.TEXTURE_CUBE_MAP,e._datas.emptyTexture["3d"].webglTexture),h=0,R=a.world._viewList.length;h=L.totalFrame&&(L._loop?(L._playYn=!0,L.currentIndex=0):(L._playYn=!1,L.currentIndex=L.totalFrame-1))}L._sheetRect[0]=1/L._segmentW,L._sheetRect[1]=1/L._segmentH,L._sheetRect[2]=L.currentIndex%L._segmentW/L._segmentW,L._sheetRect[3]=Math.floor(L.currentIndex/L._segmentH)/L._segmentH}for((q=L.program)._prepareProgramYn&&(q=L.program=q._makePrepareProgram()),We=q.key,W||z?Ve?J=H&&z?"directionalShadow_fog_sprite3D":H&&W?"directionalShadow_fog_skin":W?"directionalShadow_skin":z?"directionalShadow_sprite3D":H?"directionalShadow_fog":"directionalShadow":H&&z?J="fog_sprite3D":H&&W?J="fog_skin":W?J="skin":z?J="sprite3D":H&&(J="fog"):J=Q,(Ze=L._programList)&&J&&((K=Ze[J][We])._prepareProgramYn&&(K=Ze[J][We]=K._makePrepareProgram()),q=K),r!=q._UUID&&He.useProgram(q.webglProgram),r=q._UUID,T=q.attributeLocation,I=q.uniformLocation,U=q.systemUniformLocation,S=b.interleaveBuffer,A=b.indexBuffer,X=S._UUID,v=T.length,I.length>v&&(v=I.length),x=S.interleaveDefineInfoList,h!=X&&He.bindBuffer(He.ARRAY_BUFFER,S.webglBuffer),h=X;v--;)(y=T[v])&&(w=x[y.name],G=y.location,w&&qe[G]!=w._UUID&&(!y.enabled&&He.enableVertexAttribArray(G),y.enabled=1,He.vertexAttribPointer(G,w.size,S.glArrayType,w.normalize,S.stride_BYTES_PER_ELEMENT,w.offset_BYTES_PER_ELEMENT),qe[G]=w._UUID)),(D=I[v])&&(B=D.location,X=D._UUID,O=D.renderTypeIndex,C=D.renderType,F=L[D.materialPropertyName],O<2?(j=D.samplerIndex,F?Qe[j]!=F._UUID&&(R!=j&&He.activeTexture(He.TEXTURE0+(R=j)),F._videoDom?(He.bindTexture(He.TEXTURE_2D,F.webglTexture),F._videoDom.loaded&&He.texImage2D(He.TEXTURE_2D,0,He.RGBA,He.RGBA,He.UNSIGNED_BYTE,F._videoDom),Qe=[]):He.bindTexture(0==O?He.TEXTURE_2D:He.TEXTURE_CUBE_MAP,F.webglTexture),Ke[X]!=j&&He.uniform1iv(B,[Ke[X]=j]),Qe[j]=F._UUID):Qe[j]!=O&&(Ke[X]!=O&&He.uniform1iv(B,[Ke[X]=O]),Qe[j]=O,R=O)):(null==F&&RedGLUtil.throwFunc("RedRenderer : Material에 ",D.materialPropertyName,"이 정의 되지않았습니다."),O<13?Je[X]!=F&&He[D.renderMethod](B,(Je[X]=12==O?null:F,F)):13==O?He[D.renderMethod](B,!1,F):RedGLUtil.throwFunc("RedRenderer : 처리할수없는 타입입니다.","tRenderType -",C)))}if(L&&L._RedMouseEventMaterialYn)b&&He.uniformMatrix4fv(U.uMMatrix.location,!1,N);else if(M.autoUpdateMatrix&&(de=1,ue=0,ce=0,fe=0,he=1,Re=0,pe=0,_e=0,ge=1,Y[12]=M.x+M.pivotX,Y[13]=M.y+M.pivotY,Y[14]=M.z+M.pivotZ,Y[15]=1,z?ae=oe=se=0:(ae=M.rotationX*E,oe=M.rotationY*E,se=M.rotationZ*E),(Ce=ae%Ne)<-Oe?Ce+=Ne:Ce>Oe&&(Ce-=Ne),$=(Ce=Ce<0?ke*Ce+Ye*Ce*Ce:ke*Ce-Ye*Ce*Ce)<0?.225*(Ce*-Ce-Ce)+Ce:.225*(Ce*Ce-Ce)+Ce,(Ce=(ae+Xe)%Ne)<-Oe?Ce+=Ne:Ce>Oe&&(Ce-=Ne),re=(Ce=Ce<0?ke*Ce+Ye*Ce*Ce:ke*Ce-Ye*Ce*Ce)<0?.225*(Ce*-Ce-Ce)+Ce:.225*(Ce*Ce-Ce)+Ce,(Ce=oe%Ne)<-Oe?Ce+=Ne:Ce>Oe&&(Ce-=Ne),ee=(Ce=Ce<0?ke*Ce+Ye*Ce*Ce:ke*Ce-Ye*Ce*Ce)<0?.225*(Ce*-Ce-Ce)+Ce:.225*(Ce*Ce-Ce)+Ce,(Ce=(oe+Xe)%Ne)<-Oe?Ce+=Ne:Ce>Oe&&(Ce-=Ne),ie=(Ce=Ce<0?ke*Ce+Ye*Ce*Ce:ke*Ce-Ye*Ce*Ce)<0?.225*(Ce*-Ce-Ce)+Ce:.225*(Ce*Ce-Ce)+Ce,(Ce=se%Ne)<-Oe?Ce+=Ne:Ce>Oe&&(Ce-=Ne),te=(Ce=Ce<0?ke*Ce+Ye*Ce*Ce:ke*Ce-Ye*Ce*Ce)<0?.225*(Ce*-Ce-Ce)+Ce:.225*(Ce*Ce-Ce)+Ce,(Ce=(se+Xe)%Ne)<-Oe?Ce+=Ne:Ce>Oe&&(Ce-=Ne),we=ie*(ne=(Ce=Ce<0?ke*Ce+Ye*Ce*Ce:ke*Ce-Ye*Ce*Ce)<0?.225*(Ce*-Ce-Ce)+Ce:.225*(Ce*Ce-Ce)+Ce),Ie=$*ee*ne-re*te,Ue=re*ee*ne+$*te,De=ie*te,Be=$*ee*te+re*ne,Ge=re*ee*te-$*ne,Se=-ee,Ae=$*ie,Fe=re*ie,ae=M.scaleX,oe=M.scaleY*(a?-1:1),se=M.scaleZ,Y[0]=(de*we+fe*Ie+pe*Ue)*ae,Y[1]=(ue*we+he*Ie+_e*Ue)*ae,Y[2]=(ce*we+Re*Ie+ge*Ue)*ae,Y[3]=Y[3]*ae,Y[4]=(de*De+fe*Be+pe*Ge)*oe,Y[5]=(ue*De+he*Be+_e*Ge)*oe,Y[6]=(ce*De+Re*Be+ge*Ge)*oe,Y[7]=Y[7]*oe,Y[8]=(de*Se+fe*Ae+pe*Fe)*se,Y[9]=(ue*Se+he*Ae+_e*Fe)*se,Y[10]=(ce*Se+Re*Ae+ge*Fe)*se,Y[11]=Y[11]*se,(M.pivotX||M.pivotY||M.pivotZ)&&(de=Y[0],ue=Y[1],ce=Y[2],le=Y[3],fe=Y[4],he=Y[5],Re=Y[6],me=Y[7],pe=Y[8],_e=Y[9],ge=Y[10],ve=Y[11],Ee=Y[12],Me=Y[13],be=Y[14],Le=Y[15],Pe=1,Te=0,ye=0,xe=0,Y[0]=Pe*de+Te*fe+ye*pe+xe*Ee,Y[1]=Pe*ue+Te*he+ye*_e+xe*Me,Y[2]=Pe*ce+Te*Re+ye*ge+xe*be,Y[3]=Pe*le+Te*me+ye*ve+xe*Le,Pe=0,Te=1,ye=0,xe=0,Y[4]=Pe*de+Te*fe+ye*pe+xe*Ee,Y[5]=Pe*ue+Te*he+ye*_e+xe*Me,Y[6]=Pe*ce+Te*Re+ye*ge+xe*be,Y[7]=Pe*le+Te*me+ye*ve+xe*Le,Pe=0,Te=0,ye=1,xe=0,Y[8]=Pe*de+Te*fe+ye*pe+xe*Ee,Y[9]=Pe*ue+Te*he+ye*_e+xe*Me,Y[10]=Pe*ce+Te*Re+ye*ge+xe*be,Y[11]=Pe*le+Te*me+ye*ve+xe*Le,Pe=M.pivotX,Te=M.pivotY,ye=M.pivotZ,xe=1,Y[12]=Pe*de+Te*fe+ye*pe+xe*Ee,Y[13]=Pe*ue+Te*he+ye*_e+xe*Me,Y[14]=Pe*ce+Te*Re+ye*ge+xe*be,Y[15]=Pe*le+Te*me+ye*ve+xe*Le),c?(de=c[0],ue=c[1],ce=c[2],le=c[3],fe=c[4],he=c[5],Re=c[6],me=c[7],pe=c[8],_e=c[9],ge=c[10],ve=c[11],Ee=c[12],Me=c[13],be=c[14],Le=c[15],Pe=Y[0],Te=Y[1],ye=Y[2],xe=Y[3],N[0]=Pe*de+Te*fe+ye*pe+xe*Ee,N[1]=Pe*ue+Te*he+ye*_e+xe*Me,N[2]=Pe*ce+Te*Re+ye*ge+xe*be,N[3]=Pe*le+Te*me+ye*ve+xe*Le,Pe=Y[4],Te=Y[5],ye=Y[6],xe=Y[7],N[4]=Pe*de+Te*fe+ye*pe+xe*Ee,N[5]=Pe*ue+Te*he+ye*_e+xe*Me,N[6]=Pe*ce+Te*Re+ye*ge+xe*be,N[7]=Pe*le+Te*me+ye*ve+xe*Le,Pe=Y[8],Te=Y[9],ye=Y[10],xe=Y[11],N[8]=Pe*de+Te*fe+ye*pe+xe*Ee,N[9]=Pe*ue+Te*he+ye*_e+xe*Me,N[10]=Pe*ce+Te*Re+ye*ge+xe*be,N[11]=Pe*le+Te*me+ye*ve+xe*Le,Pe=Y[12],Te=Y[13],ye=Y[14],xe=Y[15],N[12]=Pe*de+Te*fe+ye*pe+xe*Ee,N[13]=Pe*ue+Te*he+ye*_e+xe*Me,N[14]=Pe*ce+Te*Re+ye*ge+xe*be,N[15]=Pe*le+Te*me+ye*ve+xe*Le):(N[0]=Y[0],N[1]=Y[1],N[2]=Y[2],N[3]=Y[3],N[4]=Y[4],N[5]=Y[5],N[6]=Y[6],N[7]=Y[7],N[8]=Y[8],N[9]=Y[9],N[10]=Y[10],N[11]=Y[11],N[12]=Y[12],N[13]=Y[13],N[14]=Y[14],N[15]=Y[15])),b&&(He.uniformMatrix4fv(U.uMMatrix.location,!1,N),U.uNMatrix.location&&(de=N[0],ue=N[1],ce=N[2],le=N[3],fe=N[4],he=N[5],Re=N[6],me=N[7],pe=N[8],_e=N[9],ge=N[10],ve=N[11],Me=N[12],be=N[13],Ge=_e*(Le=N[14])-ge*be,Fe=1/(Fe=(Ee=de*he-ue*fe)*(Ge=ge*(Pe=N[15])-ve*Le)-(Te=de*Re-ce*fe)*(Se=_e*Pe-ve*be)+(ye=de*me-le*fe)*Ge+(xe=ue*Re-ce*he)*(Be=pe*Pe-ve*Me)-(we=ue*me-le*he)*(De=pe*Le-ge*Me)+(Ie=ce*me-le*Re)*(Ue=pe*be-_e*Me)),k[0]=(he*Ge-Re*Se+me*Ge)*Fe,k[4]=(-ue*Ge+ce*Se-le*Ge)*Fe,k[8]=(be*Ie-Le*we+Pe*xe)*Fe,k[12]=(-_e*Ie+ge*we-ve*xe)*Fe,k[1]=(-fe*Ge+Re*Be-me*De)*Fe,k[5]=(de*Ge-ce*Be+le*De)*Fe,k[9]=(-Me*Ie+Le*ye-Pe*Te)*Fe,k[13]=(pe*Ie-ge*ye+ve*Te)*Fe,k[2]=(fe*Se-he*Be+me*Ue)*Fe,k[6]=(-de*Se+ue*Be-le*Ue)*Fe,k[10]=(Me*we-be*ye+Pe*Ee)*Fe,k[14]=(-pe*we+_e*ye-ve*Ee)*Fe,k[3]=(-fe*Ge+he*De-Re*Ue)*Fe,k[7]=(de*Ge-ue*De+ce*Ue)*Fe,k[11]=(-Me*xe+be*Te-Le*Ee)*Fe,k[15]=(pe*xe-_e*Te+ge*Ee)*Fe,He.uniformMatrix4fv(U.uNMatrix.location,!1,k))),W){var tt,rt=W.joints,it=0,nt=rt.length,at=new Float32Array(16*nt),ot=[N[0],N[1],N[2],N[3],N[4],N[5],N[6],N[7],N[8],N[9],N[10],N[11],N[12],N[13],N[14],N[15]],st=ot,dt=ot[0],ut=ot[1],ct=ot[2],lt=ot[3],ft=ot[4],ht=ot[5],Rt=ot[6],mt=ot[7],pt=ot[8],_t=ot[9],gt=ot[10],vt=ot[11],Et=ot[12],Mt=ot[13],bt=ot[14],Lt=ot[15],Pt=_t*bt*mt-Mt*gt*mt+Mt*Rt*vt-ht*bt*vt-_t*Rt*Lt+ht*gt*Lt,Tt=Et*gt*mt-pt*bt*mt-Et*Rt*vt+ft*bt*vt+pt*Rt*Lt-ft*gt*Lt,yt=pt*Mt*mt-Et*_t*mt+Et*ht*vt-ft*Mt*vt-pt*ht*Lt+ft*_t*Lt,xt=Et*_t*Rt-pt*Mt*Rt-Et*ht*gt+ft*Mt*gt+pt*ht*bt-ft*_t*bt,wt=dt*Pt+ut*Tt+ct*yt+lt*xt;if(0===wt)return mat4.identity(ot);var It=1/wt;for(st[0]=Pt*It,st[1]=(Mt*gt*lt-_t*bt*lt-Mt*ct*vt+ut*bt*vt+_t*ct*Lt-ut*gt*Lt)*It,st[2]=(ht*bt*lt-Mt*Rt*lt+Mt*ct*mt-ut*bt*mt-ht*ct*Lt+ut*Rt*Lt)*It,st[3]=(_t*Rt*lt-ht*gt*lt-_t*ct*mt+ut*gt*mt+ht*ct*vt-ut*Rt*vt)*It,st[4]=Tt*It,st[5]=(pt*bt*lt-Et*gt*lt+Et*ct*vt-dt*bt*vt-pt*ct*Lt+dt*gt*Lt)*It,st[6]=(Et*Rt*lt-ft*bt*lt-Et*ct*mt+dt*bt*mt+ft*ct*Lt-dt*Rt*Lt)*It,st[7]=(ft*gt*lt-pt*Rt*lt+pt*ct*mt-dt*gt*mt-ft*ct*vt+dt*Rt*vt)*It,st[8]=yt*It,st[9]=(Et*_t*lt-pt*Mt*lt-Et*ut*vt+dt*Mt*vt+pt*ut*Lt-dt*_t*Lt)*It,st[10]=(ft*Mt*lt-Et*ht*lt+Et*ut*mt-dt*Mt*mt-ft*ut*Lt+dt*ht*Lt)*It,st[11]=(pt*ht*lt-ft*_t*lt-pt*ut*mt+dt*_t*mt+ft*ut*vt-dt*ht*vt)*It,st[12]=xt*It,st[13]=(pt*Mt*ct-Et*_t*ct+Et*ut*gt-dt*Mt*gt-pt*ut*bt+dt*_t*bt)*It,st[14]=(Et*ht*ct-ft*Mt*ct-Et*ut*Rt+dt*Mt*Rt+ft*ut*bt-dt*ht*bt)*It,st[15]=(ft*_t*ct-pt*ht*ct+pt*ut*Rt-dt*_t*Rt-ft*ut*gt+dt*ht*gt)*It;it mode2DYn - '+t[a].mode2DYn+'
call - '+t[a].call+'
triangleNum - '+t[a].triangleNum+'
width - '+t[a].width+' / height - '+t[a].height+'
viewRectWidth - '+t[a].viewRectWidth+' / viewRectHeight - '+t[a].viewRectHeight+'
x - '+t[a].x+' / y - '+t[a].y+'
renderTime
viewRenderTime - '+t[a].viewRenderTime.toFixed(2)+'ms
baseRenderTime - '+(t[a].viewRenderTime-t[a].postEffectRenderTime).toFixed(2)+'ms
postEffectRenderTime - '+t[a].postEffectRenderTime.toFixed(2)+"ms
",i+=t[a].viewRenderTime,n+=t[a].postEffectRenderTime;r+='
',r+='
renderScale : '+e.renderScale+"
",r+='
totalRenderTime : '+i.toFixed(2)+"ms
",r+='
baseRenderTime : '+(i-n).toFixed(2)+"ms
",r+='
postEffectRenderTime : '+n.toFixed(2)+"ms
",r+="
",this._contentBox.innerHTML=r}}},Object.defineProperty(RedRenderDebuger.prototype,"visible",{get:function(){return this._visible},set:function(e){this._visible=e,window.HTMLCanvasElement&&(this._visible?document.body.appendChild(this.renderResult):this.renderResult.parentNode&&document.body.removeChild(this.renderResult))}}),Object.freeze(RedRenderDebuger),function(){var e,t,r,i,n,a,o,s,d,u,c,l,f,h,R,m,p,_,g,v,E,M,b,L,P,T,y,x,w,I,U,D,B,G,S,A,F,C,O,N;RedSystemUniformUpdater={update:(N=0,E=new Float32Array(3),function(k,Y,X,j,z,V){for(e!=k&&(L=null),e=k,L||(F=RedSystemShaderCode.MAX_DIRECTIONAL_LIGHT,C=RedSystemShaderCode.MAX_POINT_LIGHT,L={uTime:{cacheData:null,data:0},uResolution:{cacheData:null,data:new Float32Array([0,0])},u_FogDensity:{cacheData:null,data:0},uFogColor:{cacheData:null,data:new Float32Array([0,0,0,0])},u_FogDistance:{cacheData:null,data:0},uCameraMatrix:{cacheData:null,data:null},uCameraPosition:{cacheData:null,data:new Float32Array([0,0,0])},uPMatrix:{cacheData:null,data:null},uMode2DYn:{cacheData:null,data:!1},uAmbientLightColor:{cacheData:null,data:new Float32Array([0,0,0,0])},uAmbientIntensity:{cacheData:null,data:1},uDirectionalLightPositionList:{cacheData:null,data:[]},uDirectionalLightColorList:{cacheData:null,data:[]},uDirectionalLightIntensityList:{cacheData:null,data:[]},uDirectionalLightNum:{cacheData:null,data:0},uPointLightPositionList:{cacheData:null,data:[]},uPointLightColorList:{cacheData:null,data:[]},uPointLightIntensityList:{cacheData:null,data:[]},uPointLightRadiusList:{cacheData:null,data:[]},uPointLightNum:{cacheData:null,data:0}},w=new Float32Array(3),T=new Float32Array(16),x=new Float32Array(16),u=new Float32Array(3*F),c=new Float32Array(4*F),l=new Float32Array(F),f=new Float32Array(3*C),h=new Float32Array(4*C),R=new Float32Array(C),m=new Float32Array(C)),t=k.gl,B=j.scene,G=(G=j.camera)instanceof RedBaseController?G.camera:G,S=j._viewRect,D=Y.cacheInfo.cacheSystemUniformInfo,U=null,P={},V.length=0,A=N!=k._datas.RedProgramList.length,N=0,(O=L.uTime).cacheData!=X&&(P.uTime=O.data=X,O.cacheData=X),d=JSON.stringify(S),((O=L.uResolution).cacheData!=d||A)&&(O.data[0]=S[2],O.data[1]=S[3],P.uResolution=O.data,O.cacheData=d),d=B._fogDensity,((O=L.u_FogDensity).cacheData!=d||A)&&(P.u_FogDensity=O.data=d,O.cacheData=d),d=B._fogR+"_"+B._fogG+"_"+B._fogB+"_1",((O=L.uFogColor).cacheData!=d||A)&&(O.data[0]=B._fogR,O.data[1]=B._fogG,O.data[2]=B._fogB,O.data[3]=1,P.uFogColor=O.data,O.cacheData=d),d=B._fogDistance,((O=L.u_FogDistance).cacheData!=d||A)&&(P.u_FogDistance=O.data=d,O.cacheData=d),d=JSON.stringify(G.matrix),((O=L.uCameraMatrix).cacheData!=d||A)&&(P.uCameraMatrix=O.data=G.matrix,O.cacheData=d),d=G.camera?[G.camera.x,G.camera.y,G.camera.z]:[G.x,G.y,G.z],((O=L.uCameraPosition).cacheData!=d.join(",")||A)&&(P.uCameraPosition=O.data=d,O.cacheData=d.join(",")),d=JSON.stringify(G.mode2DYn),((O=L.uMode2DYn).cacheData!=d||A)&&(P.uMode2DYn=O.data=G.mode2DYn,O.cacheData=d),d=JSON.stringify(G.perspectiveMTX),((O=L.uPMatrix).cacheData!=d||A)&&(P.uPMatrix=O.data=G.perspectiveMTX,O.cacheData=d),(g=B._lightInfo[RedAmbientLight.TYPE])&&(d=JSON.stringify(g._lightColor),((O=L.uAmbientLightColor).cacheData!=d||A)&&(P.uAmbientLightColor=O.data=[g._lightColor[0],g._lightColor[1],g._lightColor[2],g._lightColor[3]],O.cacheData=d,P.uAmbientLightColor[0]*=P.uAmbientLightColor[3],P.uAmbientLightColor[1]*=P.uAmbientLightColor[3],P.uAmbientLightColor[2]*=P.uAmbientLightColor[3]),d=g._intensity,((O=L.uAmbientIntensity).cacheData!=d||A)&&(P.uAmbientIntensity=O.data=g._intensity,O.cacheData=d)),p=B._lightInfo[RedDirectionalLight.TYPE],M=p.length;M--;)g=p[M],E[0]=g.x,E[1]=g.y,E[2]=g.z,g.debug&&((v=g._debugObject).x=E[0],v.y=E[1],v.z=E[2],v._material._color=g._lightColor,V.push(v)),vec3.normalize(E,E),u[0+3*M]=E[0],u[1+3*M]=E[1],u[2+3*M]=E[2],c[0+4*M]=g._lightColor[0]*g._lightColor[3],c[1+4*M]=g._lightColor[1]*g._lightColor[3],c[2+4*M]=g._lightColor[2]*g._lightColor[3],c[3+4*M]=g._lightColor[3],l[M]=g._intensity;for(d=JSON.stringify(u),((O=L.uDirectionalLightPositionList).cacheData!=d||A)&&(P.uDirectionalLightPositionList=O.data=u,O.cacheData=d),d=JSON.stringify(c),((O=L.uDirectionalLightColorList).cacheData!=d||A)&&(P.uDirectionalLightColorList=O.data=c,O.cacheData=d),d=JSON.stringify(l),((O=L.uDirectionalLightIntensityList).cacheData!=d||A)&&(P.uDirectionalLightIntensityList=O.data=l,O.cacheData=d),d=p.length,((O=L.uDirectionalLightNum).cacheData!=d||A)&&(P.uDirectionalLightNum=O.data=d,O.cacheData=d),p=B._lightInfo[RedPointLight.TYPE],M=p.length;M--;)g=p[M],E[0]=g.x,E[1]=g.y,E[2]=g.z,g.debug&&((v=g._debugObject).x=E[0],v.y=E[1],v.z=E[2],v.scaleX=v.scaleY=v.scaleZ=g._radius,v._material._color=g._lightColor,V.push(v)),f[0+3*M]=E[0],f[1+3*M]=E[1],f[2+3*M]=E[2],h[0+4*M]=g._lightColor[0]*g._lightColor[3],h[1+4*M]=g._lightColor[1]*g._lightColor[3],h[2+4*M]=g._lightColor[2]*g._lightColor[3],h[3+4*M]=g._lightColor[3],R[M]=g._intensity,m[M]=g._radius;for(d=JSON.stringify(f),((O=L.uPointLightPositionList).cacheData!=d||A)&&(P.uPointLightPositionList=O.data=f,O.cacheData=d),d=JSON.stringify(h),((O=L.uPointLightColorList).cacheData!=d||A)&&(P.uPointLightColorList=O.data=h,O.cacheData=d),d=JSON.stringify(R),((O=L.uPointLightIntensityList).cacheData!=d||A)&&(P.uPointLightIntensityList=O.data=R,O.cacheData=d),d=JSON.stringify(m),((O=L.uPointLightRadiusList).cacheData!=d||A)&&(P.uPointLightRadiusList=O.data=m,O.cacheData=d),d=p.length,((O=L.uPointLightNum).cacheData!=d||A)&&(P.uPointLightNum=O.data=d,O.cacheData=d),B.shadowManager._directionalShadow&&(T[1]=T[2]=T[3]=T[4]=T[6]=T[7]=T[8]=T[9]=T[11]=T[12]=T[13]=T[14]=0,T[0]=T[5]=T[10]=T[15]=1,y=B.shadowManager._directionalShadow.size,_=B.shadowManager._directionalShadow._light,mat4.ortho(x,-y,y,-y,y,-y,y),w[0]=0,w[1]=0,w[2]=0,_&&(w[0]=_.x,w[1]=_.y,w[2]=_.z,vec3.normalize(w,w),mat4.lookAt(T,w,[0,0,0],[0,1,0]),mat4.multiply(T,x,T))),M=k._datas.RedProgramList.length;M--;)for(b in N++,r=k._datas.RedProgramList[M],t.useProgram(r.webglProgram),z=r._UUID,i=r.systemUniformLocation,n=i.uDirectionalShadowLightMatrix,a=n.location,o=n._UUID,a&&B.shadowManager._directionalShadow&&(_=B.shadowManager._directionalShadow._light)&&(d=JSON.stringify(T),D[o]!=d&&(t.uniformMatrix4fv(a,!1,T),D[o]=d)),(n=i.uDirectionalShadowTexture)&&(a=n.location)&&(o=n._UUID,s=B.shadowManager._directionalShadow?B.shadowManager.directionalShadow.frameBuffer.texture:k._datas.emptyTexture["2d"],(I=n.samplerIndex)!=U&&(t.activeTexture(t.TEXTURE0+I),t.bindTexture(t.TEXTURE_2D,s.webglTexture),t[n.renderMethod](a,I)),U=I),P)n=i[b],(a=n.location)&&(o=n._UUID,s=P[b],"mat"==n.renderType?t[n.renderMethod](a,!1,s):t[n.renderMethod](a,s),D[o]=null);return z})},Object.freeze(RedSystemUniformUpdater)}(),(RedView=function(e,t,r){if(!(this instanceof RedView))return new RedView(e,t,r);!t||t instanceof RedScene||RedGLUtil.throwFunc("RedView : RedScene Instance만 허용","입력값 : "+t),r?!r||r instanceof RedCamera||r instanceof RedBaseController||RedGLUtil.throwFunc("RedView : RedCamera or XXController Instance만 허용"):RedGLUtil.throwFunc("RedView : RedCamera or XXController Instance만 허용","입력값 : "+r),this.scene=t,this.postEffectManager=RedPostEffectManager(e),this.camera=r,this._width="100%",this._height="100%",this._x=0,this._y=0,this._viewRect=[0,0,0,0],this._UUID=RedGL.makeUUID()}).prototype={setSize:function(e,t){null==e&&RedGLUtil.throwFunc("RedView setSize : width가 입력되지 않았습니다."),null==t&&RedGLUtil.throwFunc("RedView setSize : height가 입력되지 않았습니다."),"number"==typeof e?this._width=e<0?0:e:e.indexOf("%")>-1&&+e.replace("%","")>=0?this._width=e:RedGLUtil.throwFunc("RedView setSize : width는 0이상의 숫자나 %만 허용.",e),"number"==typeof t?this._height=t<0?0:t:t.indexOf("%")>-1&&+t.replace("%","")>=0?this._height=t:RedGLUtil.throwFunc("RedView setSize : height는 0이상의 숫자나 %만 허용.",t)},setLocation:function(e,t){null==e&&RedGLUtil.throwFunc("RedView setLocation : x가 입력되지 않았습니다."),null==t&&RedGLUtil.throwFunc("RedView setLocation : y가 입력되지 않았습니다."),"number"==typeof e?this._x=e<0?0:e:e.indexOf("%")>-1&&+e.replace("%","")>=0?this._x=e:RedGLUtil.throwFunc("RedView setLocation : x는 0이상의 숫자나 %만 허용.",e),"number"==typeof t?this._y=t<0?0:t:t.indexOf("%")>-1&&+t.replace("%","")>=0?this._y=t:RedGLUtil.throwFunc("RedView setLocation : y는 0이상의 숫자나 %만 허용.",t)}},Object.freeze(RedView),function(){var e,t;(RedWorld=function(){if(!(this instanceof RedWorld))return new RedWorld;this._viewList=[],this._viewMap={},this._UUID=RedGL.makeUUID()}).prototype={addView:function(e,t){e instanceof RedView||RedGLUtil.throwFunc("RedWorld :addView Instance만 허용함.","입력값 : "+e),t&&(this._viewMap[t]?RedGLUtil.throwFunc("RedWorld :key 중복","입력값 : "+t):this._viewMap[t]=e),this._viewList.push(e)},getView:function(e){return"string"==typeof e||RedGLUtil.throwFunc("RedWorld :getView 문자열만 허용함.","입력값 : "+e),this._viewMap[e]},delView:function(r){if("string"==typeof r||r instanceof RedView||RedGLUtil.throwFunc("RedWorld :delView 문자열이나 RedView 만 허용함.","입력값 : "+r),"string"==typeof r)(e=this._viewMap[r])&&(t=this._viewList.indexOf(e),this._viewList.splice(t,1),delete this._viewMap[r]);else for(var i in t=this._viewList.indexOf(r),this._viewList.splice(t,1),this._viewMap)this._viewMap[i]==r&&delete this._viewMap[i]},hasView:function(e){if("string"==typeof e||e instanceof RedView||RedGLUtil.throwFunc("RedWorld :hasView 문자열이나 RedView 만 허용함.","입력값 : "+e),"string"==typeof e)return!!this._viewMap[e];var t=this._viewList.indexOf(e);return!!this._viewList[t]},getViewList:function(){return this._viewList.concat()}},Object.freeze(RedWorld)}(),function(){RedScene=function(e,t){if(!(this instanceof RedScene))return new RedScene(e,t);e instanceof RedGL||RedGLUtil.throwFunc("RedScene : RedGL Instance만 허용.",e),this.backgroundColor=t||"#000000",this.useBackgroundColor=!0,this.useFog=!1,this.fogDensity=.5,this.fogDistance=25,this.fogColor="#ffffff",this.children=[],this.shadowManager=RedShadowManager(e),this.mouseManager=RedMouseEventManager(e),this._lightInfo={RedAmbientLight:null,RedDirectionalLight:[],RedPointLight:[]},this._UUID=RedGL.makeUUID()};var e,t,r={addLight:function(e){switch(e.TYPE){case RedAmbientLight.TYPE:this._lightInfo[e.TYPE]=e;break;case RedDirectionalLight.TYPE:this._lightInfo[e.TYPE].length===RedSystemShaderCode.MAX_DIRECTIONAL_LIGHT&&RedGLUtil.throwFunc("RedScene : RedDirectionalLight "+RedSystemShaderCode.MAX_DIRECTIONAL_LIGHT+"개 까지 허용."),this._lightInfo[e.TYPE].push(e);break;case RedPointLight.TYPE:this._lightInfo[e.TYPE].length===RedSystemShaderCode.MAX_POINT_LIGHT&&RedGLUtil.throwFunc("RedScene : RedPointLight "+RedSystemShaderCode.MAX_POINT_LIGHT+"개 까지 허용."),this._lightInfo[e.TYPE].push(e);break;default:RedGLUtil.throwFunc("RedScene : RedBaseLight 인스턴스만 가능")}},removeLight:function(t){switch(t.TYPE){case RedAmbientLight.TYPE:this._lightInfo[t.TYPE]===t&&(this._lightInfo[t.TYPE]=null);break;case RedDirectionalLight.TYPE:case RedPointLight.TYPE:(e=this._lightInfo[t.TYPE].indexOf(t))>-1&&this._lightInfo[t.TYPE].splice(e,1);break;default:RedGLUtil.throwFunc("RedScene : RedBaseLight 인스턴스만 가능")}},removeLightAll:function(){this._lightInfo[RedAmbientLight.TYPE]=null,this._lightInfo[RedDirectionalLight.TYPE].length=0,this._lightInfo[RedPointLight.TYPE].length=0}};for(var i in RedScene.prototype=new RedBaseContainer,r)RedScene.prototype[i]=r[i];RedDefinePropertyInfo.definePrototype("RedScene","backgroundColor","hex",{callback:function(){t=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._backgroundColor),this._r=t[0],this._g=t[1],this._b=t[2]}}),RedDefinePropertyInfo.definePrototype("RedScene","useBackgroundColor","boolean"),RedDefinePropertyInfo.definePrototype("RedScene","useFog","boolean"),RedDefinePropertyInfo.definePrototype("RedScene","fogDensity","number",{min:0}),RedDefinePropertyInfo.definePrototype("RedScene","fogDistance","number",{min:0}),RedDefinePropertyInfo.definePrototype("RedScene","fogColor","hex",{callback:function(){var e;return function(){e=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._fogColor),this._fogR=e[0],this._fogG=e[1],this._fogB=e[2]}}()}),Object.defineProperty(RedScene.prototype,"skyBox",{get:function(){return this._skyBoxMesh},set:function(e){return!e||e instanceof RedSkyBox||RedGLUtil.throwFunc("RedScene : RedSkyBox Instance만 허용."),this._skyBoxMesh=e,this._skyBoxMesh}}),Object.defineProperty(RedScene.prototype,"grid",{get:function(){return this._gridMesh},set:function(e){return!e||e instanceof RedGrid||RedGLUtil.throwFunc("RedScene : RedGrid Instance만 허용."),this._gridMesh=e,this._gridMesh}}),Object.defineProperty(RedScene.prototype,"axis",{get:function(){return this._axisMesh},set:function(e){return!e||e instanceof RedAxis||RedGLUtil.throwFunc("RedScene : RedAxis Instance만 허용."),this._axisMesh=e,this._axisMesh}}),Object.freeze(RedScene)}(),function(){var e,t;(RedCamera=function(){if(!(this instanceof RedCamera))return new RedCamera;this.x=this.y=this.z=0,this.targetX=this.targetY=this.targetZ=0,this.fov=60,this.nearClipping=.1,this.farClipping=1e5,this.mode2DYn=!1,this.matrix=mat4.create(),this.perspectiveMTX=mat4.create(),this.autoUpdateMatrix=!0,this._UUID=RedGL.makeUUID()}).prototype.update=function(){this.lookAt(this.targetX,this.targetY,this.targetZ)},RedCamera.prototype.lookAt=(e=new Float32Array([0,1,0]),t=[],function(r,i,n){t[0]=this.targetX=r,t[1]=this.targetY=i,t[2]=this.targetZ=n,mat4.identity(this.matrix),mat4.lookAt(this.matrix,[this.x,this.y,this.z],t,e)}),Object.freeze(RedCamera)}(),(RedBasicController=function(e){if(!(this instanceof RedBasicController))return new RedBasicController(e);this.targetView=null,this.keyBuffer={},this.keyNameMapper={moveForward:"w",moveBack:"s",moveLeft:"a",moveRight:"d",moveUp:"t",moveDown:"g",turnLeft:"q",turnRight:"e",turnUp:"r",turnDown:"f"},this.speed=1,this.delay=.1,this.speedRotation=1,this.delayRotation=.1,this.maxAcceleration=3,this._currentAcceleration=0,this.camera=RedCamera(),this._desirePosition=[0,0,0],this._desirePan=0,this._desireTilt=0,this._targetObject=RedMesh(e),function(t){var r,i,n,a,o,s,d,u,c,l,f,h,R,m,p;"ie"==RedGLDetect.BROWSER_INFO.browser&&11==RedGLDetect.BROWSER_INFO.browserVer?(R="offsetX",m="offsetY"):(R="layerX",m="layerY"),p=function(r){if(r||((r={clientX:e._mouseX,clientY:e._mouseY})[R]=e._mouseX,r[m]=e._mouseY),t.targetView){var i,n;if(RedGLDetect.BROWSER_INFO.isMobile?(i=r.clientX,n=r.clientY):(i=r[R],n=r[m]),!(t.targetView._viewRect[0]this._maxAcceleration&&(this._currentAcceleration=this._maxAcceleration)):(this._currentAcceleration+=-.1,this._currentAcceleration<0&&(this._currentAcceleration=0)),r=this._targetObject,n&&(this._desirePan+=e,this._desireTilt+=t),r.rotationY+=(this._desirePan-r.rotationY)*d,r.rotationX+=(this._desireTilt-r.rotationX)*d,(i||n)&&(u=r.matrix,mat4.identity(l),mat4.rotateY(l,l,r.rotationY*Math.PI/180),mat4.rotateX(l,l,r.rotationX*Math.PI/180),mat4.translate(l,l,f),mat4.identity(u),mat4.translate(u,u,[r.x,r.y,r.z]),mat4.multiply(u,u,l),p[0]=u[12],p[1]=u[13],p[2]=u[14]),r.x+=(p[0]-r.x)*s,r.y+=(p[1]-r.y)*s,r.z+=(p[2]-r.z)*s,r.rotationY+=(this._desirePan-r.rotationY)*d,r.rotationX+=(this._desireTilt-r.rotationX)*d,u=r.matrix,mat4.identity(u),mat4.translate(u,u,[r.x,r.y,r.z]),mat4.rotateY(u,u,r.rotationY*Math.PI/180),mat4.rotateX(u,u,r.rotationX*Math.PI/180),c=mat4.clone(u),mat4.translate(c,c,[0,0,.01]),h.x=c[12],h.y=c[13],h.z=c[14],h.lookAt(r.x,r.y,r.z)}}(),Object.freeze(RedBasicController),function(){var e,t,r,i;(RedObitController=function(e){if(!(this instanceof RedObitController))return new RedObitController(e);this.centerX=0,this.centerY=0,this.centerZ=0,this.distance=15,this.speedDistance=2,this.delayDistance=.1,this.speedRotation=3,this.delayRotation=.1,this.tilt=0,this.minTilt=-90,this.maxTilt=90,this.pan=0,this.camera=RedCamera(),this._currentPan=0,this._currentTilt=0,this._currentDistance=0,this.needUpdate=!0,this.targetView=null,function(t){var r,i,n,a,o,s,d,u,c,l,f,h,R,m;h=function(e){if(t.targetView){var r,i;if(RedGLDetect.BROWSER_INFO.isMobile?(r=e.clientX,i=e.clientY):(r=e[R],i=e[m]),!(t.targetView._viewRect[0]this._maxTilt&&(this._tilt=this._maxTilt),e=this._delayRotation,t=this.camera,r=t.matrix,this._currentPan+=(this._pan-this._currentPan)*e,this._currentTilt+=(this._tilt-this._currentTilt)*e,this._currentDistance+=(this._distance-this._currentDistance)*this._delayDistance,mat4.identity(r),mat4.translate(r,r,[this._centerX,this._centerY,this._centerZ]),mat4.rotateY(r,r,this._currentPan*i),mat4.rotateX(r,r,this._currentTilt*i),mat4.translate(r,r,[0,0,this._currentDistance]),t.x=r[12],t.y=r[13],t.z=r[14],t.lookAt(this._centerX,this._centerY,this._centerZ))}),Object.freeze(RedObitController)}(),function(){var e,t,r;e=function(){ +*/},(RedTextMaterial=function(n,a){if(!(this instanceof RedTextMaterial))return new RedTextMaterial(n,a);n instanceof RedGL||RedGLUtil.throwFunc("RedTextMaterial : RedGL Instance만 허용.",n),this.makeProgramList(this,n,"RedTextMaterialProgram",e,t,i),this.diffuseTexture=a,this.alpha=1,this.width=2,this.height=2,this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedDefinePropertyInfo.definePrototypes("RedTextMaterial",["diffuseTexture","sampler2D",{essential:!0}],["alpha","number",{min:0,max:1}],["width","number",{min:2,callback:function(e){this._width=e}}],["height","number",{min:2,callback:function(e){this._height=e}}]),Object.freeze(RedTextMaterial)}(),function(){var e,t,r,i,n=[];e=function(){ +/* @preserve +//#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# +//#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# +void main(void) { +gl_PointSize = uPointSize; +float outlineSize = uOutlineThickness; +//#REDGL_DEFINE#skin#true# mat4 targetMatrix = uMMatrix * getSkinMatrix() ; +//#REDGL_DEFINE#skin#false# mat4 targetMatrix = uMMatrix; +vVertexPosition = targetMatrix * vec4(aVertexPosition, 1.0); +float tScaleX = length(vec3(uMMatrix[0][0], uMMatrix[0][1], uMMatrix[0][2])); +float tScaleY = length(vec3(uMMatrix[1][0], uMMatrix[1][1], uMMatrix[1][2])); +float tScaleZ = length(vec3(uMMatrix[2][0], uMMatrix[2][1], uMMatrix[2][2])); +//#REDGL_DEFINE#sprite3D#true# gl_Position = uPMatrix * getSprite3DMatrix(uCameraMatrix , targetMatrix) * vec4(aVertexPosition, 1.0); +//#REDGL_DEFINE#sprite3D#true# if(!u_PerspectiveScale){ +//#REDGL_DEFINE#sprite3D#true# gl_Position /= gl_Position.w; +//#REDGL_DEFINE#sprite3D#true# gl_Position.xy += aVertexPosition.xy * vec2((uPMatrix * targetMatrix)[0][0],(uPMatrix * targetMatrix)[1][1]); +//#REDGL_DEFINE#sprite3D#true# } +//#REDGL_DEFINE#skin#false#//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition * vec3(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY,1.0+outlineSize/tScaleZ) , 1.0); +//#REDGL_DEFINE#skin#true#//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition + vec3( aVertexNormal * vec3(outlineSize/tScaleX,outlineSize/tScaleY,outlineSize/tScaleZ)), 1.0); +//#REDGL_DEFINE#directionalShadow#true# vResolution = uResolution; +//#REDGL_DEFINE#directionalShadow#true# vShadowPos = cTexUnitConverter * uDirectionalShadowLightMatrix * targetMatrix * vec4(aVertexPosition, 1.0); +} +*/},t=function(){ +/* @preserve +precision mediump float; +//#REDGL_DEFINE#fragmentShareFunc#fogFactor# +//#REDGL_DEFINE#fragmentShareFunc#fog# +//#REDGL_DEFINE#fragmentShareFunc#decodeFloatShadow# +//#REDGL_DEFINE#fragmentShareFunc#getShadowColor# +void main(void) { +vec4 finalColor = uOutlineColor; +//#REDGL_DEFINE#directionalShadow#true# finalColor.rgb *= getShadowColor( vShadowPos, vResolution, uDirectionalShadowTexture); +//#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; +//#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); +} +*/},(RedOutlineMaterial=function(i,a,o){if(!(this instanceof RedOutlineMaterial))return new RedOutlineMaterial(i,a,o);i instanceof RedGL||RedGLUtil.throwFunc("RedOutlineMaterial : RedGL Instance만 허용.","입력값 : "+i),this.makeProgramList(this,i,"RedOutlineMaterialProgram",e,t,n),this._color=new Float32Array(4),this.alpha=null==o?1:o,this.color=a||"#ff0000",this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedOutlineMaterial.DEFINE_OBJECT_COLOR={get:function(){return this._colorHex},set:function(e){this._colorHex=e||"#ff2211",i=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._colorHex),this._color[0]=i[0],this._color[1]=i[1],this._color[2]=i[2],this._color[3]=this._alpha}},RedOutlineMaterial.DEFINE_OBJECT_ALPHA={min:0,max:1,callback:function(e){this._color[3]=this._alpha=e}},Object.defineProperty(RedOutlineMaterial.prototype,"color",RedOutlineMaterial.DEFINE_OBJECT_COLOR),RedDefinePropertyInfo.definePrototype("RedOutlineMaterial","alpha","number",RedOutlineMaterial.DEFINE_OBJECT_ALPHA),Object.freeze(RedOutlineMaterial)}(),function(){var e,t,r,i,n=[];e=function(){ +/* @preserve +//#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# +//#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# +void main(void) { +gl_PointSize = uPointSize; +float outlineSize = uOutlineThickness; +//#REDGL_DEFINE#skin#true# mat4 targetMatrix = uMMatrix * getSkinMatrix() ; +//#REDGL_DEFINE#skin#false# mat4 targetMatrix = uMMatrix; +vVertexPosition = targetMatrix * vec4(aVertexPosition, 1.0); +float tScaleX = length(vec3(targetMatrix[0][0], targetMatrix[0][1], targetMatrix[0][2])); +float tScaleY = length(vec3(targetMatrix[1][0], targetMatrix[1][1], targetMatrix[1][2])); +float tScaleZ = length(vec3(targetMatrix[2][0], targetMatrix[2][1], targetMatrix[2][2])); +//#REDGL_DEFINE#sprite3D#true# gl_Position = uPMatrix * getSprite3DMatrix(uCameraMatrix , targetMatrix) * vec4(aVertexPosition, 1.0); +//#REDGL_DEFINE#sprite3D#true# if(!u_PerspectiveScale){ +//#REDGL_DEFINE#sprite3D#true# gl_Position /= gl_Position.w; +//#REDGL_DEFINE#sprite3D#true# gl_Position.xy += aVertexPosition.xy * vec2((uPMatrix * targetMatrix)[0][0],(uPMatrix * targetMatrix)[1][1]); +//#REDGL_DEFINE#sprite3D#true# } +//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition * vec3(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY,1.0+outlineSize/tScaleZ) , 1.0); +vTexcoord = aTexcoord-0.5; +vTexcoord *= vec2(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY); +//#REDGL_DEFINE#directionalShadow#true# vResolution = uResolution; +//#REDGL_DEFINE#directionalShadow#true# vShadowPos = cTexUnitConverter * uDirectionalShadowLightMatrix * targetMatrix * vec4(aVertexPosition, 1.0); +} +*/},t=function(){ +/* @preserve +precision mediump float; +//#REDGL_DEFINE#fragmentShareFunc#fogFactor# +//#REDGL_DEFINE#fragmentShareFunc#fog# +//#REDGL_DEFINE#fragmentShareFunc#decodeFloatShadow# +//#REDGL_DEFINE#fragmentShareFunc#getShadowColor# +void main(void) { +vec4 finalColor = uOutlineColor; +if(-0.495 =i.end)return 0;e.position=i.cur;try{var n=r(e,t);return i.cur+=n.size,n.id}catch(e){return 0}},n=function(e,t){e.position=t.end},a=function(e,t){var r=t.getUint16(e.position,!0);return e.position+=2,r},o=function(e,t){var r=t.getUint32(e.position,!0);return e.position+=4,r},d=function(e,t){var r=t.getUint8(e.position,!0);return e.position+=1,r},s=function(e,t,r){var i,n,a="";for(i=0;i-1){var c;c=function(e){var t="";return e.map(function(e){t+=String.fromCharCode(e)}),t},n(r+o,function(r){for(var i=null,n=null,a=null,o=null,d=0,l=0,f=null,h=new DataView(r.response,12),R=(c(new Uint8Array(r.response,0,4)),h.getUint32(4,!0),h.getUint32(8,!0),new DataView(r.response,12));d-1&&a.splice(a.indexOf(f),1)},this.playAnimation=function(e){a.push(f={startTime:performance.now(),targetAnimationData:e})}},RedDefinePropertyInfo.definePrototype("RedGLTFLoader","environmentTexture","samplerCube",{callback:function(e){this.parsingResult.materials.forEach(function(t){"environmentTexture"in t&&(t.environmentTexture=e)})}});var a=[];RedGLTFLoader.animationLooper=function(e){for(var t,r,i,n,o,s,d,l,u,c,f,h,R,m,p,_,g,v,E,M,b,L,T,P,x,y,w,U,I,B,F,D,G,A,S,O,C,N,k,Y,X,j,z,V,Z,W,H,q,J,K,Q,$,ee,te,re,ie,ne=a.length;ne--;)for(w=(P=(y=a[ne]).targetAnimationData).length;w--;){for(U=P[w],t=(e-y.startTime)%(1e3*P.maxTime)/1e3,I=U.target,D=U.time,G=U.time,A=D.length,S=0,B=0,r=D[F=D.length-1],i=D[B];Sae){r=D[F=0],i=D[B=A-1],t=ae;break}}if("CUBICSPLINE"==U.interpolation){"NaN"==(x=i-r).toString()&&(x=0);var oe=(t-r)/x;"NaN"==oe.toString()&&(oe=0);var se=oe*oe,de=se*oe,le=-2*de+3*se,ue=de-se,ce=1-le,fe=ue-se+oe;if(I){var he,Re,me,pe,_e=U.data;switch(U.key){case"rotation":if((T=(E=_e[12*F+4])*E+(M=_e[12*F+5])*M+(b=_e[12*F+6])*b+(L=_e[12*F+7])*L)>0&&(T=1/Math.sqrt(T)),f=E*T,h=M*T,R=b*T,m=L*T,(T=(E=_e[12*B+4])*E+(M=_e[12*B+5])*M+(b=_e[12*B+6])*b+(L=_e[12*B+7])*L)>0&&(T=1/Math.sqrt(T)),n=E*T,o=M*T,s=b*T,d=L*T,(T=(E=_e[12*F+8])*E+(M=_e[12*F+9])*M+(b=_e[12*F+10])*b+(L=_e[12*F+11])*L)>0&&(T=1/Math.sqrt(T)),p=E*T,_=M*T,g=b*T,v=L*T,(T=(E=_e[12*F+0])*E+(M=_e[12*F+1])*M+(b=_e[12*F+2])*b+(L=_e[12*F+3])*L)>0&&(T=1/Math.sqrt(T)),F!=A-1){var ge=[0,0,0],ve=(E=ce*(he=f)+fe*(Re=p*x)+le*(me=n)+ue*(pe=E*T*x))*(Ne=E+E),Ee=E*(ke=(M=ce*(he=h)+fe*(Re=_*x)+le*(me=o)+ue*(pe=M*T*x))+M),Me=E*(Ye=(b=ce*(he=R)+fe*(Re=g*x)+le*(me=s)+ue*(pe=b*T*x))+b),be=M*Ye,Le=(L=ce*(he=m)+fe*(Re=v*x)+le*(me=d)+ue*(pe=L*T*x))*Ne,Te=L*ke,Pe=L*Ye;(Ce=[])[0]=1-((Xe=M*ke)+(je=b*Ye)),Ce[4]=Ee-Pe,Ce[8]=Me+Te,Ce[1]=Ee+Pe,Ce[5]=1-(ve+je),Ce[9]=be-Le,Ce[2]=Me-Te,Ce[6]=be+Le,Ce[10]=1-(ve+Xe),Ce[3]=0,Ce[7]=0,Ce[11]=0,Ce[12]=0,Ce[13]=0,Ce[14]=0,Ce[15]=1;var xe=Ce[0],ye=Ce[4],we=Ce[8],Ue=(Ce[1],Ce[5]),Ie=Ce[9],Be=(Ce[2],Ce[6]),Fe=Ce[10];ge[1]=Math.asin(Math.max(-1,Math.min(1,we))),Math.abs(we)<.99999?(ge[0]=Math.atan2(-Ie,Fe),ge[2]=Math.atan2(-ye,xe)):(ge[0]=Math.atan2(Be,Ue),ge[2]=0),ge[0]=-180*ge[0]/Math.PI,ge[1]=-180*ge[1]/Math.PI,ge[2]=-180*ge[2]/Math.PI,I.rotationX=ge[0],I.rotationY=ge[1],I.rotationZ=ge[2]}break;case"translation":n=_e[9*F+3],o=_e[9*F+4],s=_e[9*F+5],f=_e[9*B+3],h=_e[9*B+4],R=_e[9*B+5],p=_e[9*F+6],_=_e[9*F+7],g=_e[9*F+8],l=_e[9*B+0],u=_e[9*B+1],c=_e[9*B+2],F!=A-1&&(he=f,Re=p*x,me=n,pe=l*x,I.x=ce*he+fe*Re+le*me+ue*pe,he=h,Re=_*x,me=o,pe=u*x,I.y=ce*he+fe*Re+le*me+ue*pe,he=R,Re=g*x,me=s,pe=c*x,I.z=ce*he+fe*Re+le*me+ue*pe);break;case"scale":n=_e[9*F+3],o=_e[9*F+4],s=_e[9*F+5],f=_e[9*B+3],h=_e[9*B+4],R=_e[9*B+5],p=_e[9*F+6],_=_e[9*F+7],g=_e[9*F+8],l=_e[9*B+0],u=_e[9*B+1],c=_e[9*B+2],F!=A-1&&(he=f,Re=p*x,me=n,pe=l*x,I.scaleX=ce*he+fe*Re+le*me+ue*pe,he=h,Re=_*x,me=o,pe=u*x,I.scaleY=ce*he+fe*Re+le*me+ue*pe,he=R,Re=g*x,me=s,pe=c*x,I.scaleZ=ce*he+fe*Re+le*me+ue*pe);break;case"weights":for(O=U.targets.length;O--;){for(N=(C=U.targets[O]).geometry.interleaveBuffer.data,k=C._morphInfo.origin,Y=C.geometry.interleaveBuffer.stride,j=N.length/Y,K=C._morphInfo.list.length,G=U.data,(Q=C._morphInfo.list).cacheData||(Q.cacheData={}),X=0;X0&&(T=1/Math.sqrt(T)),f=E*T,h=M*T,R=b*T,m=L*T,(T=(E=_e[4*B])*E+(M=_e[4*B+1])*M+(b=_e[4*B+2])*b+(L=_e[4*B+3])*L)>0&&(T=1/Math.sqrt(T)),(Ge=f*(n=E*T)+h*(o=M*T)+R*(s=b*T)+m*(d=L*T))<0&&(Ge=-Ge,n=-n,o=-o,s=-s,d=-d),1-Ge>glMatrix.EPSILON?(De=Math.acos(Ge),Ae=Math.sin(De),Se=Math.sin((1-x)*De)/Ae,Oe=Math.sin(x*De)/Ae):(Se=1-x,Oe=x);var Ce,Ne,ke,Ye,Xe,je;ge=[0,0,0],ve=(E=Se*f+Oe*n)*(Ne=E+E),Ee=E*(ke=(M=Se*h+Oe*o)+M),Me=E*(Ye=(b=Se*R+Oe*s)+b),be=M*Ye,Le=(L=Se*m+Oe*d)*Ne,Te=L*ke,Pe=L*Ye;(Ce=[])[0]=1-((Xe=M*ke)+(je=b*Ye)),Ce[4]=Ee-Pe,Ce[8]=Me+Te,Ce[1]=Ee+Pe,Ce[5]=1-(ve+je),Ce[9]=be-Le,Ce[2]=Me-Te,Ce[6]=be+Le,Ce[10]=1-(ve+Xe),Ce[3]=0,Ce[7]=0,Ce[11]=0,Ce[12]=0,Ce[13]=0,Ce[14]=0,Ce[15]=1;xe=Ce[0],ye=Ce[4],we=Ce[8],Ce[1],Ue=Ce[5],Ie=Ce[9],Ce[2],Be=Ce[6],Fe=Ce[10];ge[1]=Math.asin(Math.max(-1,Math.min(1,we))),Math.abs(we)<.99999?(ge[0]=Math.atan2(-Ie,Fe),ge[2]=Math.atan2(-ye,xe)):(ge[0]=Math.atan2(Be,Ue),ge[2]=0),ge[0]=-180*ge[0]/Math.PI,ge[1]=-180*ge[1]/Math.PI,ge[2]=-180*ge[2]/Math.PI,I.rotationX=ge[0],I.rotationY=ge[1],I.rotationZ=ge[2];break;case"translation":n=_e[3*B],o=_e[3*B+1],s=_e[3*B+2],f=_e[3*F],h=_e[3*F+1],R=_e[3*F+2],I.x=f+x*(n-f),I.y=h+x*(o-h),I.z=R+x*(s-R);break;case"scale":n=_e[3*B],o=_e[3*B+1],s=_e[3*B+2],f=_e[3*F],h=_e[3*F+1],R=_e[3*F+2],I.scaleX=f+x*(n-f),I.scaleY=h+x*(o-h),I.scaleZ=R+x*(s-R);break;case"weights":for(O=U.targets.length;O--;){var ze;for(N=(C=U.targets[O]).geometry.interleaveBuffer.data,k=C._morphInfo.origin,Y=C.geometry.interleaveBuffer.stride,j=N.length/Y,K=C._morphInfo.list.length,G=U.data,(Q=C._morphInfo.list).cacheData||(Q.cacheData={}),X=0;X-1?t.images[r].uri:(t.images[r].uri.indexOf(";base64,")>-1?"":e.path)+t.images[r].uri},v=function(e,t,r){var i={};if(t.samplers){var n=t.samplers[r];"magFilter"in n&&(i.mag=n.magFilter),"minFilter"in n&&(i.min=n.minFilter),"wrapS"in n&&(i.wrap_s=n.wrapS),"wrapT"in n&&(i.wrap_t=n.wrapT)}return i.string=JSON.stringify(i),i},function(e,t,r){var i,n,a=!1,o=.5;if("material"in r){var s,d,l,u,c,f=r.material,h=t.materials[f];if("doubleSided"in h&&(a=!!h.doubleSided),"alphaMode"in h&&(n=h.alphaMode),"alphaCutoff"in h&&(o=h.alphaCutoff),"baseColorTexture"in h.pbrMetallicRoughness){var R=h.pbrMetallicRoughness.baseColorTexture.index,m=t.textures[R],p=m.source,_=g(e,t,p),E=m.sampler,M=_+(G=v(0,t,E)).string;s=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,G)}if("metallicRoughnessTexture"in h.pbrMetallicRoughness){var b=h.pbrMetallicRoughness.metallicRoughnessTexture.index,L=t.textures[b],T=L.source;_=g(e,t,T),E=L.sampler,M=_+(G=v(0,t,E)).string,l=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,G)}var P=h.normalTexture;if(null!=P){P=P.index;var x=t.textures[P],y=x.source;_=g(e,t,y),E=x.sampler,M=_+(G=v(0,t,E)).string,d=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,G)}var w=h.emissiveTexture;if(null!=w){w=w.index;var U=t.textures[w],I=U.source;_=g(e,t,I),E=U.sampler,M=_+(G=v(0,t,E)).string,u=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,G)}var B,F,D=h.occlusionTexture;if(null!=D){D=D.index;var G,A=t.textures[D],S=A.source;_=g(e,t,S),E=A.sampler,M=_+(G=v(0,t,E)).string,c=e.parsingResult.textures[M]?e.parsingResult.textures[M]:e.parsingResult.textures[M]=RedBitmapTexture(e.redGL,_,G)}"metallicFactor"in h.pbrMetallicRoughness&&(B=h.pbrMetallicRoughness.metallicFactor),"roughnessFactor"in h.pbrMetallicRoughness&&(F=h.pbrMetallicRoughness.roughnessFactor);var O=e.environmentTexture;i=RedPBRMaterial_System(e.redGL,s,O,d,c,u,l,null),C=h.pbrMetallicRoughness&&h.pbrMetallicRoughness.baseColorFactor?h.pbrMetallicRoughness.baseColorFactor:[1,1,1,1],i.baseColorFactor=new Float32Array(C),h.pbrMetallicRoughness&&(i.metallicFactor=null!=B?B:1,i.roughnessFactor=null!=F?F:1),i.emissiveFactor=null!=h.emissiveFactor?h.emissiveFactor:new Float32Array([1,1,1]),h.pbrMetallicRoughness&&(h.pbrMetallicRoughness.metallicRoughnessTexture&&(i.roughnessTexCoordIndex=h.pbrMetallicRoughness.metallicRoughnessTexture.texCoord||0),h.pbrMetallicRoughness.baseColorTexture&&(i.diffuseTexCoordIndex=h.pbrMetallicRoughness.baseColorTexture.texCoord||0)),h.occlusionTexture&&(i.occlusionTexCoordIndex=h.occlusionTexture.texCoord||0,i.occlusionPower=h.occlusionTexture.strength||1),h.emissiveTexture&&(i.emissiveTexCoordIndex=h.emissiveTexture.texCoord||0),h.normalTexture&&(i.normalTexCoordIndex=h.normalTexture.texCoord||0)}else{var C=[Math.random(),Math.random(),Math.random(),1];(i=RedPBRMaterial_System(e.redGL)).baseColorFactor=new Float32Array(C)}return[i,a,n,o]}),x=function(e,t,r,i,n,a,o,s,d){for(var l=0,u=t.length/3,c=0;l-1&&e.parsingOption[A](u);switch(u.drawMode=f||e.redGL.gl.TRIANGLES,n&&(u.useCullFace=!1,c.useMaterialDoubleSide=!0),a){case"BLEND":u.useTransparentSort=!0;break;case"MASK":u.useBlendMode=!1,c.cutOff=o;break;default:u.useBlendMode=!1,c._cutOff=-.1}p.length&&(c.useVertexColor_0=!0),w.length&&(c.useVertexTangent=!0);var S=new T(e,t,d,r.weights);S.list.forEach(function(e){var t;t=e.normals.length?e.normals:RedGLUtil.calculateNormals(e.vertices,R);var r=[];x(r,e.vertices,e.verticesColor_0,t,e.uvs,e.uvs1,e.jointWeights,e.joints,e.tangents),e.interleaveData=r}),u._morphInfo=S,u._morphInfo.origin=new Float32Array(D);var O=u.geometry.interleaveBuffer.data,C=0;G.forEach(function(e){C+=e.size});u._morphInfo.list.forEach(function(e,t){for(var r=0,i=O.length/C,n=null==u._morphInfo.list.weights[t]?.5:u._morphInfo.list.weights[t];rf.time[0]&&(s.minTime=f.time[0]),s.maxTime0){var e=parseFloat(u);if(c.push(e),2===c.length){if(s&&(c[0]+=f[0],c[1]+=f[1]),o.push(c),d&&(h=c.slice()),!--l){if("l"===i){var t=o.pop(),r=o.pop(),n=vec2.lerp([0,0],r,t,.25),a=vec2.lerp([0,0],r,t,.75);o.push(r,n,a,t)}f=h}c=[]}u=""}}var m,p=e.split("");for(n=0,a=p.length;n="0"&&m<="9"||"."===m?u+=m:"-"===m?(R(),u="-"):"m"===m?(R(),d=!0,l=1,s=!0,i="m"):"c"===m?(R(),d=!0,l=3,s=!0,i="c"):"l"===m?(R(),d=!0,l=1,s=!1,i="l"):"M"===m?(R(),d=!0,l=1,s=!1,i="m"):"C"===m?(R(),d=!0,l=3,s=!1,i="c"):"L"===m?(R(),d=!0,l=1,s=!1,i="l"):"Z"===m||(","===m?R():" "===m&&R());R();var _=o[0].slice(),g=o[0].slice();for(n=1,a=o.length;nI&&vec3.add(A,A,t)}),vec3.normalize(A,A);var S=3*F,O=2*F;U.push(w(i[S+0],i[S+1],i[S+2],A[0],A[1],A[2],n[O+0],n[O+1]))}}return{position:P,texcoord:x,normal:y,indices:U}},e=function(e,t,r){var i,n=[],a=r.position,o=r.normal,s=r.texcoord;i=r.indices;for(var d,l=0,u=a.length/3;lu&&(u=h,c=f)}return Math.sqrt(u)>i?(o(e,t,c+1,i,a),o(e,c,r,i,a)):a.push(d,l),a},e=function(e,t){null==t&&(t=1);for(var r,i,n,a,o=e.length,s=o-2,d=0;d1){var l=e(i.points,a);i._serializedPoints=r(l),l=t(i._serializedPoints,s);for(var u=0,c=(l=o(l,0,l.length,d)).length;u1){i._serializedPoints=r(i.points),l=t(i._serializedPoints,s);for(u=0,c=(l=o(l,0,l.length,d)).length;uh.max&&(l=h.max-d);l--;)m=this.list[d+l]=new RedParticleUnit(h.lifeTime),this._interleaveData.push(this.x,this.y,this.z),this._interleaveData.push(0),h.tint==RedParticleEmitter.TINT_RANDOM?this._interleaveData.push(Math.random(),Math.random(),Math.random(),1):this._interleaveData.push(h.tint[0],h.tint[1],h.tint[2],1),h.particle&&(R.movementX&&m.addRule("movementX",R.movementX),R.movementY&&m.addRule("movementY",R.movementY),R.movementZ&&m.addRule("movementZ",R.movementZ),R.scale&&m.addRule("scale",R.scale),R.alpha&&m.addRule("alpha",R.alpha));for(d=this.list.length,_="movementX,movementY,movementZ,scale,alpha".split(",");d--;)if((u=this.list[d]).startTime||(u.startTime=e,u.age=0),u.age=e-u.startTime,f=8*d,(c=u.age/u.lifeTime)<1)for(E=c,u.startCenter||(u.startCenter=[this.x,this.y,this.z]),l=_.length;l--;)E=c,(p=u[g=_[l]].ease)&&(1==p?E*=E*E*E*E:2==p?E=(E-=1)*E*E*E*E+1:3==p?E=(E*=2)<1?E*E*E*E*E*.5:.5*((E-=2)*E*E*E*E+2):4==p?E=E*E*(1.70158*E+E-1.70158):5==p?E=(E-=1)*E*(1.70158*E+E+1.70158)+1:6==p?E=(E*=2)<1?.5*E*E*(1.70158*E+E-1.70158):.5*(E-=2)*E*(1.70158*E+E+1.70158)+1:7==p?E=-1*(n(1-E*E)-1):8==p?E=n(1-(E-=1)*E):9==p?E=(E*=2)<1?-.5*(n(1-E*E)-1):.5*n(1-(E-=2)*E)+.5:10==p?E*=E*E:11==p?E=(E-=1)*E*E+1:12==p?E=(E*=2)<1?E*E*E*.5:.5*((E-=2)*E*E+2):13==p?E=0==E?0:t(2,10*(E-1)):14==p?E=1==E?1:1-t(2,-10*E):15==p?E=(E*=2)<1?0==E?0:.5*t(2,10*(E-1)):2==E?1:-.5*t(2,-10*(E-1))+1:16==p?E*=E:17==p?E*=2-E:18==p?E=(E*=2)<1?E*E*.5:.5*((2-(E-=1))*E+1):19==p?E*=E*E*E:20==p?E=1-(E-=1)*E*E*E:21==p?E=(E*=2)<1?E*E*E*E*.5:1-(E-=2)*E*E*E*.5:22==p?E=1-i(E*s):23==p?E=r(E*s):24==p?E=.5*(1-i(E*a)):25==p?E=0===E?0:1===E?1:-1*t(2,10*(E-=1))*r((E-.075)*o/.3):26==p?E=0===E?0:1===E?1:t(2,-10*E)*r((E-.075)*o/.3)+1:27==p&&(0===E||1===E||(E*=2),E=E<1?-.5*t(2,10*(E-=1))*r((E-.075)*o/.3):.5*t(2,-10*(E-=1))*r((E-.075)*o/.3)+1)),"movementX"==g&&(v=0),"movementY"==g&&(v=1),"movementZ"==g&&(v=2),"scale"==g&&(v=3),"alpha"==g&&(v=7),this._interleaveData[f+v]=v<3?u.startCenter[v]+u[g].start+u[g].gap*E:u[g].start+u[g].gap*E,h.gravity&&(u._gravitySum-=h.gravity),this._interleaveData[f+1]+=u._gravitySum;else this._interleaveData[f+0]=u.startCenter[0]=this.x,this._interleaveData[f+1]=u.startCenter[1]=this.y,this._interleaveData[f+2]=u.startCenter[2]=this.z,this._interleaveData[f+3]=u.scale.start,h.tint==RedParticleEmitter.TINT_RANDOM?(this._interleaveData[f+4]=Math.random(),this._interleaveData[f+5]=Math.random(),this._interleaveData[f+6]=Math.random()):(this._interleaveData[f+4]=h.tint[0],this._interleaveData[f+5]=h.tint[1],this._interleaveData[f+6]=h.tint[2]),this._interleaveData[f+7]=0,u._gravitySum=0,u.startTime=null,u.age=-1;this._geometry.interleaveBuffer.upload(new Float32Array(this._interleaveData))},RedDefinePropertyInfo.definePrototype("RedParticleEmitter","diffuseTexture","sampler2D",{callback:function(e){this.material.diffuseTexture=e}}),Object.freeze(RedParticleEmitter),function(){var e,t,r;r=function(e,r,i,n,a,o,s,d,l,u,c,f){var h,R,m=d/c,p=l/f,_=d/2,g=l/2,v=u/2,E=c+1,M=f+1,b=0,L=[];for(R=0;R0?1:-1,e.push(L.x,L.y,L.z),e.push(h/c,R/f),b+=1}}for(R=0;R0&&t(!0),n>0&&t(!1)),{interleaveData:c,indexData:f,type:r,interleaveBuffer:RedBuffer(e,r+"_interleaveBuffer",RedBuffer.ARRAY_BUFFER,new Float32Array(c),[RedInterleaveInfo("aVertexPosition",3),RedInterleaveInfo("aVertexNormal",3),RedInterleaveInfo("aTexcoord",2)]),indexBuffer:RedBuffer(e,r+"_indexBuffer",RedBuffer.ELEMENT_ARRAY_BUFFER,new Uint16Array(f))}},(RedCylinder=function(t,r,i,n,a,o,s,d,l){return this instanceof RedCylinder?(t instanceof RedGL||RedGLUtil.throwFunc("RedPrimitive : RedGL Instance만 허용.",t),u="RedCylinder_"+(r=void 0!==r?r:1)+"_"+(i=void 0!==i?i:1)+"_"+(n=void 0!==n?n:1)+"_"+(a=Math.floor(a)||8)+"_"+(o=Math.floor(o)||1)+"_"+(s=void 0!==s&&s)+"_"+(d=void 0!==d?d:0)+"_"+(l=void 0!==l?l:2*Math.PI),t._datas.Primitives||(t._datas.Primitives={}),t._datas.Primitives[u]?t._datas.Primitives[u]:(t._datas.Primitives[u]=this,c=e(t,u,r,i,n,a,o,s,d,l),this.interleaveBuffer=c.interleaveBuffer,this.indexBuffer=c.indexBuffer,this.interleaveBuffer.isPrimitiveBuffer=!0,this.indexBuffer.isPrimitiveBuffer=!0,void(this._UUID=RedGL.makeUUID()))):new RedCylinder(t,r,i,n,a,o,s,d,l);var u,c}).prototype=Object.create(RedGeometry.prototype),Object.freeze(RedCylinder)}(),function(){var e,t,r,i,n,a,o,s,d,l,u,c,f,h,R,m,p;e=function(e,_,g,v,E,M,b){t=g/2,r=v/2,i=Math.floor(E)||1,n=Math.floor(M)||1,a=i+1,o=n+1,s=g/i,d=v/n;var L=[],T=[];for(u=0;u0)&&M.push(a,o,d),(i!==m-1||t-1&&RedGLUtil.throwFunc("RedProgram : 프로그램이름에 _ 는 허용하지 않음.","입력값 : "+t),r="string"==typeof r?r:RedGLUtil.getStrFromComment(r.toString()),i="string"==typeof i?i:RedGLUtil.getStrFromComment(i.toString());var o=!1,s=!1,d=!1,l=!1;for(var u in RedSystemShaderCode.vertexShareFunc)a=new RegExp("//#REDGL_DEFINE#vertexShareFunc#"+u+"#","gi"),r=r.replace(a,RedSystemShaderCode.vertexShareFunc[u]);for(var u in RedSystemShaderCode.fragmentShareFunc)a=new RegExp("//#REDGL_DEFINE#fragmentShareFunc#"+u+"#","gi"),i=i.replace(a,RedSystemShaderCode.fragmentShareFunc[u]);if(n){n.sort(),t+="_"+n.join("_");for(var c=n.length;c--;)"fog"===n[c]&&(o=!0),"sprite3D"===n[c]&&(s=!0),"directionalShadow"===n[c]&&(d=!0),"skin"===n[c]&&(l=!0),"fog"!==n[c]&&"sprite3D"!=n[c]&&"directionalShadow"!=n[c]&&"skin"!=n[c]&&(a=new RegExp("//#REDGL_DEFINE#"+n[c]+"#","gi"),r=r.replace(a,""),i=i.replace(a,""))}return a=new RegExp("//#REDGL_DEFINE#fog#"+(o?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),a=new RegExp("//#REDGL_DEFINE#sprite3D#"+(s?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),a=new RegExp("//#REDGL_DEFINE#directionalShadow#"+(d?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),a=new RegExp("//#REDGL_DEFINE#skin#"+(l?"true":"false")+"#","gi"),r=r.replace(a,""),i=i.replace(a,""),RedProgram(e,t,r,i,n)},Object.freeze(RedProgram)}(),(RedSystemShaderCode={}).init=function(e){var t,r,i=e.detect;r=parseInt(Math.floor(Math.min((i.vertexShader.MAX_VERTEX_UNIFORM_VECTORS-64)/8,128))),t=parseInt(Math.floor(Math.min((i.fragmentShader.MAX_FRAGMENT_UNIFORM_VECTORS-64)/4,128))),(RedSystemShaderCode={vertexShareDeclare:["attribute vec3 aVertexPosition","attribute vec3 aVertexNormal","attribute vec4 aVertexColor","attribute vec4 aVertexWeight","attribute vec4 aVertexJoint","varying vec4 vVertexPosition","varying vec3 vVertexNormal","varying vec4 vVertexColor","attribute float aPointSize","uniform float uPointSize","attribute vec2 aTexcoord","attribute vec2 aTexcoord1","varying vec2 vTexcoord","varying vec2 vTexcoord1","uniform bool uMode2DYn","uniform float uTime","varying float vTime","uniform vec2 uResolution","varying vec2 vResolution","uniform mat4 uMMatrix","uniform mat4 uNMatrix","uniform mat4 uPMatrix","uniform mat4 uCameraMatrix","uniform bool u_PerspectiveScale","uniform float uOutlineThickness","uniform mat4 uDirectionalShadowLightMatrix","varying highp vec4 vShadowPos","const mat4 cTexUnitConverter = mat4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0)","uniform mat4 uJointMatrix["+r+"]","uniform mat4 uInverseBindMatrixForJoint["+r+"]","uniform mat4 uGlobalTransformOfNodeThatTheMeshIsAttachedTo"],fragmentShareDeclare:["varying vec4 vVertexPosition","varying vec3 vVertexNormal","varying vec4 vVertexColor","varying vec2 vTexcoord","varying vec2 vTexcoord1","varying float vTime","varying vec2 vResolution","uniform vec3 uCameraPosition","uniform vec4 uOutlineColor","uniform float u_FogDistance","uniform float u_FogDensity","uniform vec4 uFogColor","const int cDIRETIONAL_MAX = 3","uniform vec3 uDirectionalLightPositionList[3]","uniform vec4 uDirectionalLightColorList[3]","uniform float uDirectionalLightIntensityList[3]","uniform int uDirectionalLightNum","const int cPOINT_MAX = "+t,"uniform vec3 uPointLightPositionList["+t+"]","uniform vec4 uPointLightColorList["+t+"]","uniform float uPointLightRadiusList["+t+"]","uniform float uPointLightIntensityList["+t+"]","uniform int uPointLightNum","uniform vec4 uAmbientLightColor","uniform float uAmbientIntensity","uniform sampler2D uDirectionalShadowTexture","varying highp vec4 vShadowPos"],systemUniform:{},vertexShareFunc:{getSkinMatrix:["//#REDGL_DEFINE#skin#true# mat4 getSkinMatrix(){","//#REDGL_DEFINE#skin#true# mat4 skinMat =","//#REDGL_DEFINE#skin#true# aVertexWeight.x * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.x) ] * uInverseBindMatrixForJoint[int(aVertexJoint.x)]+","//#REDGL_DEFINE#skin#true# aVertexWeight.y * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.y) ] * uInverseBindMatrixForJoint[int(aVertexJoint.y)]+","//#REDGL_DEFINE#skin#true# aVertexWeight.z * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.z) ] * uInverseBindMatrixForJoint[int(aVertexJoint.z)]+","//#REDGL_DEFINE#skin#true# aVertexWeight.w * uGlobalTransformOfNodeThatTheMeshIsAttachedTo * uJointMatrix[ int(aVertexJoint.w) ] * uInverseBindMatrixForJoint[int(aVertexJoint.w)];","//#REDGL_DEFINE#skin#true# return skinMat;","//#REDGL_DEFINE#skin#true# }"].join("\n"),getSprite3DMatrix:["mat4 getSprite3DMatrix(mat4 cameraMTX, mat4 mvMatrix){"," mat4 cacheScale = mat4("," mvMatrix[0][0], 0.0, 0.0, 0.0,"," 0.0, mvMatrix[1][1], 0.0, 0.0,"," 0.0, 0.0, 1.0, mvMatrix[2][2],"," 0.0, 0.0, 0.0, 1.0"," );"," mat4 tMTX = cameraMTX * mvMatrix;"," tMTX[0][0] = 1.0, tMTX[0][1] = 0.0, tMTX[0][2] = 0.0,"," tMTX[1][0] = 0.0, tMTX[1][1] = 1.0, tMTX[1][2] = 0.0,"," tMTX[2][0] = 0.0, tMTX[2][1] = 0.0, tMTX[2][2] = 1.0;"," return tMTX * cacheScale;","}"].join("\n")},fragmentShareFunc:{getFlatNormal:["vec3 getFlatNormal(vec3 vertexPosition){"," vec3 dx = dFdx(vVertexPosition.xyz);"," vec3 dy = dFdy(vVertexPosition.xyz);"," return normalize(cross(normalize(dx), normalize(dy)));","}"].join("\n"),getDirectionalLightColor:["vec4 getDirectionalLightColor( vec4 texelColor, vec3 N, float shininess, vec4 specularLightColor, float specularTextureValue, float specularPower) {"," vec3 L;"," float specular;"," float lambertTerm;"," vec4 ld = vec4(0.0, 0.0, 0.0, 1.0);"," vec4 ls = vec4(0.0, 0.0, 0.0, 1.0);"," for(int i=0; i 0.0){"," ld += uDirectionalLightColorList[i] * texelColor * lambertTerm * uDirectionalLightIntensityList[i];"," specular = pow( max(dot(reflect(L, N), -L), 0.0), shininess) * specularPower * specularTextureValue;"," ls += specularLightColor * specular * uDirectionalLightIntensityList[i] * uDirectionalLightColorList[i].a;"," }"," }"," return ld + ls;","}"].join("\n"),getPointLightColor:["vec4 getPointLightColor( vec4 texelColor, vec3 N, float shininess, vec4 specularLightColor, float specularTextureValue, float specularPower) {"," vec3 L;"," float specular;"," float lambertTerm;"," vec4 ld = vec4(0.0, 0.0, 0.0, 1.0);"," vec4 ls = vec4(0.0, 0.0, 0.0, 1.0);"," float distanceLength;"," float attenuation;"," for(int i=0;i distanceLength){"," attenuation = 1.0 / (0.01 + 0.02 * distanceLength + 0.03 * distanceLength * distanceLength) * 0.5;"," L = normalize(L);"," lambertTerm = dot(N,-L);"," if(lambertTerm > 0.0){"," ld += uPointLightColorList[i] * texelColor * lambertTerm * attenuation * uPointLightIntensityList[i] ;"," specular = pow( max(dot( reflect(L, N), -N), 0.0), shininess) * specularPower * specularTextureValue;"," ls += specularLightColor * specular * uPointLightIntensityList[i] * uPointLightColorList[i].a ;"," }"," }"," }"," return ld + ls;","}"].join("\n"),fogFactor:["float fogFactor(float perspectiveFar, float density){"," float flog_cord = gl_FragCoord.z / gl_FragCoord.w / perspectiveFar;"," float fog = flog_cord * density;"," if(1.0 - fog < 0.0) discard;"," return clamp(1.0 - fog, 0.0, 1.0);","}"].join("\n"),fog:["vec4 fog(float fogFactor, vec4 fogColor, vec4 currentColor) {"," return mix(fogColor, currentColor, fogFactor);","}"].join("\n"),decodeFloatShadow:["float decodeFloatShadow (vec4 color) {"," const vec4 cBitShift = vec4("," 1.0 / (256.0 * 256.0 * 256.0),"," 1.0 / (256.0 * 256.0),"," 1.0 / 256.0,"," 1.0"," );"," return dot(color, cBitShift);","}"].join("\n"),getShadowColor:["float getShadowColor ( vec4 shadowPos, vec2 resolution, sampler2D directionalShadowTexture ) {"," vec3 fragmentDepth = shadowPos.xyz;"," fragmentDepth.z -= 0.007; // cShadowAcneRemover"," float amountInLight = 0.0;"," for (int x = -1; x <= 1; x++) {"," for (int y = -1; y <= 1; y++) {"," vec2 tUV = fragmentDepth.xy + vec2( float(x)/resolution.x, float(y)/resolution.y );"," if(tUV.x<0.0) return 1.0;"," if(tUV.x>1.0) return 1.0;"," if(tUV.y<0.0) return 1.0;"," if(tUV.y>1.0) return 1.0;"," float texelDepth = decodeFloatShadow( texture2D(directionalShadowTexture, tUV) );"," if (fragmentDepth.z < texelDepth ) amountInLight += 1.0;"," }"," }"," amountInLight /= 9.0;"," amountInLight = amountInLight;"," return amountInLight;","}"].join("\n"),cotangent_frame:["mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)","{"," vec3 dp1 = dFdx( p );"," vec3 dp2 = dFdy( p );"," vec2 duv1 = dFdx( uv );"," vec2 duv2 = dFdy( uv );"," "," vec3 dp2perp = cross( dp2, N );"," vec3 dp1perp = cross( N, dp1 );"," vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;"," vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;"," "," float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );"," return mat3( T * invmax, B * invmax, N );","}"].join("\n"),perturb_normal:["vec3 perturb_normal( vec3 N, vec3 V, vec2 texcoord, vec3 normalColor )"," {"," "," vec3 map = normalColor;"," map = map * 255./127. - 128./127.;"," map.xy *= u_normalPower;"," mat3 TBN = cotangent_frame(N, V, texcoord);"," return normalize(TBN * map);","}"].join("\n")}}).MAX_DIRECTIONAL_LIGHT=3,RedSystemShaderCode.MAX_POINT_LIGHT=t,RedSystemShaderCode.MAX_JOINT=r,[RedSystemShaderCode.vertexShareDeclare,RedSystemShaderCode.fragmentShareDeclare].forEach(function(e){e.forEach(function(e){"uniform"===(e=e.split(" "))[0]&&(RedSystemShaderCode.systemUniform[e[2]]=1)})});var n=[],a=[],o={bool:4,float:4,int:4,uint:4,sampler2D:4,samplerCube:4,vec2:4,vec3:4,vec4:4,mat2:4,mat3:8,mat4:16};RedSystemShaderCode.vertexShareDeclare.forEach(function(e){var t;"uniform"===(e=e.split(" "))[0]&&(t={value:e,type:e[1],num:e[2].indexOf("[")>-1?+e[2].split("[")[1].replace("]","")*o[e[1]]:o[e[1]]},n.push(t))}),a=[],RedSystemShaderCode.fragmentShareDeclare.forEach(function(e){var t;"uniform"===(e=e.split(" "))[0]&&(t={value:e,type:e[1],num:e[2].indexOf("[")>-1?+e[2].split("[")[1].replace("]","")*o[e[1]]:o[e[1]]},a.push(t))}),Object.freeze(RedSystemShaderCode)},function(){var e,t,r,i,n,a,o,s,d,l;e=function(e,t,r){switch(r){case RedShader.VERTEX:return(n=e.createShader(e.VERTEX_SHADER))||(e.isContextLost()?RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - WebGL 컨텍스트가 손실"):RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - GPU메모리가 부족일 가능성이 큼")),n.key=t,n.type=r,n;case RedShader.FRAGMENT:return(n=e.createShader(e.FRAGMENT_SHADER))||(e.isContextLost()?RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - WebGL 컨텍스트가 손실"):RedGLUtil.throwFunc("RedShader : 쉐이더를 생성실패! - GPU메모리가 부족일 가능성이 큼")),n.key=t,n.type=r,n;default:RedGLUtil.throwFunc("RedShader : 쉐이더 타입을 확인하세요. RedShader.VERTEX or RedShader.FRAGMENT 만 허용")}},t=function(e,t,r,i){e.shaderSource(r,i.lastSource),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)||RedGLUtil.throwFunc("RedShader : 쉐이더 컴파일에 실패하였습니다.\n",e.getShaderInfoLog(r))},i=function(e,t){var r;switch(e){case RedShader.VERTEX:r=RedSystemShaderCode.vertexShareDeclare.concat();break;case RedShader.FRAGMENT:r=RedSystemShaderCode.fragmentShareDeclare.concat();break;default:RedGLUtil.throwFunc("RedShader : 쉐이더 타입을 확인하세요. RedShader.VERTEX or RedShader.FRAGMENT 만 허용")}for(a=t.length;a--;)o=(o=t[a]).replace(";",""),-1===r.indexOf(o)?r.push(o):RedGLUtil.throwFunc("RedShader : ","\n1. 중복 선언 이거나","\n2. RedSystemShaderCode에 정의된 선언\n","입력값 : "+o);return r},r=function(e,t){return t=(t=t.replace(/\s+$/,"")).replace(/ /g,"").trim(),s={etc:""},d=t.match(/attribute[\s\S]+?\;|uniform[\s\S]+?\;|varying[\s\S]+?\;|const[\s\S]+?\;|precision[\s\S]+?\;/g),(d=i(e,d=d||[])).sort(),d.forEach(function(e){var r,i,n,a,o,d,l,u,c;if(e=e.trim(),t=t.replace(e+";",""),("highp"===(r=e.split(" "))[1]||"mediump"===r[1]||"lowp"===r[1])&&(c=r[1],r.splice(1,1),r.push(c),u=c),r[2])switch(i=r[0],a=r[1],n=r[2].replace(";","").split("["),d=(d=e.split("="))[1]?d[1].trim().replace(";",""):null,o=n.length>1?+n[1].split("]")[0]:0,n=n[0],i){case"precision":break;case"attribute":"a"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : attribute의 첫글자는 a로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : attribute의 두번째 글자는 대문자 시작해야합니다.",n,r);break;case"uniform":"u"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : uniform의 첫글자는 u로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : uniform의 두번째 글자는 대문자 시작해야합니다.",n,r);break;case"varying":"v"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : varying의 첫글자는 v로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : varying의 두번째 글자는 대문자 시작해야합니다.",n,r);break;case"const":"c"!==n.charAt(0)&&RedGLUtil.throwFunc("RedShader : const의 첫글자는 c로 시작해야합니다.",n,r),n.charAt(1)!==n.charAt(1).toUpperCase()&&RedGLUtil.throwFunc("RedShader : const의 두번째 글자는 대문자 시작해야합니다.",n,r);break;default:RedGLUtil.throwFunc("RedShader : 체크되지 못하는값인데 뭐냐",n,r)}else RedGLUtil.throwFunc("RedShader : 체크되지 못하는값인데 뭐냐",r);s[i]||(s[i]={},s[i].list=[],s[i].map={},s[i].source=""),l={name:n,arrayNum:o,value:d,precision:u,systemUniformYn:!!RedSystemShaderCode.systemUniform[o?n+"["+o+"]":n]},"uniform"===i&&(l.uniformType=a),"attribute"===i&&(l.attributeType=a),"varying"===i&&(l.varyingType=a),s[i].list.push(l),s[i].map[n]=e,s[i].source+=e+";\n"}),t=(t+="\n").trim(),s.etc=t+"\n",l=e===RedShader.FRAGMENT?"#extension GL_OES_standard_derivatives : enable\n":"",s.precision&&(l+=s.precision.source+"\n//const\n"),s.const&&(l+=s.const.source+"\n//attribute\n"),s.attribute&&(l+=s.attribute.source+"\n//uniform\n"),s.uniform&&(l+=s.uniform.source+"\n//varying\n"),s.varying&&(l+=s.varying.source+"\n//etc\n"),s.etc&&(l+=s.etc),s.lastSource=l,e!==RedShader.FRAGMENT||s.precision||RedGLUtil.throwFunc("RedShader : FRAGMENT Shader는 precision를 반드시 선언해야함"),s},(RedShader=function(i,n,a,o){var s;if(!(this instanceof RedShader))return new RedShader(i,n,a,o);if(i instanceof RedGL||RedGLUtil.throwFunc("RedShader : RedGL Instance만 허용.","입력값 : "+i),"string"==typeof n||RedGLUtil.throwFunc("RedShader : key - 문자열만 허용.","입력값 : "+n),a!==RedShader.VERTEX&&a!==RedShader.FRAGMENT&&RedGLUtil.throwFunc("RedShader : type - RedShader.VERTEX or RedShader.FRAGMENT 만 허용.","입력값 : "+a),i._datas.RedShader||(i._datas.RedShader={},i._datas.RedShader[RedShader.VERTEX]={},i._datas.RedShader[RedShader.FRAGMENT]={}),o)"string"==typeof o||RedGLUtil.throwFunc("RedShader : source - 문자열만 허용."),RedShader.hasKey(i,n,a)?RedGLUtil.throwFunc("RedShader : key - 이미 정의된 키로 생성을 시도.","\n키 :",n,"\n타입 :"+a):i._datas.RedShader[a][n]=this;else{if(RedShader.hasKey(i,n,a))return i._datas.RedShader[a][n];RedGLUtil.throwFunc("RedShader : "+a+" 타입에 존재하지 않는 key를 검색하려고합니다.","입력값 : "+n)}s=i.gl,this.webglShader=e(s,n,a),this.parseData=r(a,o),this.originSource=o,t(s,0,this.webglShader,this.parseData),this.key=n,this.type=a,this._UUID=RedGL.makeUUID(),Object.freeze(this)}).hasKey=function(e,t,r){return!!e._datas.RedShader[r][t]},RedShader.FRAGMENT="fragmentShader",RedShader.VERTEX="vertexShader",Object.freeze(RedShader)}(),function(){var e,t,r,i=[];e=function(t){for(var r,n=i.length;n--;)(r=i[n]).worldRender(r._redGL,t),r._callback&&r._callback(t);requestAnimationFrame(e)},requestAnimationFrame(e),(RedRenderer=function(){if(!(this instanceof RedRenderer))return new RedRenderer;this.world=null,this._tickKey=null,this._callback=null,this._UUID=RedGL.makeUUID(),this.renderInfo={},this.cacheState=[],this.cacheInfo={cacheUniformInfo:[],cacheAttrInfo:[],cacheSamplerIndex:[],cacheTexture:[],cacheSystemUniformInfo:[]},this.renderDebuger=RedRenderDebuger(),this.worldRect=[],this._glInitialized=!1}).prototype={start:function(e,t){e instanceof RedGL||RedGLUtil.throwFunc("RedGL Instance만 허용"),e.world instanceof RedWorld||RedGLUtil.throwFunc("RedWorld Instance만 허용");this.stop(),this.world=e.world,this._redGL=e,this._callback=t,i.push(this)},setDebugButton:function(){var e,t=this;window.document&&(document.body.appendChild(e=document.createElement("button")),e.style.cssText="position:fixed;left:10px;top:10px;background:rgb(91, 82, 170);color:#fff;z-index:10001;border:0;outline:none;cursor:pointer;padding:8px;font-size:11px;border-radius:5px",e.innerHTML="debugRenderInfo - "+RedGL_VERSION.version,e.addEventListener("click",function(){t.renderDebuger.visible=!t.renderDebuger.visible}))},render:function(e,t){e instanceof RedGL||RedGLUtil.throwFunc("RedGL Instance만 허용"),t=t||0,this.world=e.world,this.worldRender(e,t)},stop:function(){-1===(t=i.indexOf(this))||i.splice(t,1)}};var n,a,o,s,d,l,u,c,f,h,R,m,p,_=[],g=[],v=0;l=[],o=function(e){for(u=e.length;u--;)"number"==typeof e[u]?e[u]=e[u]:e[u]=u<2?n[u+2]*parseFloat(e[u])/100:n[u]*parseFloat(e[u])/100;return e},s=function(e,t,i){r=RedSystemUniformUpdater.update(e,this,t,i,r,l)},d=function(e){e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.frontFace(e.CCW),e.enable(e.CULL_FACE),e.cullFace(e.BACK),e.enable(e.SCISSOR_TEST),e.enable(e.BLEND),e.blendFunc(e.SRC_ALPHA,e.ONE_MINUS_SRC_ALPHA),e.disable(e.DITHER),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!1)},RedRenderer.prototype.worldRender=function(e,t){var r,i,u,c,f,h,R,E,M;for(r=e.gl,a=this,window.RedGLTFLoader&&RedGLTFLoader.animationLooper(t),(n=a.worldRect)[0]=0,n[1]=0,n[2]=r.drawingBufferWidth,n[3]=r.drawingBufferHeight,r.viewport(0,0,r.drawingBufferWidth,r.drawingBufferHeight),r.scissor(0,0,r.drawingBufferWidth,r.drawingBufferHeight),r.clear(r.COLOR_BUFFER_BIT|r.DEPTH_BUFFER_BIT),_.length=0,g.length=0,v=0,a._glInitialized||(d(r),a._glInitialized=!0),a.renderInfo={},a.cacheInfo.cacheAttrInfo.length=0,e.gl.activeTexture(e.gl.TEXTURE0),e.gl.bindTexture(e.gl.TEXTURE_2D,e._datas.emptyTexture["2d"].webglTexture),e.gl.activeTexture(e.gl.TEXTURE0+1),e.gl.bindTexture(e.gl.TEXTURE_CUBE_MAP,e._datas.emptyTexture["3d"].webglTexture),h=0,R=a.world._viewList.length;h=U.totalFrame&&(U._loop?(U._playYn=!0,U.currentIndex=0):(U._playYn=!1,U.currentIndex=U.totalFrame-1))}U._sheetRect[0]=1/U._segmentW,U._sheetRect[1]=1/U._segmentH,U._sheetRect[2]=U.currentIndex%U._segmentW/U._segmentW,U._sheetRect[3]=Math.floor(U.currentIndex/U._segmentH)/U._segmentH}for((te=U.program)._prepareProgramYn&&(te=U.program=te._makePrepareProgram()),$e=te.key,$||J?Ke?re=ee&&J?"directionalShadow_fog_sprite3D":ee&&$?"directionalShadow_fog_skin":$?"directionalShadow_skin":J?"directionalShadow_sprite3D":ee?"directionalShadow_fog":"directionalShadow":ee&&J?re="fog_sprite3D":ee&&$?re="fog_skin":$?re="skin":J?re="sprite3D":ee&&(re="fog"):re=ne,(Qe=U._programList)&&re&&((ie=Qe[re][$e])._prepareProgramYn&&(ie=Qe[re][$e]=ie._makePrepareProgram()),te=ie),r!=te._UUID&&et.useProgram(te.webglProgram),r=te._UUID,B=te.attributeLocation,A=te.uniformLocation,S=te.systemUniformLocation,k=w.interleaveBuffer,Y=w.indexBuffer,H=k._UUID,P=B.length,A.length>P&&(P=A.length),D=k.interleaveDefineInfoList,h!=H&&et.bindBuffer(et.ARRAY_BUFFER,k.webglBuffer),h=H;P--;)(F=B[P])&&(G=D[F.name],N=F.location,G&&tt[N]!=G._UUID&&(!F.enabled&&et.enableVertexAttribArray(N),F.enabled=1,et.vertexAttribPointer(N,G.size,k.glArrayType,G.normalize,k.stride_BYTES_PER_ELEMENT,G.offset_BYTES_PER_ELEMENT),tt[N]=G._UUID)),(O=A[P])&&(C=O.location,H=O._UUID,z=O.renderTypeIndex,j=O.renderType,X=U[O.materialPropertyName],z<2?(q=O.samplerIndex,X?nt[q]!=X._UUID&&(R!=q&&et.activeTexture(et.TEXTURE0+(R=q)),X._videoDom?(et.bindTexture(et.TEXTURE_2D,X.webglTexture),X._videoDom.loaded&&et.texImage2D(et.TEXTURE_2D,0,et.RGBA,et.RGBA,et.UNSIGNED_BYTE,X._videoDom),nt=[]):et.bindTexture(0==z?et.TEXTURE_2D:et.TEXTURE_CUBE_MAP,X.webglTexture),it[H]!=q&&et.uniform1iv(C,[it[H]=q]),nt[q]=X._UUID):nt[q]!=z&&(it[H]!=z&&et.uniform1iv(C,[it[H]=z]),nt[q]=z,R=z)):(null==X&&RedGLUtil.throwFunc("RedRenderer : Material에 ",O.materialPropertyName,"이 정의 되지않았습니다."),z<13?rt[H]!=X&&et[O.renderMethod](C,(rt[H]=12==z?null:X,X)):13==z?et[O.renderMethod](C,!1,X):RedGLUtil.throwFunc("RedRenderer : 처리할수없는 타입입니다.","tRenderType -",j)))}if(U&&U._RedMouseEventMaterialYn)w&&et.uniformMatrix4fv(S.uMMatrix.location,!1,V);else if(y.autoUpdateMatrix&&(Re=1,me=0,pe=0,ge=0,ve=1,Ee=0,be=0,Le=0,Te=1,W[12]=y.x,W[13]=y.y*(o?-1:1),W[14]=y.z,W[15]=1,J?ce=fe=he=0:(ce=y.rotationX*x,fe=y.rotationY*x,he=y.rotationZ*x),(je=ce%Ve)<-ze?je+=Ve:je>ze&&(je-=Ve),ae=(je=je<0?Ze*je+We*je*je:Ze*je-We*je*je)<0?.225*(je*-je-je)+je:.225*(je*je-je)+je,(je=(ce+He)%Ve)<-ze?je+=Ve:je>ze&&(je-=Ve),de=(je=je<0?Ze*je+We*je*je:Ze*je-We*je*je)<0?.225*(je*-je-je)+je:.225*(je*je-je)+je,(je=fe%Ve)<-ze?je+=Ve:je>ze&&(je-=Ve),oe=(je=je<0?Ze*je+We*je*je:Ze*je-We*je*je)<0?.225*(je*-je-je)+je:.225*(je*je-je)+je,(je=(fe+He)%Ve)<-ze?je+=Ve:je>ze&&(je-=Ve),le=(je=je<0?Ze*je+We*je*je:Ze*je-We*je*je)<0?.225*(je*-je-je)+je:.225*(je*je-je)+je,(je=he%Ve)<-ze?je+=Ve:je>ze&&(je-=Ve),se=(je=je<0?Ze*je+We*je*je:Ze*je-We*je*je)<0?.225*(je*-je-je)+je:.225*(je*je-je)+je,(je=(he+He)%Ve)<-ze?je+=Ve:je>ze&&(je-=Ve),Ge=le*(ue=(je=je<0?Ze*je+We*je*je:Ze*je-We*je*je)<0?.225*(je*-je-je)+je:.225*(je*je-je)+je),Ae=ae*oe*ue-de*se,Se=de*oe*ue+ae*se,Oe=le*se,Ce=ae*oe*se+de*ue,Ne=de*oe*se-ae*ue,ke=-oe,Ye=ae*le,Xe=de*le,ce=y.scaleX,fe=y.scaleY,he=y.scaleZ,W[0]=(Re*Ge+ge*Ae+be*Se)*ce,W[1]=(me*Ge+ve*Ae+Le*Se)*ce,W[2]=(pe*Ge+Ee*Ae+Te*Se)*ce,W[3]=W[3]*ce,W[4]=(Re*Oe+ge*Ce+be*Ne)*fe,W[5]=(me*Oe+ve*Ce+Le*Ne)*fe,W[6]=(pe*Oe+Ee*Ce+Te*Ne)*fe,W[7]=W[7]*fe,W[8]=(Re*ke+ge*Ye+be*Xe)*he,W[9]=(me*ke+ve*Ye+Le*Xe)*he,W[10]=(pe*ke+Ee*Ye+Te*Xe)*he,W[11]=W[11]*he,(y.pivotX||y.pivotY||y.pivotZ)&&(Re=W[0],me=W[1],pe=W[2],_e=W[3],ge=W[4],ve=W[5],Ee=W[6],Me=W[7],be=W[8],Le=W[9],Te=W[10],Pe=W[11],xe=W[12],ye=W[13],we=W[14],Ue=W[15],Ie=1,Be=0,Fe=0,De=0,W[0]=Ie*Re+Be*ge+Fe*be+De*xe,W[1]=Ie*me+Be*ve+Fe*Le+De*ye,W[2]=Ie*pe+Be*Ee+Fe*Te+De*we,W[3]=Ie*_e+Be*Me+Fe*Pe+De*Ue,Ie=0,Be=1,Fe=0,De=0,W[4]=Ie*Re+Be*ge+Fe*be+De*xe,W[5]=Ie*me+Be*ve+Fe*Le+De*ye,W[6]=Ie*pe+Be*Ee+Fe*Te+De*we,W[7]=Ie*_e+Be*Me+Fe*Pe+De*Ue,Ie=0,Be=0,Fe=1,De=0,W[8]=Ie*Re+Be*ge+Fe*be+De*xe,W[9]=Ie*me+Be*ve+Fe*Le+De*ye,W[10]=Ie*pe+Be*Ee+Fe*Te+De*we,W[11]=Ie*_e+Be*Me+Fe*Pe+De*Ue,o?E?(Ie=-y.pivotX,Be=y.pivotY,Fe=-y.pivotZ,De=1):(Ie=-y.pivotX/ce,Be=y.pivotY/fe,Fe=-y.pivotZ,De=1):(Ie=-y.pivotX,Be=-y.pivotY,Fe=-y.pivotZ,De=1),W[12]=Ie*Re+Be*ge+Fe*be+De*xe,W[13]=Ie*me+Be*ve+Fe*Le+De*ye,W[14]=Ie*pe+Be*Ee+Fe*Te+De*we,W[15]=Ie*_e+Be*Me+Fe*Pe+De*Ue),E?(Re=E[0],me=E[1],pe=E[2],_e=E[3],ge=E[4],ve=E[5],Ee=E[6],Me=E[7],be=E[8],Le=E[9],Te=E[10],Pe=E[11],xe=E[12],ye=E[13],we=E[14],Ue=E[15],Ie=W[0],Be=W[1],Fe=W[2],De=W[3],V[0]=Ie*Re+Be*ge+Fe*be+De*xe,V[1]=Ie*me+Be*ve+Fe*Le+De*ye,V[2]=Ie*pe+Be*Ee+Fe*Te+De*we,V[3]=Ie*_e+Be*Me+Fe*Pe+De*Ue,Ie=W[4],Be=W[5],Fe=W[6],De=W[7],V[4]=Ie*Re+Be*ge+Fe*be+De*xe,V[5]=Ie*me+Be*ve+Fe*Le+De*ye,V[6]=Ie*pe+Be*Ee+Fe*Te+De*we,V[7]=Ie*_e+Be*Me+Fe*Pe+De*Ue,Ie=W[8],Be=W[9],Fe=W[10],De=W[11],V[8]=Ie*Re+Be*ge+Fe*be+De*xe,V[9]=Ie*me+Be*ve+Fe*Le+De*ye,V[10]=Ie*pe+Be*Ee+Fe*Te+De*we,V[11]=Ie*_e+Be*Me+Fe*Pe+De*Ue,Ie=W[12],Be=W[13],Fe=W[14],De=W[15],V[12]=Ie*Re+Be*ge+Fe*be+De*xe,V[13]=Ie*me+Be*ve+Fe*Le+De*ye,V[14]=Ie*pe+Be*Ee+Fe*Te+De*we,V[15]=Ie*_e+Be*Me+Fe*Pe+De*Ue):(V[0]=W[0],V[1]=W[1],V[2]=W[2],V[3]=W[3],V[4]=W[4],V[5]=W[5],V[6]=W[6],V[7]=W[7],V[8]=W[8],V[9]=W[9],V[10]=W[10],V[11]=W[11],V[12]=W[12],V[13]=W[13],V[14]=W[14],V[15]=W[15])),w&&(et.uniformMatrix4fv(S.uMMatrix.location,!1,V),S.uNMatrix.location&&(Re=V[0],me=V[1],pe=V[2],_e=V[3],ge=V[4],ve=V[5],Ee=V[6],Me=V[7],be=V[8],Le=V[9],Te=V[10],Pe=V[11],ye=V[12],we=V[13],Ne=Le*(Ue=V[14])-Te*we,Xe=1/(Xe=(xe=Re*ve-me*ge)*(Ne=Te*(Ie=V[15])-Pe*Ue)-(Be=Re*Ee-pe*ge)*(ke=Le*Ie-Pe*we)+(Fe=Re*Me-_e*ge)*Ne+(De=me*Ee-pe*ve)*(Ce=be*Ie-Pe*ye)-(Ge=me*Me-_e*ve)*(Oe=be*Ue-Te*ye)+(Ae=pe*Me-_e*Ee)*(Se=be*we-Le*ye)),Z[0]=(ve*Ne-Ee*ke+Me*Ne)*Xe,Z[4]=(-me*Ne+pe*ke-_e*Ne)*Xe,Z[8]=(we*Ae-Ue*Ge+Ie*De)*Xe,Z[12]=(-Le*Ae+Te*Ge-Pe*De)*Xe,Z[1]=(-ge*Ne+Ee*Ce-Me*Oe)*Xe,Z[5]=(Re*Ne-pe*Ce+_e*Oe)*Xe,Z[9]=(-ye*Ae+Ue*Fe-Ie*Be)*Xe,Z[13]=(be*Ae-Te*Fe+Pe*Be)*Xe,Z[2]=(ge*ke-ve*Ce+Me*Se)*Xe,Z[6]=(-Re*ke+me*Ce-_e*Se)*Xe,Z[10]=(ye*Ge-we*Fe+Ie*xe)*Xe,Z[14]=(-be*Ge+Le*Fe-Pe*xe)*Xe,Z[3]=(-ge*Ne+ve*Oe-Ee*Se)*Xe,Z[7]=(Re*Ne-me*Oe+pe*Se)*Xe,Z[11]=(-ye*De+we*Be-Ue*xe)*Xe,Z[15]=(be*De-Le*Be+Te*xe)*Xe,et.uniformMatrix4fv(S.uNMatrix.location,!1,Z))),$){var st,dt=$.joints,lt=0,ut=dt.length,ct=new Float32Array(16*ut),ft=[V[0],V[1],V[2],V[3],V[4],V[5],V[6],V[7],V[8],V[9],V[10],V[11],V[12],V[13],V[14],V[15]],ht=ft,Rt=ft[0],mt=ft[1],pt=ft[2],_t=ft[3],gt=ft[4],vt=ft[5],Et=ft[6],Mt=ft[7],bt=ft[8],Lt=ft[9],Tt=ft[10],Pt=ft[11],xt=ft[12],yt=ft[13],wt=ft[14],Ut=ft[15],It=Lt*wt*Mt-yt*Tt*Mt+yt*Et*Pt-vt*wt*Pt-Lt*Et*Ut+vt*Tt*Ut,Bt=xt*Tt*Mt-bt*wt*Mt-xt*Et*Pt+gt*wt*Pt+bt*Et*Ut-gt*Tt*Ut,Ft=bt*yt*Mt-xt*Lt*Mt+xt*vt*Pt-gt*yt*Pt-bt*vt*Ut+gt*Lt*Ut,Dt=xt*Lt*Et-bt*yt*Et-xt*vt*Tt+gt*yt*Tt+bt*vt*wt-gt*Lt*wt,Gt=Rt*It+mt*Bt+pt*Ft+_t*Dt;if(0===Gt)return mat4.identity(ft);var At=1/Gt;for(ht[0]=It*At,ht[1]=(yt*Tt*_t-Lt*wt*_t-yt*pt*Pt+mt*wt*Pt+Lt*pt*Ut-mt*Tt*Ut)*At,ht[2]=(vt*wt*_t-yt*Et*_t+yt*pt*Mt-mt*wt*Mt-vt*pt*Ut+mt*Et*Ut)*At,ht[3]=(Lt*Et*_t-vt*Tt*_t-Lt*pt*Mt+mt*Tt*Mt+vt*pt*Pt-mt*Et*Pt)*At,ht[4]=Bt*At,ht[5]=(bt*wt*_t-xt*Tt*_t+xt*pt*Pt-Rt*wt*Pt-bt*pt*Ut+Rt*Tt*Ut)*At,ht[6]=(xt*Et*_t-gt*wt*_t-xt*pt*Mt+Rt*wt*Mt+gt*pt*Ut-Rt*Et*Ut)*At,ht[7]=(gt*Tt*_t-bt*Et*_t+bt*pt*Mt-Rt*Tt*Mt-gt*pt*Pt+Rt*Et*Pt)*At,ht[8]=Ft*At,ht[9]=(xt*Lt*_t-bt*yt*_t-xt*mt*Pt+Rt*yt*Pt+bt*mt*Ut-Rt*Lt*Ut)*At,ht[10]=(gt*yt*_t-xt*vt*_t+xt*mt*Mt-Rt*yt*Mt-gt*mt*Ut+Rt*vt*Ut)*At,ht[11]=(bt*vt*_t-gt*Lt*_t-bt*mt*Mt+Rt*Lt*Mt+gt*mt*Pt-Rt*vt*Pt)*At,ht[12]=Dt*At,ht[13]=(bt*yt*pt-xt*Lt*pt+xt*mt*Tt-Rt*yt*Tt-bt*mt*wt+Rt*Lt*wt)*At,ht[14]=(xt*vt*pt-gt*yt*pt-xt*mt*Et+Rt*yt*Et+gt*mt*wt-Rt*vt*wt)*At,ht[15]=(gt*Lt*pt-bt*vt*pt+bt*mt*Et-Rt*Lt*Et-gt*mt*Tt+Rt*vt*Tt)*At;lt mode2DYn - '+t[a].mode2DYn+'
call - '+t[a].call+'
triangleNum - '+t[a].triangleNum+'
width - '+t[a].width+' / height - '+t[a].height+'
viewRectWidth - '+t[a].viewRectWidth+' / viewRectHeight - '+t[a].viewRectHeight+'
x - '+t[a].x+' / y - '+t[a].y+'
renderTime
viewRenderTime - '+t[a].viewRenderTime.toFixed(2)+'ms
baseRenderTime - '+(t[a].viewRenderTime-t[a].postEffectRenderTime).toFixed(2)+'ms
postEffectRenderTime - '+t[a].postEffectRenderTime.toFixed(2)+"ms
",i+=t[a].viewRenderTime,n+=t[a].postEffectRenderTime;r+='
',r+='
renderScale : '+e.renderScale+"
",r+='
totalRenderTime : '+i.toFixed(2)+"ms
",r+='
baseRenderTime : '+(i-n).toFixed(2)+"ms
",r+='
postEffectRenderTime : '+n.toFixed(2)+"ms
",r+="
",this._contentBox.innerHTML=r}}},Object.defineProperty(RedRenderDebuger.prototype,"visible",{get:function(){return this._visible},set:function(e){this._visible=e,window.HTMLCanvasElement&&(this._visible?document.body.appendChild(this.renderResult):this.renderResult.parentNode&&document.body.removeChild(this.renderResult))}}),Object.freeze(RedRenderDebuger),function(){var e,t,r,i,n,a,o,s,d,l,u,c,f,h,R,m,p,_,g,v,E,M,b,L,T,P,x,y,w,U,I,B,F,D,G,A,S,O,C,N;RedSystemUniformUpdater={update:(N=0,E=new Float32Array(3),function(k,Y,X,j,z,V){for(e!=k&&(L=null),e=k,L||(S=RedSystemShaderCode.MAX_DIRECTIONAL_LIGHT,O=RedSystemShaderCode.MAX_POINT_LIGHT,L={uTime:{cacheData:null,data:0},uResolution:{cacheData:null,data:new Float32Array([0,0])},u_FogDensity:{cacheData:null,data:0},uFogColor:{cacheData:null,data:new Float32Array([0,0,0,0])},u_FogDistance:{cacheData:null,data:0},uCameraMatrix:{cacheData:null,data:null},uCameraPosition:{cacheData:null,data:new Float32Array([0,0,0])},uPMatrix:{cacheData:null,data:null},uMode2DYn:{cacheData:null,data:!1},uAmbientLightColor:{cacheData:null,data:new Float32Array([0,0,0,0])},uAmbientIntensity:{cacheData:null,data:1},uDirectionalLightPositionList:{cacheData:null,data:[]},uDirectionalLightColorList:{cacheData:null,data:[]},uDirectionalLightIntensityList:{cacheData:null,data:[]},uDirectionalLightNum:{cacheData:null,data:0},uPointLightPositionList:{cacheData:null,data:[]},uPointLightColorList:{cacheData:null,data:[]},uPointLightIntensityList:{cacheData:null,data:[]},uPointLightRadiusList:{cacheData:null,data:[]},uPointLightNum:{cacheData:null,data:0}},w=new Float32Array(3),P=new Float32Array(16),y=new Float32Array(16),l=new Float32Array(3*S),u=new Float32Array(4*S),c=new Float32Array(S),f=new Float32Array(3*O),h=new Float32Array(4*O),R=new Float32Array(O),m=new Float32Array(O)),t=k.gl,F=j.scene,D=(D=j.camera)instanceof RedBaseController?D.camera:D,G=j._viewRect,B=Y.cacheInfo.cacheSystemUniformInfo,I=null,T={},V.length=0,A=N!=k._datas.RedProgramList.length,N=0,(C=L.uTime).cacheData!=X&&(T.uTime=C.data=X,C.cacheData=X),d=JSON.stringify(G),((C=L.uResolution).cacheData!=d||A)&&(C.data[0]=G[2],C.data[1]=G[3],T.uResolution=C.data,C.cacheData=d),d=F._fogDensity,((C=L.u_FogDensity).cacheData!=d||A)&&(T.u_FogDensity=C.data=d,C.cacheData=d),d=F._fogR+"_"+F._fogG+"_"+F._fogB+"_1",((C=L.uFogColor).cacheData!=d||A)&&(C.data[0]=F._fogR,C.data[1]=F._fogG,C.data[2]=F._fogB,C.data[3]=1,T.uFogColor=C.data,C.cacheData=d),d=F._fogDistance,((C=L.u_FogDistance).cacheData!=d||A)&&(T.u_FogDistance=C.data=d,C.cacheData=d),d=JSON.stringify(D.matrix),((C=L.uCameraMatrix).cacheData!=d||A)&&(T.uCameraMatrix=C.data=D.matrix,C.cacheData=d),d=D.camera?[D.camera.x,D.camera.y,D.camera.z]:[D.x,D.y,D.z],((C=L.uCameraPosition).cacheData!=d.join(",")||A)&&(T.uCameraPosition=C.data=d,C.cacheData=d.join(",")),d=JSON.stringify(D.mode2DYn),((C=L.uMode2DYn).cacheData!=d||A)&&(T.uMode2DYn=C.data=D.mode2DYn,C.cacheData=d),d=JSON.stringify(D.perspectiveMTX),((C=L.uPMatrix).cacheData!=d||A)&&(T.uPMatrix=C.data=D.perspectiveMTX,C.cacheData=d),(g=F._lightInfo[RedAmbientLight.TYPE])&&(d=JSON.stringify(g._lightColor),((C=L.uAmbientLightColor).cacheData!=d||A)&&(T.uAmbientLightColor=C.data=[g._lightColor[0],g._lightColor[1],g._lightColor[2],g._lightColor[3]],C.cacheData=d,T.uAmbientLightColor[0]*=T.uAmbientLightColor[3],T.uAmbientLightColor[1]*=T.uAmbientLightColor[3],T.uAmbientLightColor[2]*=T.uAmbientLightColor[3]),d=g._intensity,((C=L.uAmbientIntensity).cacheData!=d||A)&&(T.uAmbientIntensity=C.data=g._intensity,C.cacheData=d)),p=F._lightInfo[RedDirectionalLight.TYPE],M=p.length;M--;)g=p[M],E[0]=g.x,E[1]=g.y,E[2]=g.z,g.debug&&((v=g._debugObject).x=E[0],v.y=E[1],v.z=E[2],v._material._color=g._lightColor,V.push(v)),vec3.normalize(E,E),l[0+3*M]=E[0],l[1+3*M]=E[1],l[2+3*M]=E[2],u[0+4*M]=g._lightColor[0]*g._lightColor[3],u[1+4*M]=g._lightColor[1]*g._lightColor[3],u[2+4*M]=g._lightColor[2]*g._lightColor[3],u[3+4*M]=g._lightColor[3],c[M]=g._intensity;for(d=JSON.stringify(l),((C=L.uDirectionalLightPositionList).cacheData!=d||A)&&(T.uDirectionalLightPositionList=C.data=l,C.cacheData=d),d=JSON.stringify(u),((C=L.uDirectionalLightColorList).cacheData!=d||A)&&(T.uDirectionalLightColorList=C.data=u,C.cacheData=d),d=JSON.stringify(c),((C=L.uDirectionalLightIntensityList).cacheData!=d||A)&&(T.uDirectionalLightIntensityList=C.data=c,C.cacheData=d),d=p.length,((C=L.uDirectionalLightNum).cacheData!=d||A)&&(T.uDirectionalLightNum=C.data=d,C.cacheData=d),p=F._lightInfo[RedPointLight.TYPE],M=p.length;M--;)g=p[M],E[0]=g.x,E[1]=g.y,E[2]=g.z,g.debug&&((v=g._debugObject).x=E[0],v.y=E[1],v.z=E[2],v.scaleX=v.scaleY=v.scaleZ=g._radius,v._material._color=g._lightColor,V.push(v)),f[0+3*M]=E[0],f[1+3*M]=E[1],f[2+3*M]=E[2],h[0+4*M]=g._lightColor[0]*g._lightColor[3],h[1+4*M]=g._lightColor[1]*g._lightColor[3],h[2+4*M]=g._lightColor[2]*g._lightColor[3],h[3+4*M]=g._lightColor[3],R[M]=g._intensity,m[M]=g._radius;for(d=JSON.stringify(f),((C=L.uPointLightPositionList).cacheData!=d||A)&&(T.uPointLightPositionList=C.data=f,C.cacheData=d),d=JSON.stringify(h),((C=L.uPointLightColorList).cacheData!=d||A)&&(T.uPointLightColorList=C.data=h,C.cacheData=d),d=JSON.stringify(R),((C=L.uPointLightIntensityList).cacheData!=d||A)&&(T.uPointLightIntensityList=C.data=R,C.cacheData=d),d=JSON.stringify(m),((C=L.uPointLightRadiusList).cacheData!=d||A)&&(T.uPointLightRadiusList=C.data=m,C.cacheData=d),d=p.length,((C=L.uPointLightNum).cacheData!=d||A)&&(T.uPointLightNum=C.data=d,C.cacheData=d),F.shadowManager._directionalShadow&&(P[1]=P[2]=P[3]=P[4]=P[6]=P[7]=P[8]=P[9]=P[11]=P[12]=P[13]=P[14]=0,P[0]=P[5]=P[10]=P[15]=1,x=F.shadowManager._directionalShadow.size,_=F.shadowManager._directionalShadow._light,mat4.ortho(y,-x,x,-x,x,-x,x),w[0]=0,w[1]=0,w[2]=0,_&&(w[0]=_.x,w[1]=_.y,w[2]=_.z,vec3.normalize(w,w),mat4.lookAt(P,w,[0,0,0],[0,1,0]),mat4.multiply(P,y,P))),M=k._datas.RedProgramList.length;M--;)for(b in N++,r=k._datas.RedProgramList[M],t.useProgram(r.webglProgram),z=r._UUID,i=r.systemUniformLocation,n=i.uDirectionalShadowLightMatrix,a=n.location,o=n._UUID,a&&F.shadowManager._directionalShadow&&(_=F.shadowManager._directionalShadow._light)&&(d=JSON.stringify(P),B[o]!=d&&(t.uniformMatrix4fv(a,!1,P),B[o]=d)),(n=i.uDirectionalShadowTexture)&&(a=n.location)&&(o=n._UUID,s=F.shadowManager._directionalShadow?F.shadowManager.directionalShadow.frameBuffer.texture:k._datas.emptyTexture["2d"],(U=n.samplerIndex)!=I&&(t.activeTexture(t.TEXTURE0+U),t.bindTexture(t.TEXTURE_2D,s.webglTexture),t[n.renderMethod](a,U)),I=U),T)n=i[b],(a=n.location)&&(o=n._UUID,s=T[b],"mat"==n.renderType?t[n.renderMethod](a,!1,s):t[n.renderMethod](a,s),B[o]=null);return z})},Object.freeze(RedSystemUniformUpdater)}(),(RedView=function(e,t,r){if(!(this instanceof RedView))return new RedView(e,t,r);!t||t instanceof RedScene||RedGLUtil.throwFunc("RedView : RedScene Instance만 허용","입력값 : "+t),r?!r||r instanceof RedCamera||r instanceof RedBaseController||RedGLUtil.throwFunc("RedView : RedCamera or XXController Instance만 허용"):RedGLUtil.throwFunc("RedView : RedCamera or XXController Instance만 허용","입력값 : "+r),this.scene=t,this.postEffectManager=RedPostEffectManager(e),this.camera=r,this._width="100%",this._height="100%",this._x=0,this._y=0,this._viewRect=[0,0,0,0],this._UUID=RedGL.makeUUID()}).prototype={setSize:function(e,t){null==e&&RedGLUtil.throwFunc("RedView setSize : width가 입력되지 않았습니다."),null==t&&RedGLUtil.throwFunc("RedView setSize : height가 입력되지 않았습니다."),"number"==typeof e?this._width=e<0?0:e:e.indexOf("%")>-1&&+e.replace("%","")>=0?this._width=e:RedGLUtil.throwFunc("RedView setSize : width는 0이상의 숫자나 %만 허용.",e),"number"==typeof t?this._height=t<0?0:t:t.indexOf("%")>-1&&+t.replace("%","")>=0?this._height=t:RedGLUtil.throwFunc("RedView setSize : height는 0이상의 숫자나 %만 허용.",t)},setLocation:function(e,t){null==e&&RedGLUtil.throwFunc("RedView setLocation : x가 입력되지 않았습니다."),null==t&&RedGLUtil.throwFunc("RedView setLocation : y가 입력되지 않았습니다."),"number"==typeof e?this._x=e<0?0:e:e.indexOf("%")>-1&&+e.replace("%","")>=0?this._x=e:RedGLUtil.throwFunc("RedView setLocation : x는 0이상의 숫자나 %만 허용.",e),"number"==typeof t?this._y=t<0?0:t:t.indexOf("%")>-1&&+t.replace("%","")>=0?this._y=t:RedGLUtil.throwFunc("RedView setLocation : y는 0이상의 숫자나 %만 허용.",t)}},Object.freeze(RedView),function(){var e,t;(RedWorld=function(){if(!(this instanceof RedWorld))return new RedWorld;this._viewList=[],this._viewMap={},this._UUID=RedGL.makeUUID()}).prototype={addView:function(e,t){e instanceof RedView||RedGLUtil.throwFunc("RedWorld :addView Instance만 허용함.","입력값 : "+e),t&&(this._viewMap[t]?RedGLUtil.throwFunc("RedWorld :key 중복","입력값 : "+t):this._viewMap[t]=e),this._viewList.push(e)},getView:function(e){return"string"==typeof e||RedGLUtil.throwFunc("RedWorld :getView 문자열만 허용함.","입력값 : "+e),this._viewMap[e]},delView:function(r){if("string"==typeof r||r instanceof RedView||RedGLUtil.throwFunc("RedWorld :delView 문자열이나 RedView 만 허용함.","입력값 : "+r),"string"==typeof r)(e=this._viewMap[r])&&(t=this._viewList.indexOf(e),this._viewList.splice(t,1),delete this._viewMap[r]);else for(var i in t=this._viewList.indexOf(r),this._viewList.splice(t,1),this._viewMap)this._viewMap[i]==r&&delete this._viewMap[i]},hasView:function(e){if("string"==typeof e||e instanceof RedView||RedGLUtil.throwFunc("RedWorld :hasView 문자열이나 RedView 만 허용함.","입력값 : "+e),"string"==typeof e)return!!this._viewMap[e];var t=this._viewList.indexOf(e);return!!this._viewList[t]},getViewList:function(){return this._viewList.concat()}},Object.freeze(RedWorld)}(),function(){RedScene=function(e,t){if(!(this instanceof RedScene))return new RedScene(e,t);e instanceof RedGL||RedGLUtil.throwFunc("RedScene : RedGL Instance만 허용.",e),this.backgroundColor=t||"#000000",this.useBackgroundColor=!0,this.useFog=!1,this.fogDensity=.5,this.fogDistance=25,this.fogColor="#ffffff",this.children=[],this.shadowManager=RedShadowManager(e),this.mouseManager=RedMouseEventManager(e),this._lightInfo={RedAmbientLight:null,RedDirectionalLight:[],RedPointLight:[]},this._UUID=RedGL.makeUUID()};var e,t,r={addLight:function(e){switch(e.TYPE){case RedAmbientLight.TYPE:this._lightInfo[e.TYPE]=e;break;case RedDirectionalLight.TYPE:this._lightInfo[e.TYPE].length===RedSystemShaderCode.MAX_DIRECTIONAL_LIGHT&&RedGLUtil.throwFunc("RedScene : RedDirectionalLight "+RedSystemShaderCode.MAX_DIRECTIONAL_LIGHT+"개 까지 허용."),this._lightInfo[e.TYPE].push(e);break;case RedPointLight.TYPE:this._lightInfo[e.TYPE].length===RedSystemShaderCode.MAX_POINT_LIGHT&&RedGLUtil.throwFunc("RedScene : RedPointLight "+RedSystemShaderCode.MAX_POINT_LIGHT+"개 까지 허용."),this._lightInfo[e.TYPE].push(e);break;default:RedGLUtil.throwFunc("RedScene : RedBaseLight 인스턴스만 가능")}},removeLight:function(t){switch(t.TYPE){case RedAmbientLight.TYPE:this._lightInfo[t.TYPE]===t&&(this._lightInfo[t.TYPE]=null);break;case RedDirectionalLight.TYPE:case RedPointLight.TYPE:(e=this._lightInfo[t.TYPE].indexOf(t))>-1&&this._lightInfo[t.TYPE].splice(e,1);break;default:RedGLUtil.throwFunc("RedScene : RedBaseLight 인스턴스만 가능")}},removeLightAll:function(){this._lightInfo[RedAmbientLight.TYPE]=null,this._lightInfo[RedDirectionalLight.TYPE].length=0,this._lightInfo[RedPointLight.TYPE].length=0}};for(var i in RedScene.prototype=new RedBaseContainer,r)RedScene.prototype[i]=r[i];RedDefinePropertyInfo.definePrototype("RedScene","backgroundColor","hex",{callback:function(){t=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._backgroundColor),this._r=t[0],this._g=t[1],this._b=t[2]}}),RedDefinePropertyInfo.definePrototype("RedScene","useBackgroundColor","boolean"),RedDefinePropertyInfo.definePrototype("RedScene","useFog","boolean"),RedDefinePropertyInfo.definePrototype("RedScene","fogDensity","number",{min:0}),RedDefinePropertyInfo.definePrototype("RedScene","fogDistance","number",{min:0}),RedDefinePropertyInfo.definePrototype("RedScene","fogColor","hex",{callback:function(){var e;return function(){e=RedGLUtil.hexToRGB_ZeroToOne.call(this,this._fogColor),this._fogR=e[0],this._fogG=e[1],this._fogB=e[2]}}()}),Object.defineProperty(RedScene.prototype,"skyBox",{get:function(){return this._skyBoxMesh},set:function(e){return!e||e instanceof RedSkyBox||RedGLUtil.throwFunc("RedScene : RedSkyBox Instance만 허용."),this._skyBoxMesh=e,this._skyBoxMesh}}),Object.defineProperty(RedScene.prototype,"grid",{get:function(){return this._gridMesh},set:function(e){return!e||e instanceof RedGrid||RedGLUtil.throwFunc("RedScene : RedGrid Instance만 허용."),this._gridMesh=e,this._gridMesh}}),Object.defineProperty(RedScene.prototype,"axis",{get:function(){return this._axisMesh},set:function(e){return!e||e instanceof RedAxis||RedGLUtil.throwFunc("RedScene : RedAxis Instance만 허용."),this._axisMesh=e,this._axisMesh}}),Object.freeze(RedScene)}(),function(){var e,t;(RedCamera=function(){if(!(this instanceof RedCamera))return new RedCamera;this.x=this.y=this.z=0,this.targetX=this.targetY=this.targetZ=0,this.fov=60,this.nearClipping=.1,this.farClipping=1e5,this.mode2DYn=!1,this.matrix=mat4.create(),this.perspectiveMTX=mat4.create(),this.autoUpdateMatrix=!0,this._UUID=RedGL.makeUUID()}).prototype.update=function(){this.lookAt(this.targetX,this.targetY,this.targetZ)},RedCamera.prototype.lookAt=(e=new Float32Array([0,1,0]),t=[],function(r,i,n){t[0]=this.targetX=r,t[1]=this.targetY=i,t[2]=this.targetZ=n,mat4.identity(this.matrix),mat4.lookAt(this.matrix,[this.x,this.y,this.z],t,e)}),Object.freeze(RedCamera)}(),(RedBasicController=function(e){if(!(this instanceof RedBasicController))return new RedBasicController(e);this.targetView=null,this.keyBuffer={},this.keyNameMapper={moveForward:"w",moveBack:"s",moveLeft:"a",moveRight:"d",moveUp:"t",moveDown:"g",turnLeft:"q",turnRight:"e",turnUp:"r",turnDown:"f"},this.speed=1,this.delay=.1,this.speedRotation=1,this.delayRotation=.1,this.maxAcceleration=3,this._currentAcceleration=0,this.camera=RedCamera(),this._desirePosition=[0,0,0],this._desirePan=0,this._desireTilt=0,this._targetObject=RedMesh(e),function(t){var r,i,n,a,o,s,d,l,u,c,f,h,R,m,p;"ie"==RedGLDetect.BROWSER_INFO.browser&&11==RedGLDetect.BROWSER_INFO.browserVer?(R="offsetX",m="offsetY"):(R="layerX",m="layerY"),p=function(r){if(r||((r={clientX:e._mouseX,clientY:e._mouseY})[R]=e._mouseX,r[m]=e._mouseY),t.targetView){var i,n;if(RedGLDetect.BROWSER_INFO.isMobile?(i=r.clientX,n=r.clientY):(i=r[R],n=r[m]),!(t.targetView._viewRect[0]this._maxAcceleration&&(this._currentAcceleration=this._maxAcceleration)):(this._currentAcceleration+=-.1,this._currentAcceleration<0&&(this._currentAcceleration=0)),r=this._targetObject,n&&(this._desirePan+=e,this._desireTilt+=t),r.rotationY+=(this._desirePan-r.rotationY)*d,r.rotationX+=(this._desireTilt-r.rotationX)*d,(i||n)&&(l=r.matrix,mat4.identity(c),mat4.rotateY(c,c,r.rotationY*Math.PI/180),mat4.rotateX(c,c,r.rotationX*Math.PI/180),mat4.translate(c,c,f),mat4.identity(l),mat4.translate(l,l,[r.x,r.y,r.z]),mat4.multiply(l,l,c),p[0]=l[12],p[1]=l[13],p[2]=l[14]),r.x+=(p[0]-r.x)*s,r.y+=(p[1]-r.y)*s,r.z+=(p[2]-r.z)*s,r.rotationY+=(this._desirePan-r.rotationY)*d,r.rotationX+=(this._desireTilt-r.rotationX)*d,l=r.matrix,mat4.identity(l),mat4.translate(l,l,[r.x,r.y,r.z]),mat4.rotateY(l,l,r.rotationY*Math.PI/180),mat4.rotateX(l,l,r.rotationX*Math.PI/180),u=mat4.clone(l),mat4.translate(u,u,[0,0,.01]),h.x=u[12],h.y=u[13],h.z=u[14],h.lookAt(r.x,r.y,r.z)}}(),Object.freeze(RedBasicController),function(){var e,t,r,i;(RedObitController=function(e){if(!(this instanceof RedObitController))return new RedObitController(e);this.centerX=0,this.centerY=0,this.centerZ=0,this.distance=15,this.speedDistance=2,this.delayDistance=.1,this.speedRotation=3,this.delayRotation=.1,this.tilt=0,this.minTilt=-90,this.maxTilt=90,this.pan=0,this.camera=RedCamera(),this._currentPan=0,this._currentTilt=0,this._currentDistance=0,this.needUpdate=!0,this.targetView=null,function(t){var r,i,n,a,o,s,d,l,u,c,f,h,R,m;h=function(e){if(t.targetView){var r,i;if(RedGLDetect.BROWSER_INFO.isMobile?(r=e.clientX,i=e.clientY):(r=e[R],i=e[m]),!(t.targetView._viewRect[0]this._maxTilt&&(this._tilt=this._maxTilt),e=this._delayRotation,t=this.camera,r=t.matrix,this._currentPan+=(this._pan-this._currentPan)*e,this._currentTilt+=(this._tilt-this._currentTilt)*e,this._currentDistance+=(this._distance-this._currentDistance)*this._delayDistance,mat4.identity(r),mat4.translate(r,r,[this._centerX,this._centerY,this._centerZ]),mat4.rotateY(r,r,this._currentPan*i),mat4.rotateX(r,r,this._currentTilt*i),mat4.translate(r,r,[0,0,this._currentDistance]),t.x=r[12],t.y=r[13],t.z=r[14],t.lookAt(this._centerX,this._centerY,this._centerZ))}),Object.freeze(RedObitController)}(),function(){var e,t,r;e=function(){ /* @preserve void main(void) { vVertexColor = aVertexColor; @@ -1031,7 +1108,7 @@ uniform sampler2D u_diffuseTexture; void main(void) { gl_FragColor = texture2D(u_diffuseTexture, vTexcoord); } -*/},(RedPostEffectMaterial=function(i,n){if(!(this instanceof RedPostEffectMaterial))return new RedPostEffectMaterial(i,n);i instanceof RedGL||RedGLUtil.throwFunc("RedPostEffectMaterial : RedGL Instance만 허용.",i),this.diffuseTexture=n,this.program=RedProgram.makeProgram(i,"RedPostEffectMaterialProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseMaterial,RedDefinePropertyInfo.definePrototype("RedPostEffectMaterial","diffuseTexture","sampler2D",{essential:!0}),Object.freeze(RedPostEffectMaterial)}(),function(){var e;(RedDirectionalShadow=function(e,t){if(!(this instanceof RedDirectionalShadow))return new RedDirectionalShadow(e,t);e instanceof RedGL||RedGLUtil.throwFunc("RedDirectionalShadow : RedGL Instance만 허용.",e),this._directionalShadowMaterial=RedDirectionalShadowMaterial(e),this.frameBuffer=RedFrameBuffer(e),this.light=t,this.width=2048,this.height=2048,this.size=20,this._UUID=RedGL.makeUUID(),this._castingList=[]}).prototype.addCasting=function(e){e instanceof RedBaseObject3D||RedGLUtil.throwFunc("addCasting","RedBaseObject3D Instance만 가능","입력값 : "+e),this._castingList.push(e)},RedDirectionalShadow.prototype.removeCasting=function(t){-1==(e=this._castingList.indexOf(t))?RedGLUtil.throwFunc("removeCasting","존재하지 않는 대상을 삭제하려고 함"):this._castingList.splice(e,1)},Object.defineProperty(RedDirectionalShadow.prototype,"light",{get:function(){return this._light},set:function(e){e&&e instanceof RedDirectionalLight||RedGLUtil.throwFunc("RedDirectionalShadow - light : RedDirectionalLight Instance만 허용.",e),this._light=e}}),RedDefinePropertyInfo.definePrototypes("RedDirectionalShadow",["width","number",{min:1}],["height","number",{min:1}],["size","number",{min:1}]),Object.freeze(RedDirectionalShadow)}(),function(){var e,t,r,i,n,a;(RedShadowManager=function(e){if(!(this instanceof RedShadowManager))return new RedShadowManager(e);e instanceof RedGL||RedGLUtil.throwFunc("RedShadowManager : RedGL Instance만 허용.",e),this._UUID=RedGL.makeUUID()}).prototype={render:function(o,s,d,u,c){(i=this._directionalShadow)&&(e=o.gl,r=s.worldRect,t=d._viewRect,n=i.width,a=i.height,i.frameBuffer.width=n,i.frameBuffer.height=a,i.frameBuffer.bind(o.gl),e.viewport(0,0,n,a),e.scissor(0,0,n,a),e.clearColor(0,0,0,1),e.clearDepth(1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),s.sceneRender(o,d.scene,d.camera,d.camera.mode2DYn,i._castingList,u,c,i._directionalShadowMaterial),i.frameBuffer.unbind(o.gl),e.viewport(t[0],r[3]-t[3]-t[1],t[2],t[3]),e.scissor(t[0],r[3]-t[3]-t[1],t[2],t[3]))}},Object.defineProperty(RedShadowManager.prototype,"directionalShadow",{get:function(){return this._directionalShadow},set:function(e){!e||e instanceof RedDirectionalShadow||RedGLUtil.throwFunc("RedShadowManager - directionalShadow : RedDirectionalShadow Instance만 허용.",e),this._directionalShadow=e}}),Object.freeze(RedShadowManager)}(),function(){var e,t,r,i;t=function(t,r,i){var n;n=t._svg.querySelector("td").style,t["_"+r]=i,Object.defineProperty(t,r,{get:function(){return t["_"+r]},set:function(i){t["_"+r]=i,n[r]="number"==typeof i?i+="px":i,e(t)}}),t[r]=i},e=function(e){e._height=+e._height,e._svg.setAttribute("width",e._width),e._svg.setAttribute("height",e._height),e._svg.querySelector("foreignObject").setAttribute("height",e._height),e._svg.querySelector("table").style.height=e._height+"px",e._img.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(e._svg.outerHTML)},(RedText=function(e,r,i){if(!(this instanceof RedText))return new RedText(e,r,i);e instanceof RedGL||RedGLUtil.throwFunc("RedText : RedGL Instance만 허용.",e),RedBaseObject3D.build.call(this,e.gl);var n=this;this._cvs=null,this._ctx=null,this._svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this._svg.setAttribute("xmlns","http://www.w3.org/2000/svg"),this._svg.style="position:absolute;top:0px;left:0px;text-align:center;z-index:10",this._svg.innerHTML='
',this.geometry=RedPlane(e,1,1),this.material=RedTextMaterial(e,RedBitmapTexture(e,this._cvs)),this.blendSrc=e.gl.ONE,this.blendDst=e.gl.ONE_MINUS_SRC_ALPHA,this.useCullFace=!1,this.perspectiveScale=!0,this.sprite3DYn=!1,this._img=new Image,i=i||256,(r=r||256)>e.detect.texture.MAX_TEXTURE_SIZE&&(r=e.detect.texture.MAX_TEXTURE_SIZE),i>e.detect.texture.MAX_TEXTURE_SIZE&&(i=e.detect.texture.MAX_TEXTURE_SIZE),this.width=r,this.height=i,t(this,"padding",0),t(this,"background",""),t(this,"color","#000"),t(this,"fontFamily","Arial"),t(this,"fontSize",16),t(this,"fontWeight","normal"),t(this,"fontStyle","normal"),t(this,"lineHeight",24),t(this,"letterSpacing",0),t(this,"wordBreak","break-all"),t(this,"verticalAlign","middle"),t(this,"textAlign","center"),this._img.onload=function(){var t,r;(t=n._width)%2==0&&(t+=1),(r=n._height)%2==0&&(r+=1),n._cvs=window.OffscreenCanvas?new OffscreenCanvas(t,r):document.createElement("canvas"),n._ctx=n._cvs.getContext("2d"),n._cvs.width=t,n._cvs.height=r,n._ctx.clearRect(0,0,t,r),n._ctx.drawImage(n._img,0,0,t,r),n.material.width=t,n.material.height=r,n.material.diffuseTexture.src=n._cvs,n.material.diffuseTexture.option={min:e.gl.LINEAR,mag:e.gl.LINEAR,wrap_s:e.gl.CLAMP_TO_EDGE,wrap_t:e.gl.CLAMP_TO_EDGE}},this.useTransparentSort=!0,this._UUID=RedGL.makeUUID()}).prototype=new RedBaseObject3D,RedDefinePropertyInfo.definePrototypes("RedText",["perspectiveScale","boolean"],["sprite3DYn","boolean"],["width","uint",{min:2,callback:function(t){this._width=t,this.material.width=t,e(this)}}],["height","uint",{min:2,callback:function(t){this._height=t,this.material.height=t,e(this)}}]),Object.defineProperty(RedText.prototype,"text",{get:function(){return this._text},set:function(t){r=this._svg,i=r.querySelector("foreignObject td"),this._text=t.replace(/\/gi,"
");var n=this,a=this._text.match(//g),o=[],s=this._text,d=(a=a||[]).length,u=0;a.forEach(function(t){var r=t.match(/src\s*=\s*(\'|\").*?(\'|\")/g)[0];r=r.replace(/src\s*=\s*(\'|\")/g,"").replace(/(\'|\")/g,"");var a=document.createElement("div");a.innerHTML=t;var c=a.querySelector("img");c.onload=function(){var t=document.createElement("canvas");t.width=c.style.width?+c.style.width:c.width,t.height=c.style.height?+c.style.height:c.height;var r=t.getContext("2d");r.scale(t.width/c.naturalWidth,t.height/c.naturalHeight),r.drawImage(c,0,0),l.result='',++u==d&&(o.forEach(function(e){s=s.replace(e.source,e.result)}),i.innerHTML=s,e(n)),c.onload=null};var l={source:t,sourceSrc:r,result:""};o.push(l)}),0==a.length&&(i.innerHTML=s,e(this))}}),Object.freeze(RedText)}(),function(){var e,t,r,i,n,a,o,s,d;(RedMouseEventManager=function(e){if(!(this instanceof RedMouseEventManager))return new RedMouseEventManager(e);e instanceof RedGL||RedGLUtil.throwFunc("RedMouseEventManager : RedGL Instance만 허용.",e),this.frameBuffer=RedFrameBuffer(e),this._mouseEventMaterial=RedMouseEventMaterial(e),this._mouseEventListObject={},this._mouseEventList=[],this._prevInfo={},this._UUID=RedGL.makeUUID()}).prototype={add:function(e,t,r){var i=e._mouseColorID;this._mouseEventListObject[i]||(this._mouseEventListObject[i]={target:e},this._mouseEventList.push(e)),this._mouseEventListObject[i][t]=r},remove:function(e,t){var r=e._mouseColorID;if(this._mouseEventListObject[r]){var i=0;for(var n in this._mouseEventListObject[r][t]&&delete this._mouseEventListObject[r][t],this._mouseEventListObject[r])i++;if(1===i){var a=this._mouseEventList.indexOf(e);a>-1&&(this._mouseEventList.splice(a,1),delete this._mouseEventListObject[r])}}},render:(n=new Uint8Array(4),a=1,o=[],s="default",d=function(){if(o.length){var e=o.shift();e.info[e.type].call(e.info.target,{target:e.info.target,type:"out"})}},function(u,c,l,f,h,R){if(this._mouseEventList.length){a=u.renderScale*window.devicePixelRatio,e=u.gl,t=c.worldRect,l._viewRect,r=t[2],i=t[3],this.frameBuffer.width=r,this.frameBuffer.height=i,this.frameBuffer.bind(u.gl),c.sceneRender(u,l.scene,l.camera,l.camera.mode2DYn,this._mouseEventList,f,h,this._mouseEventMaterial);var m,p,_,g=u._mouseEventInfo;for(m=0,p=g.length;m
',this.geometry=RedPlane(e,1,1),this.material=RedTextMaterial(e,RedBitmapTexture(e,this._cvs)),this.blendSrc=e.gl.ONE,this.blendDst=e.gl.ONE_MINUS_SRC_ALPHA,this.useCullFace=!1,this.perspectiveScale=!0,this.sprite3DYn=!1,this._img=new Image,i=i||256,(r=r||256)>e.detect.texture.MAX_TEXTURE_SIZE&&(r=e.detect.texture.MAX_TEXTURE_SIZE),i>e.detect.texture.MAX_TEXTURE_SIZE&&(i=e.detect.texture.MAX_TEXTURE_SIZE),this.width=r,this.height=i,t(this,"padding",0),t(this,"background",""),t(this,"color","#000"),t(this,"fontFamily","Arial"),t(this,"fontSize",16),t(this,"fontWeight","normal"),t(this,"fontStyle","normal"),t(this,"lineHeight",24),t(this,"letterSpacing",0),t(this,"wordBreak","break-all"),t(this,"verticalAlign","middle"),t(this,"textAlign","center"),this._img.onload=function(){var t,r;(t=n._width)%2==0&&(t+=1),(r=n._height)%2==0&&(r+=1),n._cvs=window.OffscreenCanvas?new OffscreenCanvas(t,r):document.createElement("canvas"),n._ctx=n._cvs.getContext("2d"),n._cvs.width=t,n._cvs.height=r,n._ctx.clearRect(0,0,t,r),n._ctx.drawImage(n._img,0,0,t,r),n.material.width=t,n.material.height=r,n.material.diffuseTexture.src=n._cvs,n.material.diffuseTexture.option={min:e.gl.LINEAR,mag:e.gl.LINEAR,wrap_s:e.gl.CLAMP_TO_EDGE,wrap_t:e.gl.CLAMP_TO_EDGE}},this.useTransparentSort=!0,this._UUID=RedGL.makeUUID()}).prototype=new RedBaseObject3D,RedDefinePropertyInfo.definePrototypes("RedText",["perspectiveScale","boolean"],["sprite3DYn","boolean"],["width","uint",{min:2,callback:function(t){this._width=t,this.material.width=t,e(this)}}],["height","uint",{min:2,callback:function(t){this._height=t,this.material.height=t,e(this)}}]),Object.defineProperty(RedText.prototype,"text",{get:function(){return this._text},set:function(t){r=this._svg,i=r.querySelector("foreignObject td"),this._text=t.replace(/\/gi,"
");var n=this,a=this._text.match(//g),o=[],s=this._text,d=(a=a||[]).length,l=0;a.forEach(function(t){var r=t.match(/src\s*=\s*(\'|\").*?(\'|\")/g)[0];r=r.replace(/src\s*=\s*(\'|\")/g,"").replace(/(\'|\")/g,"");var a=document.createElement("div");a.innerHTML=t;var u=a.querySelector("img");u.onload=function(){var t=document.createElement("canvas");t.width=u.style.width?+u.style.width:u.width,t.height=u.style.height?+u.style.height:u.height;var r=t.getContext("2d");r.scale(t.width/u.naturalWidth,t.height/u.naturalHeight),r.drawImage(u,0,0),c.result='',++l==d&&(o.forEach(function(e){s=s.replace(e.source,e.result)}),i.innerHTML=s,e(n)),u.onload=null};var c={source:t,sourceSrc:r,result:""};o.push(c)}),0==a.length&&(i.innerHTML=s,e(this))}}),Object.freeze(RedText)}(),function(){var e,t,r,i,n,a,o,s,d;(RedMouseEventManager=function(e){if(!(this instanceof RedMouseEventManager))return new RedMouseEventManager(e);e instanceof RedGL||RedGLUtil.throwFunc("RedMouseEventManager : RedGL Instance만 허용.",e),this.frameBuffer=RedFrameBuffer(e),this._mouseEventMaterial=RedMouseEventMaterial(e),this._mouseEventListObject={},this._mouseEventList=[],this._prevInfo={},this._UUID=RedGL.makeUUID()}).prototype={add:function(e,t,r){var i=e._mouseColorID;this._mouseEventListObject[i]||(this._mouseEventListObject[i]={target:e},this._mouseEventList.push(e)),this._mouseEventListObject[i][t]=r},remove:function(e,t){var r=e._mouseColorID;if(this._mouseEventListObject[r]){var i=0;for(var n in this._mouseEventListObject[r][t]&&delete this._mouseEventListObject[r][t],this._mouseEventListObject[r])i++;if(1===i){var a=this._mouseEventList.indexOf(e);a>-1&&(this._mouseEventList.splice(a,1),delete this._mouseEventListObject[r])}}},render:(n=new Uint8Array(4),a=1,o=[],s="default",d=function(){if(o.length){var e=o.shift();e.info[e.type].call(e.info.target,{target:e.info.target,type:"out"})}},function(l,u,c,f,h,R){if(this._mouseEventList.length){a=l.renderScale*window.devicePixelRatio,e=l.gl,t=u.worldRect,c._viewRect,r=t[2],i=t[3],this.frameBuffer.width=r,this.frameBuffer.height=i,this.frameBuffer.bind(l.gl),u.sceneRender(l,c.scene,c.camera,c.camera.mode2DYn,this._mouseEventList,f,h,this._mouseEventMaterial);var m,p,_,g=l._mouseEventInfo;for(m=0,p=g.length;m lumaMax)) finalColor = vec4(rgbA, 1.0); else finalColor = vec4(rgbB, 1.0); gl_FragColor = finalColor; } -*/},(RedPostEffect_FXAA=function(i){if(!(this instanceof RedPostEffect_FXAA))return new RedPostEffect_FXAA(i);i instanceof RedGL||RedGLUtil.throwFunc("RedPostEffect_FXAA : RedGL Instance만 허용.",i),this.frameBuffer=RedFrameBuffer(i),this.diffuseTexture=null,this.program=RedProgram.makeProgram(i,"RedPostEffectFXAAProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBasePostEffect,RedPostEffect_FXAA.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototype("RedPostEffect_FXAA","diffuseTexture","sampler2D"),Object.freeze(RedPostEffect_FXAA)}(),function(){var e,t,r,i,n,a;(RedGLOffScreen=function(e,t,r,i,n){if(!(this instanceof RedGLOffScreen))return new RedGLOffScreen(e,t,r,i,n);RedGLDetect.getBrowserInfo();var a=this;a.htmlCanvas=e,a.redGLSrc=i,fetch(n).then(function(e){e.text().then(function(e){a.hostCode="\ncanvas.tagName = 'CANVAS';\nreturn RedGL(canvas, function (v) {\nvar _host_ = "+e+";\n_host_.call(this);\n\n});",a.setSize(t,r)})}).catch(function(e){})}).prototype.updatePostMessage=function(e){if(!e)throw"RedGLOffScreen.prototype['updatePostMessage'] - run을 정의해야합니다."+e;if(!e.name)throw"RedGLOffScreen.prototype['updatePostMessage'] - run객체의 name을 정의해야합니다."+e.name;this.worker.postMessage({state:"update",run:e})},RedGLOffScreen.prototype._init=function(r,i,n){var a=this;this.worker&&this.worker.terminate();var o=this.htmlCanvas.parentNode,s=r.cloneNode(!0);o.replaceChild(s,this.htmlCanvas),this.htmlCanvas=s;var d="x,y,clientX,clientY,pageX,pageY,screenX,screenY,layerX,layerY,detail,shiftKey,altKey,ctrlKey,movementX,movementY,button,type,which,deltaX,deltaY,deltaZ,timeStamp,targetTouches".split(","),u="shiftKey,altKey,ctrlKey,key,keyCode,location,code,charCode,detail,timeStamp,which,type".split(","),c=[RedGLDetect.BROWSER_INFO.move,RedGLDetect.BROWSER_INFO.down,RedGLDetect.BROWSER_INFO.up],l="keydown,keyup,keypress".split(",");c.forEach(function(e){a.htmlCanvas.addEventListener(e,function(e){var t={};d.forEach(function(r){if("targetTouches"==r&&e[r]){for(var i=[],n=e[r].length;n--;){var a=e[r][n];i.push({clientX:a.clientX,clientY:a.clientY,force:a.force,identifier:a.identifier,pageX:a.pageX,pageY:a.pageY,radiusX:a.radiusX,radiusY:a.radiusY,rotationAngle:a.rotationAngle,screenX:a.screenX,screenY:a.screenY})}t[r]=i}else t[r]=e[r]}),a.worker.postMessage({state:e.type,event:t})})}),l.forEach(function(e){window.addEventListener(e,function(e){var t={};u.forEach(function(r){t[r]=e[r]}),a.worker.postMessage({state:e.type,event:t})})}),this.offScreenCanvas=this.htmlCanvas.transferControlToOffscreen(),this.offScreenCanvas.width=i,this.offScreenCanvas.height=n,this.worker=null,t=new Blob([e],{type:"application/javascript"}),this.worker=new Worker(URL.createObjectURL(t));var f=document.location.pathname.split("/");f[f.length-1].indexOf(".")>-1&&f.pop();var h=this.redGLSrc.split("/");h.forEach(function(e,t){".."===e&&(f.pop(),h[t]=""),"."===e&&(h[t]="")}),this.worker.postMessage({canvas:this.offScreenCanvas,state:"init",redGLSrc:document.location.origin+f.join("/")+"/"+h.join("/"),hostCode:this.hostCode.toString()},[this.offScreenCanvas])},RedGLOffScreen.prototype.setSize=(n=0,a=0,function(e,t,o){void 0===e&&RedGLUtil.throwFunc("RedGL setSize : width가 입력되지 않았습니다."),void 0===t&&RedGLUtil.throwFunc("RedGL setSize : height가 입력되지 않았습니다."),r=this._width=e,i=this._height=t,"number"!=typeof r&&(r.indexOf("%")>-1?r=(document.documentElement?document.documentElement.clientWidth:document.body.clientWidth)*parseFloat(r)/100:RedGLUtil.throwFunc("RedGL setSize : width는 0이상의 숫자나 %만 허용.",r)),"number"!=typeof i&&(i.indexOf("%")>-1?i=window.innerHeight*parseFloat(i)/100:RedGLUtil.throwFunc("RedGL setSize : height는 0이상의 숫자나 %만 허용.",i)),window.devicePixelRatio,this._canvas,(n!==r||a!==i||o)&&(n=r,a=i),r=parseInt(r),i=parseInt(i),this._init(this.htmlCanvas,r,i)}),e=(e=function(){var e,t;this.window=this,onmessage=function(r){switch(r.data.state){case"init":e||(importScripts(r.data.redGLSrc),e=new Function("canvas",r.data.hostCode)),t=new e(r.data.canvas);break;case"update":var i=r.data.run.args;t.userInterface[r.data.run.name]["array"==typeof i?"apply":"call"](t,r.data.run.args);break;case RedGLDetect.BROWSER_INFO.move:var n=new Event(RedGLDetect.BROWSER_INFO.move),a=r.data.event;for(var o in a)n[o]=a[o];t._canvas.dispatchEvent(n);break;case RedGLDetect.BROWSER_INFO.down:for(var o in n=new Event(RedGLDetect.BROWSER_INFO.down),a=r.data.event)n[o]=a[o];t._canvas.dispatchEvent(n);break;case RedGLDetect.BROWSER_INFO.up:for(var o in n=new Event(RedGLDetect.BROWSER_INFO.up),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n);break;case"wheel":for(var o in n=new Event("wheel"),a=r.data.event)n[o]=a[o];t._canvas.dispatchEvent(n);break;case"keydown":for(var o in n=new Event("keydown"),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n);break;case"keyup":for(var o in n=new Event("keyup"),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n);break;case"keypress":for(var o in n=new Event("keypress"),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n)}}}).toString().replace(/^function ?. ?\) ?\{|\}\;?$/g,"")}();var RedGL_VERSION={version:"RedGL Release. last update( 2019-07-09 12:27:18)"}; \ No newline at end of file +*/},(RedPostEffect_FXAA=function(i){if(!(this instanceof RedPostEffect_FXAA))return new RedPostEffect_FXAA(i);i instanceof RedGL||RedGLUtil.throwFunc("RedPostEffect_FXAA : RedGL Instance만 허용.",i),this.frameBuffer=RedFrameBuffer(i),this.diffuseTexture=null,this.program=RedProgram.makeProgram(i,"RedPostEffectFXAAProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBasePostEffect,RedPostEffect_FXAA.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototype("RedPostEffect_FXAA","diffuseTexture","sampler2D"),Object.freeze(RedPostEffect_FXAA)}(),(RedFilterFrameBuffer=function(e,t,r){if(!(this instanceof RedFilterFrameBuffer))return new RedFilterFrameBuffer(e,t,r);var i;e instanceof RedGL||RedGLUtil.throwFunc("RedFilterFrameBuffer : RedGL Instance만 허용.",e),t&&("number"==typeof t||RedGLUtil.throwFunc("RedFilterFrameBuffer : width - 숫자만 허용","입력값 : ",t)),r&&("number"==typeof r||RedGLUtil.throwFunc("RedFilterFrameBuffer : height - 숫자만 허용","입력값 : ",r)),i=e.gl,r=r||1080,(t=t||1920)>e.detect.texture.MAX_TEXTURE_SIZE&&(t=e.detect.texture.MAX_TEXTURE_SIZE),r>e.detect.texture.MAX_TEXTURE_SIZE&&(r=e.detect.texture.MAX_TEXTURE_SIZE),this.redGL=e,this.width=t,this.height=r,this._prevWidth=null,this._prevHeight=null,this.webglFrameBuffer=i.createFramebuffer(),this.webglRenderBuffer=i.createRenderbuffer(),this.texture=RedBitmapTexture(e),this._UUID=RedGL.makeUUID(),i.bindFramebuffer(i.FRAMEBUFFER,this.webglFrameBuffer),i.activeTexture(i.TEXTURE0),i.bindTexture(i.TEXTURE_2D,this.texture.webglTexture),i.texImage2D(i.TEXTURE_2D,0,i.RGBA,this.width,this.height,0,i.RGBA,i.UNSIGNED_BYTE,null),i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL,!1),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,i.NEAREST),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,i.CLAMP_TO_EDGE),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,i.CLAMP_TO_EDGE),i.framebufferTexture2D(i.FRAMEBUFFER,i.COLOR_ATTACHMENT0,i.TEXTURE_2D,this.texture.webglTexture,0),i.bindTexture(i.TEXTURE_2D,null),i.bindFramebuffer(i.FRAMEBUFFER,null)}).prototype={bind:function(e){e.bindFramebuffer(e.FRAMEBUFFER,this.webglFrameBuffer),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.texture.webglTexture),this._prevWidth!=this.width||this._prevHeight!=this.height?e.texImage2D(e.TEXTURE_2D,0,e.RGBA,parseInt(this.width),parseInt(this.height),0,e.RGBA,e.UNSIGNED_BYTE,null):e.clear(e.COLOR_BUFFER_BIT),this._prevWidth=this.width,this._prevHeight=this.height},unbind:function(e){e.bindFramebuffer(e.FRAMEBUFFER,null)}},RedDefinePropertyInfo.definePrototypes("RedFilterFrameBuffer",["width","number",{min:2}],["height","number",{min:2}]),Object.freeze(RedFilterFrameBuffer),function(){var e,t,r,i,n,a,o;(RedFilterEffectManager=function(e){if(!(this instanceof RedFilterEffectManager))return new RedFilterEffectManager(e);e instanceof RedGL||RedGLUtil.throwFunc("RedFilterEffectManager : RedGL Instance만 허용.",e),Object.defineProperty(this,"frameBuffer",{value:RedFilterFrameBuffer(e)}),Object.defineProperty(this,"finalMaterial",{value:RedFilterMaterial(e,this.frameBuffer.texture)}),this.filterList=[];var t=RedMesh(e,RedPlane(e,1,1,1,1,!0),this.finalMaterial);t.useCullFace=!1,Object.defineProperty(this,"children",{value:[t]}),this._UUID=RedGL.makeUUID()}).prototype={bind:function(e){this.frameBuffer.bind(e)},unbind:function(e){this.frameBuffer.unbind(e)},render:(o=[],n=function(r,o,s,d,l,u,c,f,h,R,m){var p,_,g,v,E,M,b,L,T,P,x,y,w=[];if(b=r.gl,P=d.scene,x=d._viewRect,o._process&&o._process.length)for(M=i,L=0,T=o._process.length;LM?I:M,v=(B=D[1]*y[T]+D[5]*y[P]+D[9]*y[x])b?B:b,E=(F=D[2]*y[T]+D[6]*y[P]+D[10]*y[x])L?F:L;for(A=[M-g,b-v,L-E],o.length=0,w=0,U=this.filterList.length,t=this.children[0];wp[3]&&(S=p[3]),d.scissor(parseInt(j[0]*window.devicePixelRatio-S/2),parseInt(_[3]-j[1]*window.devicePixelRatio-S/2),parseInt(S),parseInt(S))),w=0,U=o.length;w 0.0) finalColor.rgb = (finalColor.rgb - 0.5) / (1.0 - u_contrast_value) + 0.5; +else finalColor.rgb = (finalColor.rgb - 0.5) * (1.0 + u_contrast_value) + 0.5; +finalColor.rgb += u_brightness_value; +gl_FragColor = finalColor; +} +*/},(RedFilter_BrightnessContrast=function(i){if(!(this instanceof RedFilter_BrightnessContrast))return new RedFilter_BrightnessContrast(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_BrightnessContrast : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.brightness=0,this.contrast=0,this.program=RedProgram.makeProgram(i,"RedFilterBrightnessContrastProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_BrightnessContrast.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_BrightnessContrast",["diffuseTexture","sampler2D"],["brightness","number",{min:-150,max:150,callback:function(e){this._brightness_value=e/255}}],["contrast","number",{min:-50,max:100,callback:function(e){this._contrast_value=e/255}}]),Object.freeze(RedFilter_BrightnessContrast)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +void main(void) { +vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution); +highp float gray = (finalColor.r + finalColor.g + finalColor.b)/3.0; +gl_FragColor = vec4( gray, gray, gray, finalColor.a); +} +*/},(RedFilter_Gray=function(i){if(!(this instanceof RedFilter_Gray))return new RedFilter_Gray(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Gray : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.program=RedProgram.makeProgram(i,"RedFilterGrayProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Gray.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototype("RedFilter_Gray","diffuseTexture","sampler2D"),Object.freeze(RedFilter_Gray)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +void main(void) { +vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution); +if(finalColor.a == 0.0) discard; +finalColor.r = 1.0 - finalColor.r; +finalColor.g = 1.0 - finalColor.g; +finalColor.b = 1.0 - finalColor.b; +gl_FragColor = finalColor; +} +*/},(RedFilter_Invert=function(i){if(!(this instanceof RedFilter_Invert))return new RedFilter_Invert(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Invert : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.program=RedProgram.makeProgram(i,"RedFilterInvertProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Invert.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototype("RedFilter_Invert","diffuseTexture","sampler2D"),Object.freeze(RedFilter_Invert)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform float u_threshold_value; +void main() { +vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); +float v; +if(0.2126 * finalColor.r + 0.7152 * finalColor.g + 0.0722 * finalColor.b >= u_threshold_value) v = 1.0; +else v = 0.0; +finalColor.r = finalColor.g = finalColor.b = v; +gl_FragColor = finalColor; +} +*/},(RedFilter_Threshold=function(i){if(!(this instanceof RedFilter_Threshold))return new RedFilter_Threshold(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Threshold : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.threshold=50,this.program=RedProgram.makeProgram(i,"RedFilterThresholdProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Threshold.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_Threshold",["diffuseTexture","sampler2D"],["threshold","number",{min:1,max:255,callback:function(e){this._threshold_value=e/255}}]),Object.freeze(RedFilter_Threshold)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform float u_hue_value; +uniform float u_saturation_value; +void main(void) { +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +vec4 finalColor = texture2D(u_diffuseTexture, testCoord ); +float angle = u_hue_value * 3.1415926535897932384626433832795; +float s = sin(angle), c = cos(angle); +vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0; +float len = length(finalColor.rgb); +finalColor.rgb = vec3( +dot(finalColor.rgb, weights.xyz), +dot(finalColor.rgb, weights.zxy), +dot(finalColor.rgb, weights.yzx) +); +float average = (finalColor.r + finalColor.g + finalColor.b) / 3.0; +if (u_saturation_value > 0.0) finalColor.rgb += (average - finalColor.rgb) * (1.0 - 1.0 / (1.001 - u_saturation_value)); +else finalColor.rgb += (average - finalColor.rgb) * (-u_saturation_value); +gl_FragColor = finalColor; +} +*/},(RedFilter_HueSaturation=function(i){if(!(this instanceof RedFilter_HueSaturation))return new RedFilter_HueSaturation(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_HueSaturation : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.hue=0,this.saturation=0,this.program=RedProgram.makeProgram(i,"RedFilterHueSaturationProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_HueSaturation.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_HueSaturation",["diffuseTexture","sampler2D"],["hue","number",{min:-180,max:180,callback:function(e){this._hue_value=e/180}}],["saturation","number",{min:-100,max:100,callback:function(e){this._saturation_value=e/100}}]),Object.freeze(RedFilter_HueSaturation)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +void main(void) { +vec2 px = vec2(1.0/vResolution.x, 1.0/vResolution.y); +vec4 finalColor = vec4(0.0); +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-7.0*px.x, -7.0*px.y))*0.0044299121055113265; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-6.0*px.x, -6.0*px.y))*0.00895781211794; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-5.0*px.x, -5.0*px.y))*0.0215963866053; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-4.0*px.x, -4.0*px.y))*0.0443683338718; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-3.0*px.x, -3.0*px.y))*0.0776744219933; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-2.0*px.x, -2.0*px.y))*0.115876621105; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-1.0*px.x, -1.0*px.y))*0.147308056121; +finalColor += texture2D(u_diffuseTexture, testCoord )*0.159576912161; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 1.0*px.x, 1.0*px.y))*0.147308056121; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 2.0*px.x, 2.0*px.y))*0.115876621105; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 3.0*px.x, 3.0*px.y))*0.0776744219933; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 4.0*px.x, 4.0*px.y))*0.0443683338718; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 5.0*px.x, 5.0*px.y))*0.0215963866053; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 6.0*px.x, 6.0*px.y))*0.00895781211794; +finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 7.0*px.x, 7.0*px.y))*0.0044299121055113265; +gl_FragColor = finalColor; +} +*/},(RedFilter_Blur=function(i){if(!(this instanceof RedFilter_Blur))return new RedFilter_Blur(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Blur : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.program=RedProgram.makeProgram(i,"RedFilterBlurProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Blur.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototype("RedFilter_Blur","diffuseTexture","sampler2D"),Object.freeze(RedFilter_Blur)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision mediump float; +uniform sampler2D u_diffuseTexture; +uniform float u_size; +float random(vec3 scale, float seed) { +return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); +} +void main() { +vec4 finalColor = vec4(0.0); +vec2 delta; +float total = 0.0; +float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); +delta = vec2(u_size/vResolution.x,0.0); +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +float percent; +float weight; +for (float t = -4.0; t <= 4.0; t+=1.0) { +float percent = (t + offset - 0.5) / 4.0; +float weight = 1.0 - abs(percent); +vec4 sample = texture2D(u_diffuseTexture, testCoord + delta * percent); +sample.rgb *= sample.a; +finalColor += sample * weight; +total += weight; +} +finalColor = finalColor / total; +finalColor.rgb /= finalColor.a + 0.00001; +gl_FragColor = finalColor ; +} +*/},(RedFilter_BlurX=function(i){if(!(this instanceof RedFilter_BlurX))return new RedFilter_BlurX(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_BlurX : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.size=50,this.program=RedProgram.makeProgram(i,"RedFilterBlurXProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_BlurX.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_BlurX",["diffuseTexture","sampler2D"],["size","number",{min:0}]),Object.freeze(RedFilter_BlurX)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform float u_size; +float random(vec3 scale, float seed) { +return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); +} +void main() { +vec4 finalColor = vec4(0.0); +vec2 delta; +float total = 0.0; +float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); +delta = vec2(0.0, u_size/vResolution.y); +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +for (float t = -4.0; t <= 4.0; t++) { +float percent = (t + offset - 0.5) / 4.0; +float weight = 1.0 - abs(percent); +vec4 sample = texture2D(u_diffuseTexture, testCoord + delta * percent); +sample.rgb *= sample.a; +finalColor += sample * weight; +total += weight; +} +finalColor = finalColor / total; +finalColor.rgb /= finalColor.a + 0.00001; +gl_FragColor = finalColor ; +} +*/},(RedFilter_BlurY=function(i){if(!(this instanceof RedFilter_BlurY))return new RedFilter_BlurY(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_BlurY : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.size=25,this.program=RedProgram.makeProgram(i,"RedFilterBlurYProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_BlurY.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_BlurY",["diffuseTexture","sampler2D"],["size","number",{min:0}]),Object.freeze(RedFilter_BlurY)}(),(RedFilter_GaussianBlur=function(e){if(!(this instanceof RedFilter_GaussianBlur))return new RedFilter_GaussianBlur(e);e instanceof RedGL||RedGLUtil.throwFunc("RedFilter_GaussianBlur : RedGL Instance만 허용.",e),this._UUID=RedGL.makeUUID(),this._process=[RedFilter_BlurX(e),RedFilter_BlurY(e)],this.radius=1}).prototype=new RedBaseFilter,RedFilter_GaussianBlur.prototype.updateTexture=function(){},RedDefinePropertyInfo.definePrototype("RedFilter_GaussianBlur","radius","number",{min:.1,max:255,callback:function(e){this._process[0].size=e,this._process[1].size=e}}),Object.freeze(RedFilter_GaussianBlur),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform float u_width; +uniform float u_height; +void main(void) { +vec4 finalColor; +float dx = 1.0/vResolution.x * u_width; +float dy = 1.0/vResolution.y * u_height; +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +vec2 coord = vec2( +dx * (floor(testCoord.x / dx) + 0.5), +dy * (floor(testCoord.y / dy) + 0.5) +); +finalColor = texture2D(u_diffuseTexture, coord); +gl_FragColor = finalColor; +} +*/},(RedFilter_Pixelize=function(i){if(!(this instanceof RedFilter_Pixelize))return new RedFilter_Pixelize(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Pixelize : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.width=5,this.height=5,this.program=RedProgram.makeProgram(i,"RedFilterPixelizeProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Pixelize.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_Pixelize",["diffuseTexture","sampler2D"],["width","number",{min:0}],["height","number",{min:0}]),Object.freeze(RedFilter_Pixelize)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform float u_centerX; +uniform float u_centerY; +uniform float u_angle; +uniform float u_radius; +uniform bool u_grayMode; +float pattern(float angle, vec2 testCoord) { +angle = angle * 3.141592653589793/180.0; +float s = sin(angle), c = cos(angle); +vec2 tex = testCoord; +tex.x -= u_centerX + 0.5; +tex.y -= u_centerY + 0.5; +vec2 point = vec2( +c * tex.x - s * tex.y, +s * tex.x + c * tex.y +) * vResolution / u_radius; +return (sin(point.x) * sin(point.y)) * 4.0; +} +void main(void) { +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +vec4 finalColor = texture2D(u_diffuseTexture, testCoord); +if(u_grayMode) { +float average = (finalColor.r + finalColor.g + finalColor.b) / 3.0; +gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern(u_angle,testCoord)), finalColor.a); +}else{ +vec3 cmy = 1.0 - finalColor.rgb; +float k = min(cmy.x, min(cmy.y, cmy.z)); +cmy = (cmy - k) / (1.0 - k); +cmy = clamp(cmy * 10.0 - 3.0 + vec3(pattern(u_angle + 0.26179,testCoord), pattern(u_angle + 1.30899,testCoord), pattern(u_angle,testCoord)), 0.0, 1.0); +k = clamp(k * 10.0 - 5.0 + pattern(u_angle + 0.78539,testCoord), 0.0, 1.0); +gl_FragColor = vec4(1.0 - cmy - k, finalColor.a); +} +} +*/},(RedFilter_HalfTone=function(i){if(!(this instanceof RedFilter_HalfTone))return new RedFilter_HalfTone(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_HalfTone : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.centerX=0,this.centerY=0,this.angle=0,this.radius=2,this.grayMode=!1,this.program=RedProgram.makeProgram(i,"RedFilterHalfToneProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_HalfTone.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_HalfTone",["diffuseTexture","sampler2D"],["centerX","number"],["centerY","number"],["angle","number"],["grayMode","boolean"],["radius","number",{min:0}]),Object.freeze(RedFilter_HalfTone)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform sampler2D u_blurTexture; +uniform float u_exposure; +uniform float u_bloomStrength; +void main() { +vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); +vec4 thresholdColor = finalColor; +vec4 blurColor = texture2D(u_blurTexture, gl_FragCoord.xy/vResolution.xy); +finalColor.rgb = (finalColor.rgb + blurColor.rgb * u_bloomStrength) * u_exposure; +gl_FragColor = finalColor ; +} +*/},(RedFilter_Bloom=function(i){if(!(this instanceof RedFilter_Bloom))return new RedFilter_Bloom(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Bloom : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.blurTexture=null,this.exposure=1,this.bloomStrength=1.2,this._process=[RedFilter_BloomThreshold(i),RedFilter_BlurX(i),RedFilter_BlurY(i)],this.blur=20,this.threshold=75,this.program=RedProgram.makeProgram(i,"RedFilterBloomProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Bloom.prototype.updateTexture=function(e,t){this.diffuseTexture=t,this.blurTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_Bloom",["diffuseTexture","sampler2D"],["blurTexture","sampler2D"],["exposure","number",{min:0}],["bloomStrength","number",{min:0}],["threshold","number",{min:0,callback:function(e){this._process[0].threshold=e,this._threshold=this._process[0].threshold}}],["blur","number",{min:0,callback:function(e){this._process[1].size=e,this._process[2].size=e}}]),Object.freeze(RedFilter_Bloom)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform sampler2D u_diffuseTexture; +uniform float u_threshold_value; +void main() { +vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); +if(0.2126 * finalColor.r + 0.7152 * finalColor.g + 0.0722 * finalColor.b < u_threshold_value) finalColor.r = finalColor.g = finalColor.b = 0.0; +gl_FragColor = finalColor; +} +*/},(RedFilter_BloomThreshold=function(i){if(!(this instanceof RedFilter_BloomThreshold))return new RedFilter_BloomThreshold(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_BloomThreshold : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.renderScale=.5,this.threshold=128,this.program=RedProgram.makeProgram(i,"RedFilterBloomThresholdProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_BloomThreshold.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_BloomThreshold",["diffuseTexture","sampler2D"],["threshold","number",{min:0,max:255,callback:function(e){this._threshold_value=e/255}}]),Object.freeze(RedFilter_BloomThreshold)}(),function(){var e,t,r;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision lowp float; +uniform bool u_grayMode; +uniform sampler2D u_diffuseTexture; +uniform float u_noiseIntensity; // noise effect intensity value (0 = no effect, 1 = full effect) +uniform float u_scanlineIntensity; // scanlines effect intensity value (0 = no effect, 1 = full effect) +uniform float u_scanlineCount; // scanlines effect count value (0 = no effect, 4096 = full effect) +void main() { +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +vec4 diffuseColor = texture2D( u_diffuseTexture, testCoord ); +float x = testCoord.x * testCoord.y * vTime; +x = mod( x, 13.0 ) * mod( x, 123.0 ); +float dx = mod( x, 0.01 ); +vec3 finalColor = diffuseColor.rgb + diffuseColor.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 ); +vec2 sc = vec2( sin( testCoord.y * u_scanlineCount ), cos( testCoord.y * u_scanlineCount ) ); +finalColor += diffuseColor.rgb * vec3( sc.x, sc.y, sc.x ) * u_scanlineIntensity; +finalColor = diffuseColor.rgb + clamp( u_noiseIntensity, 0.0, 1.0 ) * ( finalColor - diffuseColor.rgb ); +if( u_grayMode ) finalColor = vec3( finalColor.r * 0.3 + finalColor.g * 0.59 + finalColor.b * 0.11 ); +gl_FragColor = vec4( finalColor, diffuseColor.a ); +} +*/},(RedFilter_Film=function(i){if(!(this instanceof RedFilter_Film))return new RedFilter_Film(i);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Film : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.grayMode=!1,this.scanlineIntensity=.5,this.noiseIntensity=.5,this.scanlineCount=2048,this.program=RedProgram.makeProgram(i,"RedFilterFilmProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Film.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototypes("RedFilter_Film",["diffuseTexture","sampler2D"],["grayMode","boolean"],["scanlineIntensity","number",{min:0}],["noiseIntensity","number",{min:0}],["scanlineCount","number",{min:0}]),Object.freeze(RedFilter_Film)}(),function(){var e,t,r,i,n;e=RedBaseFilter.baseVertexShaderSource1,t=function(){ +/* @preserve +precision mediump float; +uniform sampler2D u_diffuseTexture; +uniform mat3 u_kernel; +uniform float uKernelWeight; +void main(void) { +vec2 perPX = vec2(1.0/vResolution.x, 1.0/vResolution.y); +vec2 testCoord = gl_FragCoord.xy/vResolution.xy; +vec4 finalColor = vec4(0.0); +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, -1.0)) * u_kernel[0][0] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, -1.0)) * u_kernel[0][1] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, -1.0)) * u_kernel[0][2] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, 0.0)) * u_kernel[1][0] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, 0.0)) * u_kernel[1][1] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, 0.0)) * u_kernel[1][2] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, 1.0)) * u_kernel[2][0] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, 1.0)) * u_kernel[2][1] ; +finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, 1.0)) * u_kernel[2][2] ; +gl_FragColor = vec4((finalColor / uKernelWeight).rgb, finalColor.a); +} +*/},(RedFilter_Convolution=function(i,n){if(!(this instanceof RedFilter_Convolution))return new RedFilter_Convolution(i,n);i instanceof RedGL||RedGLUtil.throwFunc("RedFilter_Convolution : RedGL Instance만 허용.",i),this.frameBuffer=RedFilterFrameBuffer(i),this.diffuseTexture=null,this.kernel=n,this.program=RedProgram.makeProgram(i,"RedFilterConvolutionProgram",e,t),this._UUID=RedGL.makeUUID(),r||(this.checkUniformAndProperty(),r=!0)}).prototype=new RedBaseFilter,RedFilter_Convolution.prototype.updateTexture=function(e){this.diffuseTexture=e},RedDefinePropertyInfo.definePrototype("RedFilter_Convolution","diffuseTexture","sampler2D"),Object.defineProperty(RedFilter_Convolution.prototype,"kernel",{get:function(){return this._kernel||(this._kernel=RedFilter_Convolution.NORMAL),this._kernel},set:function(e){this._kernel=e}}),Object.defineProperty(RedFilter_Convolution.prototype,"kernelWeight",{get:function(){for(n in i=0,this.kernel)i+=this.kernel[n];return i}}),RedFilter_Convolution.NORMAL=[0,0,0,0,1,0,0,0,0],RedFilter_Convolution.SHARPEN=[0,-1,0,-1,5,-1,0,-1,0],RedFilter_Convolution.BLUR=[1,1,1,1,1,1,1,1,1],RedFilter_Convolution.EDGE=[0,1,0,1,-4,1,0,1,0],RedFilter_Convolution.EMBOSS=[-2,-1,0,-1,1,1,0,1,2],Object.freeze(RedFilter_Convolution)}(),function(){var e,t,r,i,n,a;(RedGLOffScreen=function(e,t,r,i,n){if(!(this instanceof RedGLOffScreen))return new RedGLOffScreen(e,t,r,i,n);RedGLDetect.getBrowserInfo();var a=this;a.htmlCanvas=e,a.redGLSrc=i,fetch(n).then(function(e){e.text().then(function(e){a.hostCode="\ncanvas.tagName = 'CANVAS';\nreturn RedGL(canvas, function (v) {\nvar _host_ = "+e+";\n_host_.call(this);\n\n});",a.setSize(t,r)})}).catch(function(e){})}).prototype.updatePostMessage=function(e){if(!e)throw"RedGLOffScreen.prototype['updatePostMessage'] - run을 정의해야합니다."+e;if(!e.name)throw"RedGLOffScreen.prototype['updatePostMessage'] - run객체의 name을 정의해야합니다."+e.name;this.worker.postMessage({state:"update",run:e})},RedGLOffScreen.prototype._init=function(r,i,n){var a=this;this.worker&&this.worker.terminate();var o=this.htmlCanvas.parentNode,s=r.cloneNode(!0);o.replaceChild(s,this.htmlCanvas),this.htmlCanvas=s;var d="x,y,clientX,clientY,pageX,pageY,screenX,screenY,layerX,layerY,detail,shiftKey,altKey,ctrlKey,movementX,movementY,button,type,which,deltaX,deltaY,deltaZ,timeStamp,targetTouches".split(","),l="shiftKey,altKey,ctrlKey,key,keyCode,location,code,charCode,detail,timeStamp,which,type".split(","),u=[RedGLDetect.BROWSER_INFO.move,RedGLDetect.BROWSER_INFO.down,RedGLDetect.BROWSER_INFO.up],c="keydown,keyup,keypress".split(",");u.forEach(function(e){a.htmlCanvas.addEventListener(e,function(e){var t={};d.forEach(function(r){if("targetTouches"==r&&e[r]){for(var i=[],n=e[r].length;n--;){var a=e[r][n];i.push({clientX:a.clientX,clientY:a.clientY,force:a.force,identifier:a.identifier,pageX:a.pageX,pageY:a.pageY,radiusX:a.radiusX,radiusY:a.radiusY,rotationAngle:a.rotationAngle,screenX:a.screenX,screenY:a.screenY})}t[r]=i}else t[r]=e[r]}),a.worker.postMessage({state:e.type,event:t})})}),c.forEach(function(e){window.addEventListener(e,function(e){var t={};l.forEach(function(r){t[r]=e[r]}),a.worker.postMessage({state:e.type,event:t})})}),this.offScreenCanvas=this.htmlCanvas.transferControlToOffscreen(),this.offScreenCanvas.width=i,this.offScreenCanvas.height=n,this.worker=null,t=new Blob([e],{type:"application/javascript"}),this.worker=new Worker(URL.createObjectURL(t));var f=document.location.pathname.split("/");f[f.length-1].indexOf(".")>-1&&f.pop();var h=this.redGLSrc.split("/");h.forEach(function(e,t){".."===e&&(f.pop(),h[t]=""),"."===e&&(h[t]="")}),this.worker.postMessage({canvas:this.offScreenCanvas,state:"init",redGLSrc:document.location.origin+f.join("/")+"/"+h.join("/"),hostCode:this.hostCode.toString()},[this.offScreenCanvas])},RedGLOffScreen.prototype.setSize=(n=0,a=0,function(e,t,o){void 0===e&&RedGLUtil.throwFunc("RedGL setSize : width가 입력되지 않았습니다."),void 0===t&&RedGLUtil.throwFunc("RedGL setSize : height가 입력되지 않았습니다."),r=this._width=e,i=this._height=t,"number"!=typeof r&&(r.indexOf("%")>-1?r=(document.documentElement?document.documentElement.clientWidth:document.body.clientWidth)*parseFloat(r)/100:RedGLUtil.throwFunc("RedGL setSize : width는 0이상의 숫자나 %만 허용.",r)),"number"!=typeof i&&(i.indexOf("%")>-1?i=window.innerHeight*parseFloat(i)/100:RedGLUtil.throwFunc("RedGL setSize : height는 0이상의 숫자나 %만 허용.",i)),window.devicePixelRatio,this._canvas,(n!==r||a!==i||o)&&(n=r,a=i),r=parseInt(r),i=parseInt(i),this._init(this.htmlCanvas,r,i)}),e=(e=function(){var e,t;this.window=this,onmessage=function(r){switch(r.data.state){case"init":e||(importScripts(r.data.redGLSrc),e=new Function("canvas",r.data.hostCode)),t=new e(r.data.canvas);break;case"update":var i=r.data.run.args;t.userInterface[r.data.run.name]["array"==typeof i?"apply":"call"](t,r.data.run.args);break;case RedGLDetect.BROWSER_INFO.move:var n=new Event(RedGLDetect.BROWSER_INFO.move),a=r.data.event;for(var o in a)n[o]=a[o];t._canvas.dispatchEvent(n);break;case RedGLDetect.BROWSER_INFO.down:for(var o in n=new Event(RedGLDetect.BROWSER_INFO.down),a=r.data.event)n[o]=a[o];t._canvas.dispatchEvent(n);break;case RedGLDetect.BROWSER_INFO.up:for(var o in n=new Event(RedGLDetect.BROWSER_INFO.up),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n);break;case"wheel":for(var o in n=new Event("wheel"),a=r.data.event)n[o]=a[o];t._canvas.dispatchEvent(n);break;case"keydown":for(var o in n=new Event("keydown"),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n);break;case"keyup":for(var o in n=new Event("keyup"),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n);break;case"keypress":for(var o in n=new Event("keypress"),a=r.data.event)n[o]=a[o];this.window.dispatchEvent(n)}}}).toString().replace(/^function ?. ?\) ?\{|\}\;?$/g,"")}();var RedGL_VERSION={version:"RedGL Release. last update( 2019-08-07 11:46:16)"}; \ No newline at end of file diff --git a/src/base/RedBaseFilter.js b/src/base/RedBaseFilter.js new file mode 100644 index 00000000..f3efac5e --- /dev/null +++ b/src/base/RedBaseFilter.js @@ -0,0 +1,63 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ +"use strict"; +var RedBaseFilter; +(function () { + var tPrototype; + /*DOC: + { + constructorYn : true, + title :`RedBaseFilter`, + description : ` + 메쉬 필터 정의 사용되는 기저층 + `, + extends:['RedBaseMaterial'], + return : 'RedBaseFilter Instance' + } + :DOC*/ + RedBaseFilter = function () {}; + tPrototype = RedBaseFilter.prototype = new RedBaseMaterial(); + tPrototype['bind'] = RedFilterEffectManager.prototype['bind']; + tPrototype['unbind'] = RedFilterEffectManager.prototype['unbind']; + /*DOC: + { + title :`updateTexture`, + code : 'METHOD', + description : ` + 메쉬 필터 정의시 반드시 재정의 되어야함. + 메쉬 필터 내부에서 사용되는 텍스쳐를 업데이트함. + `, + return : 'void' + } + :DOC*/ + tPrototype['updateTexture'] = function () { + RedGLUtil.throwFunc('RedBaseFilter - updateTexture : 반드시 재정의해야함') + }; + /*DOC: + { + title :`_process`, + code : 'PROPERTY', + description : ` + 해당메쉬 필터 처리전 전처리과정이 필요할 경우 사용. + `, + return : 'void' + } + :DOC*/ + tPrototype['_process'] = []; + RedBaseFilter['baseVertexShaderSource1'] = function () { + /* @preserve + void main(void) { + vTexcoord = aTexcoord; + vResolution = uResolution; + vTime = uTime; + gl_Position = uPMatrix * uCameraMatrix * uMMatrix * vec4(aVertexPosition, 1.0); + } + */ + }; + Object.freeze(RedBaseFilter); +})(); \ No newline at end of file diff --git a/src/base/RedBaseObject3D.js b/src/base/RedBaseObject3D.js index 061d1d12..9d3eb137 100644 --- a/src/base/RedBaseObject3D.js +++ b/src/base/RedBaseObject3D.js @@ -1,8 +1,9 @@ /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.7.5 11:49 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * */ "use strict"; var RedBaseObject3D; @@ -368,9 +369,81 @@ var RedBaseObject3D; parseInt(Math.random() * 255), parseInt(Math.random() * 255), 255 - ]) + ]); + // 아웃라인 + /*DOC: + { + code : 'PROPERTY', + title :`outlineThickness`, + description : ` + 기본값 : 0 + 최소값 : 0 + `, + return : 'Number' + } + :DOC*/ + this['outlineThickness'] = 0; + this['_outlineAlpha'] = 1; + this['_outlineColor'] = new Float32Array(4) + this['outlineColor'] = '#ff0000'; + this['_filterList'] = []; + }; RedBaseObject3D.prototype = { + /*DOC: + { + title :`addFilter`, + code : 'METHOD', + description : ` + filter 추가 + `, + params : { + filter : [ + {type:'RedBaseFilter Instance'} + ] + }, + return : 'void' + } + :DOC*/ + addFilter: function (filter) { + filter instanceof RedBaseFilter || RedGLUtil.throwFunc('RedFilterEffectManager : addFilter - RedBaseFilter Instance만 허용.', '입력값 : ' + filter); + this['_filterList'].push(filter); + }, + /*DOC: + { + title :`removeFilter`, + code : 'METHOD', + description : ` + filter 제거 + `, + params : { + filter : [ + {type:'RedBaseFilter Instance'} + ] + }, + return : 'void' + } + :DOC*/ + removeFilter: (function () { + var t0; + return function (filter) { + t0 = this['_filterList'].indexOf(filter); + if (t0 != -1) this['_filterList'].splice(t0, 1); + } + })(), + /*DOC: + { + title :`removeAllFilter`, + code : 'METHOD', + description : ` + 모든 filter 제거 + `, + return : 'void' + } + :DOC*/ + removeAllFilter: function () { + this['_filterList'].length = 0; + }, /*DOC: { title :`addLOD`, @@ -934,5 +1007,47 @@ var RedBaseObject3D; this['_material'] = v } }); + /*DOC: + { + code : 'PROPERTY', + title :`outlineColor`, + description : `기본값 : #ff0000`, + return : 'hex' + } + :DOC*/ + Object.defineProperty(RedBaseObject3D.prototype, 'outlineColor', { + get: function () { + return this['_outlineColorHex'] + }, + set: (function () { + var t0; + return function (hex) { + this['_outlineColorHex'] = hex ? hex : '#ff0000'; + t0 = RedGLUtil.hexToRGB_ZeroToOne.call(this, this['_outlineColorHex']); + this['_outlineColor'][0] = t0[0]; + this['_outlineColor'][1] = t0[1]; + this['_outlineColor'][2] = t0[2]; + this['_outlineColor'][3] = this['_outlineAlpha']; + } + })() + }); + /*DOC: + { + code : 'PROPERTY', + title :`outlineAlpha`, + description : ` + 기본값 : 1 + 최소값 : 0 + 최대값 : 1 + `, + return : 'Number' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedBaseObject3D', 'outlineAlpha', 'number', { + 'min': 0, 'max': 1, + callback: function (v) { + this['_outlineColor'][3] = this['_outlineAlpha'] = v + } + }); Object.freeze(RedBaseObject3D); })(); diff --git a/src/filter/RedFilterEffectManager.js b/src/filter/RedFilterEffectManager.js new file mode 100644 index 00000000..69b8a18c --- /dev/null +++ b/src/filter/RedFilterEffectManager.js @@ -0,0 +1,421 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:52:14 + * + */ + +"use strict"; +var RedFilterEffectManager; +(function () { + var tRedGL; + /*DOC: + { + constructorYn : true, + title :`RedFilterEffectManager`, + description : ` + RedFilterEffectManager Instance 생성. + RedScene 생성시 내부속성으로 자동생성됨. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + demo : '../example/RedFilters.html', + return : 'RedFilterEffectManager Instance' + } + :DOC*/ + RedFilterEffectManager = function (redGL) { + if (!(this instanceof RedFilterEffectManager)) return new RedFilterEffectManager(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilterEffectManager : RedGL Instance만 허용.', redGL); + /*DOC: + { + title :`frameBuffer`, + code : 'PROPERTY', + description : ` + 이펙트 렌더링시 사용될 프레임버퍼 + `, + return : 'RedFrameBuffer Instance' + } + :DOC*/ + Object.defineProperty(this, 'frameBuffer', {value: RedFilterFrameBuffer(redGL)}); + Object.defineProperty(this, 'finalMaterial', {value: RedFilterMaterial(redGL, this['frameBuffer']['texture'])}); + /*DOC: + { + title :`filterList`, + code : 'PROPERTY', + description : ` + 이펙트 리스트 + `, + return : 'Array' + } + :DOC*/ + this['filterList'] = []; + var quadMesh = RedMesh(redGL, RedPlane(redGL, 1, 1, 1, 1, true), this['finalMaterial']); + quadMesh.useCullFace = false; + Object.defineProperty(this, 'children', {value: [quadMesh]}); + this['_UUID'] = RedGL.makeUUID(); + console.log(this); + }; + RedFilterEffectManager.prototype = { + /*DOC: + { + title :`bind`, + code : 'METHOD', + description : ` + 프레임 버퍼 바인딩. + 렌더러에서 자동호출됨. + `, + params : { + gl : [ + {type:'WebGL Context'} + ] + }, + return : 'void' + } + :DOC*/ + bind: function (gl) { + this['frameBuffer'].bind(gl); + }, + /*DOC: + { + title :`unbind`, + code : 'METHOD', + description : ` + 프레임 버퍼 언바인딩. + 렌더러에서 자동호출됨. + `, + params : { + gl : [ + {type:'WebGL Context'} + ] + }, + return : 'void' + } + :DOC*/ + unbind: function (gl) { + this['frameBuffer'].unbind(gl); + }, + render: (function () { + var tQuadMesh; + var originFrameBufferTexture, lastFrameBufferTexture; + + var drawEffect; + var tCacheSystemUniformInfo; + var tEffectList; + tEffectList = []; + drawEffect = function (redGL, effect, quadChildren, redView, tCamera, redRenderer, time, renderInfo, tMesh, depth, length) { + var tPerspectiveMTX = []; + var tProgram; + var tLocationInfo; + var tSystemUniformLocation; + var tLocation; + var tUUID; + var tValueStr; + var tParentFrameBufferTexture; + var gl; + var i, len; + var tScene, tViewRect; + var tFrameBuffer; + gl = redGL.gl; + tScene = redView['scene']; + tViewRect = redView['_viewRect']; + //////////////////////////////////////////////////////////////////////////// + if (effect['_process'] && effect['_process'].length) { + tParentFrameBufferTexture = lastFrameBufferTexture; + i = 0; + len = effect['_process'].length; + for (i; i < len; i++) { + drawEffect(redGL, effect['_process'][i], quadChildren, redView, tCamera, redRenderer, time, renderInfo, tMesh, depth + 1); + } + } + tFrameBuffer = effect['frameBuffer']; + if (tFrameBuffer) { + // 최종메쉬의 재질을 현재 이펙트로 변경 + tFrameBuffer['_width'] = parseInt(tViewRect[2]); + tFrameBuffer['_height'] = parseInt(tViewRect[3]); + tQuadMesh['_material'] = effect; + // 프로그램을 변경 + tProgram = tQuadMesh['_material']['program']; + gl.useProgram(tProgram['webglProgram']); + // 시스템 유니폼중 업데이트 해야할 목록 처리 + tSystemUniformLocation = tProgram['systemUniformLocation']; + // 퍼스펙티브 매트릭스 처리 + tLocationInfo = tSystemUniformLocation['uPMatrix']; + if (tLocationInfo) { + tLocation = tLocationInfo['location']; + tUUID = tLocationInfo['_UUID']; + if (tLocation) { + if (tCamera['mode2DYn']) { + var x, y, z; + // mat4.ortho( + // tPerspectiveMTX, + // -0.5, // left + // 0.5, // right + // -0.5, // bottom + // 0.5, // top, + // -tCamera['farClipping'], + // tCamera['farClipping'] + // ); + // mat4.translate(tPerspectiveMTX, tPerspectiveMTX, [-0.5, 0.5, 0]); + // mat4.scale(tPerspectiveMTX, tPerspectiveMTX, [1 / parseInt(tViewRect[2]) * tRedGL.renderScale * window.devicePixelRatio, 1 / parseInt(tViewRect[3]) * tRedGL.renderScale * window.devicePixelRatio, 1]) + //ortho + tPerspectiveMTX[0] = 2; + tPerspectiveMTX[1] = 0; + tPerspectiveMTX[2] = 0; + tPerspectiveMTX[3] = 0; + tPerspectiveMTX[4] = 0; + tPerspectiveMTX[5] = 2; + tPerspectiveMTX[6] = 0; + tPerspectiveMTX[7] = 0; + tPerspectiveMTX[8] = 0; + tPerspectiveMTX[9] = 0; + tPerspectiveMTX[10] = 2 * -1 / tCamera['farClipping'] * 2; + tPerspectiveMTX[11] = 0; + tPerspectiveMTX[12] = 0; + tPerspectiveMTX[13] = 0; + tPerspectiveMTX[14] = 0; + tPerspectiveMTX[15] = 1; + x = -0.5, y = 0.5, z = 0; + tPerspectiveMTX[12] = tPerspectiveMTX[0] * x + tPerspectiveMTX[4] * y + tPerspectiveMTX[8] * z + tPerspectiveMTX[12]; + tPerspectiveMTX[13] = tPerspectiveMTX[1] * x + tPerspectiveMTX[5] * y + tPerspectiveMTX[9] * z + tPerspectiveMTX[13]; + tPerspectiveMTX[14] = tPerspectiveMTX[2] * x + tPerspectiveMTX[6] * y + tPerspectiveMTX[10] * z + tPerspectiveMTX[14]; + tPerspectiveMTX[15] = tPerspectiveMTX[3] * x + tPerspectiveMTX[7] * y + tPerspectiveMTX[11] * z + tPerspectiveMTX[15]; + x = 1 / parseInt(tViewRect[2]) * tRedGL.renderScale * window.devicePixelRatio; + y = 1 / parseInt(tViewRect[3]) * tRedGL.renderScale * window.devicePixelRatio; + z = 1; + tPerspectiveMTX[0] = tPerspectiveMTX[0] * x; + tPerspectiveMTX[1] = tPerspectiveMTX[1] * x; + tPerspectiveMTX[2] = tPerspectiveMTX[2] * x; + tPerspectiveMTX[3] = tPerspectiveMTX[3] * x; + tPerspectiveMTX[4] = tPerspectiveMTX[4] * y; + tPerspectiveMTX[5] = tPerspectiveMTX[5] * y; + tPerspectiveMTX[6] = tPerspectiveMTX[6] * y; + tPerspectiveMTX[7] = tPerspectiveMTX[7] * y; + tPerspectiveMTX[8] = tPerspectiveMTX[8] * z; + tPerspectiveMTX[9] = tPerspectiveMTX[9] * z; + tPerspectiveMTX[10] = tPerspectiveMTX[10] * z; + tPerspectiveMTX[11] = tPerspectiveMTX[11] * z; + + + } else { + tPerspectiveMTX = tCamera['perspectiveMTX'] + } + tValueStr = JSON.stringify(tPerspectiveMTX); + if (tCacheSystemUniformInfo[tUUID] != tValueStr) { + gl.uniformMatrix4fv(tLocation, false, tPerspectiveMTX); + tCacheSystemUniformInfo[tUUID] = tValueStr; + } + } + } + ////////////////////////////////////////////////////////////////////// + // if (!tCamera['mode2DYn'] || depth || length > 1) { + gl.bindFramebuffer(gl.FRAMEBUFFER, tFrameBuffer['webglFrameBuffer']); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tFrameBuffer['texture']['webglTexture']); + + if (tFrameBuffer['_prevWidth'] != tFrameBuffer['width'] || tFrameBuffer['_prevHeight'] != tFrameBuffer['height']) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, tFrameBuffer['width'], tFrameBuffer['height'], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } else { + gl.clear(gl.COLOR_BUFFER_BIT) + } + + + tFrameBuffer._prevWidth = tFrameBuffer['width']; + tFrameBuffer._prevHeight = tFrameBuffer['height'] + // } + // 해당 이펙트의 기본 텍스쳐를 지난 이펙트의 최종 텍스쳐로 업로드 + if (effect['_process'] && effect['_process'].length) { + effect.updateTexture( + lastFrameBufferTexture, + tParentFrameBufferTexture + ); + } else { + effect['_diffuseTexture'] = lastFrameBufferTexture; + } + // 해당 이펙트를 렌더링하고 + redRenderer.sceneRender(redGL, tScene, tCamera, tCamera['mode2DYn'], quadChildren, time, renderInfo); + // 해당 이펙트의 프레임 버퍼를 언바인딩한다. + // if (!tCamera['mode2DYn'] || depth || length > 1) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + // } + // 현재 이펙트를 최종 텍스쳐로 기록하고 다음 이펙트가 있을경우 활용한다. + lastFrameBufferTexture = tFrameBuffer['texture']; + } + }; + return function (redGL, gl, redRenderer, redView, time, renderInfo, tMesh) { + var tCamera; + var tScene; + var tViewRect, tWorldRect; + var minX, minY, minZ, maxX, maxY, maxZ, vx, vy, vz, t, i, len; + var tx, ty, tz; + var tMatrix; + var stride; + var currentAABB; + var tRadius; + var tScaleX, tScaleY, tScaleTestX, tScaleTestY; + var prevEffect, tEffect; + prevEffect = null; + tScaleX = tScaleY = 0; + tRedGL = redGL; + tScene = redView['scene']; + tRadius = 0; + tCamera = redView['camera'] instanceof RedBaseController ? redView['camera']['camera'] : redView['camera']; + tViewRect = redView['_viewRect']; + tWorldRect = redRenderer['worldRect']; + tCacheSystemUniformInfo = redRenderer['cacheInfo']['cacheSystemUniformInfo']; + ///////////////////////////////////////////////////////////////////// + // 쿼드메쉬 영역 계산 + tMatrix = tMesh.matrix; + stride = tMesh._geometry['interleaveBuffer']['stride']; + minX = minY = minZ = maxX = maxY = maxZ = 0; + t = tMesh._geometry['interleaveBuffer']['data']; + i = 0; + len = tMesh._geometry['interleaveBuffer']['pointNum']; + for (i; i < len; i++) { + vx = i * stride , vy = vx + 1, vz = vx + 2; + tx = tMatrix[0] * t[vx] + tMatrix[4] * t[vy] + tMatrix[8] * t[vz]; + ty = tMatrix[1] * t[vx] + tMatrix[5] * t[vy] + tMatrix[9] * t[vz]; + tz = tMatrix[2] * t[vx] + tMatrix[6] * t[vy] + tMatrix[10] * t[vz]; + minX = tx < minX ? tx : minX; + maxX = tx > maxX ? tx : maxX; + minY = ty < minY ? ty : minY; + maxY = ty > maxY ? ty : maxY; + minZ = tz < minZ ? tz : minZ; + maxZ = tz > maxZ ? tz : maxZ; + } + currentAABB = [maxX - minX, maxY - minY, maxZ - minZ]; + ///////////////////////////////////////////////////////////////////// + // 렌더링할 이펙트 리스트를 정리한다. + tEffectList.length = 0; + i = 0; + len = this['filterList'].length; + tQuadMesh = this['children'][0]; + for (i; i < len; i++) { + tEffect = this['filterList'][i]; + + if (prevEffect != tEffect) { + // 최종 이펙트 리스트에 등록 + tEffectList[tEffectList.length] = tEffect; + // 스케일 계산 + if (tEffect instanceof RedFilter_Blur) { + tScaleTestX = currentAABB[0] + (tCamera['mode2DYn'] ? 5 : 0) + tScaleTestY = currentAABB[1] + (tCamera['mode2DYn'] ? 5 : 0) + } else if (tEffect instanceof RedFilter_BlurX || tEffect instanceof RedFilter_BlurY) { + tScaleTestX = currentAABB[0] + tEffect['_size'] ; + tScaleTestY = currentAABB[1] + tEffect['_size'] ; + } else if (tEffect instanceof RedFilter_GaussianBlur) { + tScaleTestX = currentAABB[0] + tEffect['_radius']; + tScaleTestY = currentAABB[1] + tEffect['_radius']; + } else if (tEffect instanceof RedFilter_Bloom) { + tScaleTestX = currentAABB[0] + tEffect['_blur']; + tScaleTestY = currentAABB[1] + tEffect['_blur']; + } else { + tScaleTestX = currentAABB[0]; + tScaleTestY = currentAABB[1] + } + + tScaleX = tScaleX < tScaleTestX ? tScaleTestX : tScaleX; + tScaleY = tScaleY < tScaleTestY ? tScaleTestY : tScaleY; + } + + prevEffect = tEffect + } + + // 쿼드메쉬 위치 설정 + tQuadMesh.x = tMesh.x; + tQuadMesh.y = tMesh.y; + tQuadMesh.z = tMesh.z; + // 쿼드메쉬 영역 설정 + if (tCamera['mode2DYn']) { + // 2D 일떄 + tQuadMesh.scaleX = tScaleX; + tQuadMesh.scaleY = tScaleY; + tQuadMesh.scaleZ = 1; + } else { + // 3D 일때 + tRadius = Math.sqrt(currentAABB[0] * currentAABB[0] + currentAABB[1] * currentAABB[1]); + tQuadMesh.scaleY = tQuadMesh.scaleX = tQuadMesh.scaleZ = tRadius + tQuadMesh.lookAt(tCamera.x, tCamera.y, tCamera.z) + + } + //////////////////////////////////////////////////////////////////////////// + // 프레임 버퍼 정보를 캐싱 + lastFrameBufferTexture = originFrameBufferTexture = this['frameBuffer']['texture']; + //////////////////////////////////////////////////////////////////////////// + // 최종결과는 RedView의 사이즈와 동일하게 한다. + this['frameBuffer']['_width'] = tViewRect[2]; + this['frameBuffer']['_height'] = tViewRect[3]; + + if (tCamera['mode2DYn']) { + gl.scissor( + parseInt(tMesh.x * redGL._renderScale * window.devicePixelRatio - tQuadMesh.scaleX / 2 * window.devicePixelRatio)-10, + parseInt(tViewRect[3] - tMesh.y * redGL._renderScale * window.devicePixelRatio - tQuadMesh.scaleY / 2 * window.devicePixelRatio)-10, + parseInt(tQuadMesh.scaleX * window.devicePixelRatio)+20, + parseInt(tQuadMesh.scaleY * window.devicePixelRatio)+20 + ); + } else { + var tScreen_point; + var tScreen_distance; + var tScreen_resultMTX; + var tScreen_resultPosition; + tScreen_resultPosition = {x: 0, y: 0, z: 0, w: 0}; + tScreen_resultMTX = [ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + ]; + ///////////////////////////////////////////////////////////////////////////////// + mat4.multiply(tScreen_resultMTX, tCamera.perspectiveMTX, tCamera.matrix); + mat4.multiply(tScreen_resultMTX, tScreen_resultMTX, tQuadMesh['matrix']); + //////////////////////////////////////////////////////////////////////////////// + tScreen_resultPosition.x = tScreen_resultMTX[12], tScreen_resultPosition.y = tScreen_resultMTX[13], tScreen_resultPosition.z = tScreen_resultMTX[14], tScreen_resultPosition.w = tScreen_resultMTX[15]; + tScreen_resultPosition.x = tScreen_resultPosition.x * 0.5 / tScreen_resultPosition.w + 0.5; + tScreen_resultPosition.y = tScreen_resultPosition.y * 0.5 / tScreen_resultPosition.w + 0.5; + tScreen_point = [ + (tViewRect[0] + tScreen_resultPosition.x * tViewRect[2]) / window.devicePixelRatio, + (tViewRect[1] + (1 - tScreen_resultPosition.y) * tViewRect[3]) / window.devicePixelRatio + ]; + tScreen_distance = vec3.distance([tCamera.x, tCamera.y, tCamera.z], [tMesh.x, tMesh.y, tMesh.z]); + tRadius = tRadius / (tScreen_distance) * tViewRect[3] + if (tRadius > tViewRect[3]) tRadius = tViewRect[3] + gl.scissor( + parseInt(tScreen_point[0] * window.devicePixelRatio - tRadius / 2), + parseInt(tWorldRect[3] - tScreen_point[1] * window.devicePixelRatio - tRadius / 2), + parseInt(tRadius), + parseInt(tRadius) + ); + } + + //////////////////////////////////////////////////////////////////////////// + // 이펙트 렌더 + i = 0; + len = tEffectList.length; + for (i; i < len; i++) drawEffect(redGL, tEffectList[i], this['children'], redView, tCamera, redRenderer, time, renderInfo, tMesh, 0, len); + //////////////////////////////////////////////////////////////////////////// + if (redView['postEffectManager']['postEffectList'].length) { + var tPostEffectManagerFrameBuffer = redView['postEffectManager']['frameBuffer'] + gl.bindFramebuffer(gl.FRAMEBUFFER, tPostEffectManagerFrameBuffer['webglFrameBuffer']); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tPostEffectManagerFrameBuffer['texture']['webglTexture']); + // 렌더버퍼 세팅 + gl.bindRenderbuffer(gl.RENDERBUFFER, tPostEffectManagerFrameBuffer['webglRenderBuffer']); + // 프레임버퍼 세팅 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tPostEffectManagerFrameBuffer['texture']['webglTexture'], 0); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, tPostEffectManagerFrameBuffer['webglRenderBuffer']); + } + if (lastFrameBufferTexture != originFrameBufferTexture) { + this['finalMaterial']['_diffuseTexture'] = lastFrameBufferTexture; + tQuadMesh._material = this['finalMaterial']; + redRenderer.sceneRender(redGL, tScene, tCamera, tCamera['mode2DYn'], this['children'], time, renderInfo); + } + gl.scissor(tViewRect[0], tWorldRect[3] - tViewRect[3] - tViewRect[1], tViewRect[2], tViewRect[3]); + this['finalMaterial']['_diffuseTexture'] = this['frameBuffer']['texture']; + } + })() + }; + Object.freeze(RedFilterEffectManager); +})(); \ No newline at end of file diff --git a/src/filter/RedFilterFrameBuffer.js b/src/filter/RedFilterFrameBuffer.js new file mode 100644 index 00000000..9dbc79e3 --- /dev/null +++ b/src/filter/RedFilterFrameBuffer.js @@ -0,0 +1,143 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ +"use strict"; +var RedFilterFrameBuffer; +(function () { + /*DOC: + { + constructorYn : true, + title :`RedFilterFrameBuffer`, + description : ` + RedFilterFrameBuffer Instance 생성자. + `, + params : { + redGL : [ + {type:'RedGL Instance'} + ], + width : [ + {type:'Number'}, + '기기허용 최대값보다 큰경우 기기허용 최대값으로 설정됨' + ], + height : [ + {type:'Number'}, + '기기허용 최대값보다 큰경우 기기허용 최대값으로 설정됨' + ] + }, + example : ` + RedFilterFrameBuffer( RedGL Instance ); + `, + return : 'RedGeometry Instance' + } + :DOC*/ + var testMap = {} + RedFilterFrameBuffer = function (redGL, width, height) { + if (!(this instanceof RedFilterFrameBuffer)) return new RedFilterFrameBuffer(redGL, width, height); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilterFrameBuffer : RedGL Instance만 허용.', redGL); + if (width) typeof width == 'number' || RedGLUtil.throwFunc('RedFilterFrameBuffer : width - 숫자만 허용', '입력값 : ', width); + if (height) typeof height == 'number' || RedGLUtil.throwFunc('RedFilterFrameBuffer : height - 숫자만 허용', '입력값 : ', height); + var gl; + gl = redGL['gl']; + width = width || 1920; + height = height || 1080; + if (width > redGL['detect']['texture']['MAX_TEXTURE_SIZE']) width = redGL['detect']['texture']['MAX_TEXTURE_SIZE']; + if (height > redGL['detect']['texture']['MAX_TEXTURE_SIZE']) height = redGL['detect']['texture']['MAX_TEXTURE_SIZE']; + this['redGL'] = redGL; + this['width'] = width; + this['height'] = height; + this._prevWidth = null + this._prevHeight = null + this['webglFrameBuffer'] = gl.createFramebuffer(); + this['webglRenderBuffer'] = gl.createRenderbuffer(); + this['texture'] = RedBitmapTexture(redGL); + this['_UUID'] = RedGL.makeUUID(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this['webglFrameBuffer']); + // 텍스쳐 세팅 + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this['texture']['webglTexture']); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this['width'], this['height'], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + // gl.generateMipmap(gl.TEXTURE_2D); + // 프레임버퍼 세팅 + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this['texture']['webglTexture'], 0); + // + gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + console.log(this) + }; + RedFilterFrameBuffer.prototype = { + /*DOC: + { + code : 'METHOD', + title :`bind`, + description : `소유하고있는 webglFrameBuffer, webglTexture, webglRenderBuffer를 binding.`, + params : { + gl : [{type:'WebGL Context'}] + }, + return : 'void' + } + :DOC*/ + bind: function (gl) { + gl.bindFramebuffer(gl.FRAMEBUFFER, this['webglFrameBuffer']); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this['texture']['webglTexture']); + if (this['_prevWidth'] != this['width'] || this['_prevHeight'] != this['height']) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, parseInt(this['width']), parseInt(this['height']), 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } else { + gl.clear(gl.COLOR_BUFFER_BIT) + } + + this._prevWidth = this['width'] + this._prevHeight = this['height'] + + }, + /*DOC: + { + code : 'METHOD', + title :`unbind`, + description : `소유하고있는 webglFrameBuffer, webglTexture, webglRenderBuffer를 unbinding.`, + params : { + gl : [{type:'WebGL Context'}] + }, + return : 'void' + } + :DOC*/ + unbind: function (gl) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilterFrameBuffer', + /*DOC: + { + code:`PROPERTY`, + title :`width`, + description : ` + 기본값 : 1920 or 하드웨어 최대값 + `, + return : 'Number' + } + :DOC*/ + ['width', 'number', {min: 2}], + /*DOC: + { + code:`PROPERTY`, + title :`height`, + description : ` + 기본값 : 1080 or 하드웨어 최대값 + `, + return : 'Number' + } + :DOC*/ + ['height', 'number', {min: 2}] + ); + Object.freeze(RedFilterFrameBuffer); +})(); \ No newline at end of file diff --git a/src/filter/RedFilter_Convolution.js b/src/filter/RedFilter_Convolution.js new file mode 100644 index 00000000..79254f92 --- /dev/null +++ b/src/filter/RedFilter_Convolution.js @@ -0,0 +1,223 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:32:14 + * + */ + +"use strict"; +var RedFilter_Convolution; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterConvolutionProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision mediump float; + uniform sampler2D u_diffuseTexture; + uniform mat3 u_kernel; + uniform float uKernelWeight; + void main(void) { + vec2 perPX = vec2(1.0/vResolution.x, 1.0/vResolution.y); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 finalColor = vec4(0.0); + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, -1.0)) * u_kernel[0][0] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, -1.0)) * u_kernel[0][1] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, -1.0)) * u_kernel[0][2] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, 0.0)) * u_kernel[1][0] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, 0.0)) * u_kernel[1][1] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, 0.0)) * u_kernel[1][2] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2(-1.0, 1.0)) * u_kernel[2][0] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 0.0, 1.0)) * u_kernel[2][1] ; + finalColor += texture2D(u_diffuseTexture, testCoord + perPX * vec2( 1.0, 1.0)) * u_kernel[2][2] ; + gl_FragColor = vec4((finalColor / uKernelWeight).rgb, finalColor.a); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Convolution`, + description : ` + Convolution 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/RedFilter_Convolution.html', + example : ` + var effect; + effect = RedFilter_DoF(RedGL Instance, RedFilter_Convolution.SHARPEN); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Convolution Instance' + } + :DOC*/ + RedFilter_Convolution = function (redGL, kernel) { + if (!(this instanceof RedFilter_Convolution)) return new RedFilter_Convolution(redGL, kernel); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Convolution : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['kernel'] = kernel; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Convolution.prototype = new RedBaseFilter(); + RedFilter_Convolution.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Convolution', 'diffuseTexture', 'sampler2D'); + /*DOC: + { + code : 'PROPERTY', + title :`kernel`, + description : ` + 커널값. + 3 * 3 매트릭스 형식의 배열 + `, + return : 'Array' + } + :DOC*/ + Object.defineProperty(RedFilter_Convolution.prototype, 'kernel', { + get: function () { + if (!this['_kernel']) this['_kernel'] = RedFilter_Convolution['NORMAL']; + return this['_kernel'] + }, + set: function (v) { + this['_kernel'] = v + } + }); + Object.defineProperty(RedFilter_Convolution.prototype, 'kernelWeight', (function () { + var sum; + var k; + return { + get: function () { + sum = 0; + for (k in this['kernel']) sum += this['kernel'][k]; + return sum; + } + } + })()); + /*DOC: + { + title :`RedFilter_Convolution.NORMAL`, + code : 'CONST', + description : ` + + [ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['NORMAL'] = [ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + ]; + /*DOC: + { + title :`RedFilter_Convolution.SHARPEN`, + code : 'CONST', + description : ` + + [ + 0, -1, 0, + -1, 5, -1, + 0, -1, 0 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['SHARPEN'] = [ + 0, -1, 0, + -1, 5, -1, + 0, -1, 0 + ]; + /*DOC: + { + title :`RedFilter_Convolution.BLUR`, + code : 'CONST', + description : ` + + [ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['BLUR'] = [ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1 + ]; + /*DOC: + { + title :`RedFilter_Convolution.EDGE`, + code : 'CONST', + description : ` + + [ + 0, 1, 0, + 1, -4, 1, + 0, 1, 0 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['EDGE'] = [ + 0, 1, 0, + 1, -4, 1, + 0, 1, 0 + ]; + /*DOC: + { + title :`RedFilter_Convolution.EMBOSS`, + code : 'CONST', + description : ` + + [ + -2, -1, 0, + -1, 1, 1, + 0, 1, 2 + ] + + `, + return : 'Array' + } + :DOC*/ + RedFilter_Convolution['EMBOSS'] = [ + -2, -1, 0, + -1, 1, 1, + 0, 1, 2 + ]; + Object.freeze(RedFilter_Convolution); +})(); \ No newline at end of file diff --git a/src/filter/RedFilter_Film.js b/src/filter/RedFilter_Film.js new file mode 100644 index 00000000..8e9da897 --- /dev/null +++ b/src/filter/RedFilter_Film.js @@ -0,0 +1,158 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ + +"use strict"; +var RedFilter_Film; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterFilmProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform bool u_grayMode; + uniform sampler2D u_diffuseTexture; + uniform float u_noiseIntensity; // noise effect intensity value (0 = no effect, 1 = full effect) + uniform float u_scanlineIntensity; // scanlines effect intensity value (0 = no effect, 1 = full effect) + uniform float u_scanlineCount; // scanlines effect count value (0 = no effect, 4096 = full effect) + + void main() { + // sample the source + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 diffuseColor = texture2D( u_diffuseTexture, testCoord ); + + // make some noise + float x = testCoord.x * testCoord.y * vTime; + x = mod( x, 13.0 ) * mod( x, 123.0 ); + float dx = mod( x, 0.01 ); + + // add noise + vec3 finalColor = diffuseColor.rgb + diffuseColor.rgb * clamp( 0.1 + dx * 100.0, 0.0, 1.0 ); + + // get us a sine and cosine + vec2 sc = vec2( sin( testCoord.y * u_scanlineCount ), cos( testCoord.y * u_scanlineCount ) ); + + // add scanlines + finalColor += diffuseColor.rgb * vec3( sc.x, sc.y, sc.x ) * u_scanlineIntensity; + + // interpolate between source and result by intensity + finalColor = diffuseColor.rgb + clamp( u_noiseIntensity, 0.0, 1.0 ) * ( finalColor - diffuseColor.rgb ); + + // convert to grayscale if desired + if( u_grayMode ) finalColor = vec3( finalColor.r * 0.3 + finalColor.g * 0.59 + finalColor.b * 0.11 ); + gl_FragColor = vec4( finalColor, diffuseColor.a ); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Film`, + description : ` + Film 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/RedFilter_Film.html', + example : ` + var effect; + effect = RedFilter_Film(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Film Instance' + } + :DOC*/ + RedFilter_Film = function (redGL) { + if (!(this instanceof RedFilter_Film)) return new RedFilter_Film(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Film : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['grayMode'] = false; + this['scanlineIntensity'] = 0.5; + this['noiseIntensity'] = 0.5; + this['scanlineCount'] = 2048; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Film.prototype = new RedBaseFilter(); + RedFilter_Film.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Film', + [ 'diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`grayMode`, + description : ` + 그레이모드 + 기본값 : false + `, + return : 'Boolean' + } + :DOC*/ + [ 'grayMode', 'boolean'], + /*DOC: + { + code : 'PROPERTY', + title :`scanlineIntensity`, + description : ` + 스캔라인강도 + 기본값 : 0.5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + [ 'scanlineIntensity', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`noiseIntensity`, + description : ` + 노이즈강도 + 기본값 : 0.5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + [ 'noiseIntensity', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`scanlineCount`, + description : ` + 스캔라인 수 + 기본값 : 2048 + min : 0 + `, + return : 'Number' + } + :DOC*/ + [ 'scanlineCount', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_Film); +})(); \ No newline at end of file diff --git a/src/filter/adjustments/RedFilter_BrightnessContrast.js b/src/filter/adjustments/RedFilter_BrightnessContrast.js new file mode 100644 index 00000000..8b9e1473 --- /dev/null +++ b/src/filter/adjustments/RedFilter_BrightnessContrast.js @@ -0,0 +1,120 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_BrightnessContrast; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBrightnessContrastProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision mediump float; + uniform sampler2D u_diffuseTexture; + uniform float u_brightness_value; + uniform float u_contrast_value; + void main(void) { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution ); + if (u_contrast_value > 0.0) finalColor.rgb = (finalColor.rgb - 0.5) / (1.0 - u_contrast_value) + 0.5; + else finalColor.rgb = (finalColor.rgb - 0.5) * (1.0 + u_contrast_value) + 0.5; + finalColor.rgb += u_brightness_value; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BrightnessContrast`, + description : ` + BrightnessContrast 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_BrightnessContrast.html', + example : ` + var effect; + effect = RedFilter_BrightnessContrast(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BrightnessContrast Instance' + } + :DOC*/ + RedFilter_BrightnessContrast = function (redGL) { + if (!(this instanceof RedFilter_BrightnessContrast)) return new RedFilter_BrightnessContrast(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BrightnessContrast : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['brightness'] = 0; + this['contrast'] = 0; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BrightnessContrast.prototype = new RedBaseFilter(); + RedFilter_BrightnessContrast.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BrightnessContrast', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`brightness`, + description : ` + 밝기 + 기본값 : 0 + min : -150 + max : 150 + `, + return : 'Number' + } + :DOC*/ + ['brightness', 'number', { + min: -150, max: 150, callback: function (v) { + this['_brightness_value'] = v / 255 + } + }], + /*DOC: + { + code : 'PROPERTY', + title :`contrast`, + description : ` + 대조 + 기본값 : 0 + min: -50 + max: 100 + `, + return : 'Number' + } + :DOC*/ + ['contrast', 'number', { + min: -50, max: 100, callback: function (v) { + this['_contrast_value'] = v / 255 + } + }] + ); + Object.freeze(RedFilter_BrightnessContrast); +})(); \ No newline at end of file diff --git a/src/filter/adjustments/RedFilter_Gray.js b/src/filter/adjustments/RedFilter_Gray.js new file mode 100644 index 00000000..dd9f8695 --- /dev/null +++ b/src/filter/adjustments/RedFilter_Gray.js @@ -0,0 +1,75 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Gray; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterGrayProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + void main(void) { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution); + highp float gray = (finalColor.r + finalColor.g + finalColor.b)/3.0; + gl_FragColor = vec4( gray, gray, gray, finalColor.a); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Gray`, + description : ` + Gray 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_Gray.html', + example : ` + var effect; + effect = RedFilter_Gray(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Gray Instance' + } + :DOC*/ + RedFilter_Gray = function (redGL) { + if (!(this instanceof RedFilter_Gray)) return new RedFilter_Gray(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Gray : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Gray.prototype = new RedBaseFilter(); + RedFilter_Gray.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Gray', 'diffuseTexture', 'sampler2D'); + Object.freeze(RedFilter_Gray); +})(); \ No newline at end of file diff --git a/src/filter/adjustments/RedFilter_HueSaturation.js b/src/filter/adjustments/RedFilter_HueSaturation.js new file mode 100644 index 00000000..be98d990 --- /dev/null +++ b/src/filter/adjustments/RedFilter_HueSaturation.js @@ -0,0 +1,132 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_HueSaturation; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterHueSaturationProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_hue_value; + uniform float u_saturation_value; + void main(void) { + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 finalColor = texture2D(u_diffuseTexture, testCoord ); + float angle = u_hue_value * 3.1415926535897932384626433832795; + float s = sin(angle), c = cos(angle); + vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0; + float len = length(finalColor.rgb); + + finalColor.rgb = vec3( + dot(finalColor.rgb, weights.xyz), + dot(finalColor.rgb, weights.zxy), + dot(finalColor.rgb, weights.yzx) + ); + + float average = (finalColor.r + finalColor.g + finalColor.b) / 3.0; + if (u_saturation_value > 0.0) finalColor.rgb += (average - finalColor.rgb) * (1.0 - 1.0 / (1.001 - u_saturation_value)); + else finalColor.rgb += (average - finalColor.rgb) * (-u_saturation_value); + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_HueSaturation`, + description : ` + HueSaturation 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_HueSaturation.html', + example : ` + var effect; + effect = RedFilter_HueSaturation(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_HueSaturation Instance' + } + :DOC*/ + RedFilter_HueSaturation = function (redGL) { + if (!(this instanceof RedFilter_HueSaturation)) return new RedFilter_HueSaturation(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_HueSaturation : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['hue'] = 0; + this['saturation'] = 0; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_HueSaturation.prototype = new RedBaseFilter(); + RedFilter_HueSaturation.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_HueSaturation', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`hue`, + description : ` + 색조 + 기본값 : 0 + min: -180 + max: 180 + `, + return : 'Number' + } + :DOC*/ + ['hue', 'number', { + min: -180, max: 180, callback: function (v) { + this['_hue_value'] = v / 180 + } + }], + /*DOC: + { + code : 'PROPERTY', + title :`saturation`, + description : ` + 채도 + 기본값 : 0 + min: -100 + max: 100 + `, + return : 'Number' + } + :DOC*/ + ['saturation', 'number', { + min: -100, max: 100, callback: function (v) { + this['_saturation_value'] = v / 100 + } + }] + ); + Object.freeze(RedFilter_HueSaturation); +})(); \ No newline at end of file diff --git a/src/filter/adjustments/RedFilter_Invert.js b/src/filter/adjustments/RedFilter_Invert.js new file mode 100644 index 00000000..b20b2226 --- /dev/null +++ b/src/filter/adjustments/RedFilter_Invert.js @@ -0,0 +1,79 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 17:36:26 + * + */ + +"use strict"; +var RedFilter_Invert; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterInvertProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + + void main(void) { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution); + if(finalColor.a == 0.0) discard; + finalColor.r = 1.0 - finalColor.r; + finalColor.g = 1.0 - finalColor.g; + finalColor.b = 1.0 - finalColor.b; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Invert`, + description : ` + Invert 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_Invert.html', + example : ` + var effect; + effect = RedFilter_Invert(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Invert Instance' + } + :DOC*/ + RedFilter_Invert = function (redGL) { + if (!(this instanceof RedFilter_Invert)) return new RedFilter_Invert(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Invert : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Invert.prototype = new RedBaseFilter(); + RedFilter_Invert.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Invert', 'diffuseTexture', 'sampler2D'); + Object.freeze(RedFilter_Invert); +})(); \ No newline at end of file diff --git a/src/filter/adjustments/RedFilter_Threshold.js b/src/filter/adjustments/RedFilter_Threshold.js new file mode 100644 index 00000000..dcfbfd5b --- /dev/null +++ b/src/filter/adjustments/RedFilter_Threshold.js @@ -0,0 +1,105 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_Threshold; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterThresholdProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_threshold_value; + void main() { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + float v; + if(0.2126 * finalColor.r + 0.7152 * finalColor.g + 0.0722 * finalColor.b >= u_threshold_value) v = 1.0; + else v = 0.0; + finalColor.r = finalColor.g = finalColor.b = v; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Threshold`, + description : ` + Threshold 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/adjustments/RedFilter_Threshold.html', + example : ` + var effect; + effect = RedFilter_Threshold(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Threshold Instance' + } + :DOC*/ + RedFilter_Threshold = function (redGL) { + if (!(this instanceof RedFilter_Threshold)) return new RedFilter_Threshold(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Threshold : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['threshold'] = 50; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Threshold.prototype = new RedBaseFilter(); + RedFilter_Threshold.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Threshold', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`threshold`, + description : ` + 최소 유효값 + 기본값 : 128 + min: 1 + max: 255 + `, + return : 'Number' + } + :DOC*/ + [ + 'threshold', 'number', + { + min: 1, max: 255, callback: function (v) { + this['_threshold_value'] = v / 255 + } + } + ] + ); + + Object.freeze(RedFilter_Threshold); +})(); \ No newline at end of file diff --git a/src/filter/bloom/RedFilter_Bloom.js b/src/filter/bloom/RedFilter_Bloom.js new file mode 100644 index 00000000..ce073239 --- /dev/null +++ b/src/filter/bloom/RedFilter_Bloom.js @@ -0,0 +1,159 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Bloom; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBloomProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform sampler2D u_blurTexture; + uniform float u_exposure; + uniform float u_bloomStrength; + + void main() { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + vec4 thresholdColor = finalColor; + vec4 blurColor = texture2D(u_blurTexture, gl_FragCoord.xy/vResolution.xy); + finalColor.rgb = (finalColor.rgb + blurColor.rgb * u_bloomStrength) * u_exposure; + gl_FragColor = finalColor ; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Bloom`, + description : ` + Bloom 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/bloom/RedFilter_Bloom.html', + example : ` + var effect; + effect = RedFilter_Bloom(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Bloom Instance' + } + :DOC*/ + RedFilter_Bloom = function (redGL) { + if (!(this instanceof RedFilter_Bloom)) return new RedFilter_Bloom(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Bloom : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['blurTexture'] = null; + this['exposure'] = 1; + this['bloomStrength'] = 1.2; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['_process'] = [ + RedFilter_BloomThreshold(redGL), + RedFilter_BlurX(redGL), + RedFilter_BlurY(redGL) + ]; + this['blur'] = 20; + this['threshold'] = 75; + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Bloom.prototype = new RedBaseFilter(); + RedFilter_Bloom.prototype['updateTexture'] = function (lastFrameBufferTexture, parentFrameBufferTexture) { + this['diffuseTexture'] = parentFrameBufferTexture; + this['blurTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Bloom', + ['diffuseTexture', 'sampler2D'], + ['blurTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`exposure`, + description : ` + 확산 강도. + 기본값 : 1 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['exposure', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`bloomStrength`, + description : ` + 블룸 강도 + 기본값 : 1.2 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['bloomStrength', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`threshold`, + description : ` + 최소 유효값 + 기본값 : 75 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['threshold', 'number', { + min: 0, + callback: function (v) { + this['_process'][0]['threshold'] = v; + this['_threshold'] = this['_process'][0]['threshold'] + } + }], + /*DOC: + { + code : 'PROPERTY', + title :`blur`, + description : ` + blur 정도. + 기본값 : 20 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['blur', 'number', { + min: 0, callback: function (v) { + this['_process'][1]['size'] = v; + this['_process'][2]['size'] = v; + } + }] + ); + Object.freeze(RedFilter_Bloom); +})(); \ No newline at end of file diff --git a/src/filter/bloom/RedFilter_BloomThreshold.js b/src/filter/bloom/RedFilter_BloomThreshold.js new file mode 100644 index 00000000..566ba116 --- /dev/null +++ b/src/filter/bloom/RedFilter_BloomThreshold.js @@ -0,0 +1,102 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_BloomThreshold; +(function () { + var vSource, fSource; + var PROGRAM_NAME; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_threshold_value; + + void main() { + vec4 finalColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + if(0.2126 * finalColor.r + 0.7152 * finalColor.g + 0.0722 * finalColor.b < u_threshold_value) finalColor.r = finalColor.g = finalColor.b = 0.0; + gl_FragColor = finalColor; + } + */ + }; + PROGRAM_NAME = 'RedFilterBloomThresholdProgram'; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BloomThreshold`, + description : ` + BloomThreshold 이펙트 + RedFilter_Bloom 내부에서 사용하는 절차 이펙트 + 시스템적으로 사용됨. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + example : ` + var effect; + effect = RedFilter_BloomThreshold(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BloomThreshold Instance' + } + :DOC*/ + RedFilter_BloomThreshold = function (redGL) { + if (!(this instanceof RedFilter_BloomThreshold)) return new RedFilter_BloomThreshold(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BloomThreshold : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['renderScale'] = 0.5 + this['threshold'] = 128; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BloomThreshold.prototype = new RedBaseFilter(); + RedFilter_BloomThreshold.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BloomThreshold', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`threshold`, + description : ` + 최소 유효값 + 기본값 : 128 + `, + return : 'Number' + } + :DOC*/ + [ + 'threshold', 'number', + { + min: 0, max: 255, callback: function (v) { + this['_threshold_value'] = v / 255 + } + } + ] + ); + Object.freeze(RedFilter_BloomThreshold); +})(); \ No newline at end of file diff --git a/src/filter/blur/RedFilter_Blur.js b/src/filter/blur/RedFilter_Blur.js new file mode 100644 index 00000000..06de9922 --- /dev/null +++ b/src/filter/blur/RedFilter_Blur.js @@ -0,0 +1,91 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Blur; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBlurProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + void main(void) { + vec2 px = vec2(1.0/vResolution.x, 1.0/vResolution.y); + vec4 finalColor = vec4(0.0); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-7.0*px.x, -7.0*px.y))*0.0044299121055113265; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-6.0*px.x, -6.0*px.y))*0.00895781211794; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-5.0*px.x, -5.0*px.y))*0.0215963866053; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-4.0*px.x, -4.0*px.y))*0.0443683338718; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-3.0*px.x, -3.0*px.y))*0.0776744219933; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-2.0*px.x, -2.0*px.y))*0.115876621105; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2(-1.0*px.x, -1.0*px.y))*0.147308056121; + finalColor += texture2D(u_diffuseTexture, testCoord )*0.159576912161; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 1.0*px.x, 1.0*px.y))*0.147308056121; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 2.0*px.x, 2.0*px.y))*0.115876621105; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 3.0*px.x, 3.0*px.y))*0.0776744219933; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 4.0*px.x, 4.0*px.y))*0.0443683338718; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 5.0*px.x, 5.0*px.y))*0.0215963866053; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 6.0*px.x, 6.0*px.y))*0.00895781211794; + finalColor += texture2D(u_diffuseTexture, testCoord + vec2( 7.0*px.x, 7.0*px.y))*0.0044299121055113265; + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Blur`, + description : ` + 기본 블러 이펙트 + postEffectManager.addEffect( effect Instance ) 로 추가. + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_Blur.html', + example : ` + var effect; + effect = RedFilter_Blur(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Blur Instance' + } + :DOC*/ + RedFilter_Blur = function (redGL) { + if (!(this instanceof RedFilter_Blur)) return new RedFilter_Blur(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Blur : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Blur.prototype = new RedBaseFilter(); + RedFilter_Blur.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototype('RedFilter_Blur', 'diffuseTexture', 'sampler2D'); + Object.freeze(RedFilter_Blur); +})(); \ No newline at end of file diff --git a/src/filter/blur/RedFilter_BlurX.js b/src/filter/blur/RedFilter_BlurX.js new file mode 100644 index 00000000..dc9542ec --- /dev/null +++ b/src/filter/blur/RedFilter_BlurX.js @@ -0,0 +1,111 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_BlurX; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBlurXProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision mediump float; + uniform sampler2D u_diffuseTexture; + uniform float u_size; + float random(vec3 scale, float seed) { + return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); + } + void main() { + vec4 finalColor = vec4(0.0); + vec2 delta; + float total = 0.0; + float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); + delta = vec2(u_size/vResolution.x,0.0); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + float percent; + float weight; + for (float t = -4.0; t <= 4.0; t+=1.0) { + float percent = (t + offset - 0.5) / 4.0; + float weight = 1.0 - abs(percent); + vec4 sample = texture2D(u_diffuseTexture, testCoord + delta * percent); + sample.rgb *= sample.a; + finalColor += sample * weight; + total += weight; + } + finalColor = finalColor / total; + finalColor.rgb /= finalColor.a + 0.00001; + gl_FragColor = finalColor ; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BlurX`, + description : ` + X축 블러 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_BlurX.html', + example : ` + var effect; + effect = RedFilter_BlurX(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BlurX Instance' + } + :DOC*/ + RedFilter_BlurX = function (redGL) { + if (!(this instanceof RedFilter_BlurX)) return new RedFilter_BlurX(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BlurX : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['size'] = 50; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BlurX.prototype = new RedBaseFilter(); + RedFilter_BlurX.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BlurX', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`size`, + description : ` + 블러 사이즈 + 기본값 : 50 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['size', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_BlurX); +})(); \ No newline at end of file diff --git a/src/filter/blur/RedFilter_BlurY.js b/src/filter/blur/RedFilter_BlurY.js new file mode 100644 index 00000000..80f1e0af --- /dev/null +++ b/src/filter/blur/RedFilter_BlurY.js @@ -0,0 +1,110 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.7 11:21:57 + * + */ + +"use strict"; +var RedFilter_BlurY; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterBlurYProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_size; + float random(vec3 scale, float seed) { + return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); + } + void main() { + vec4 finalColor = vec4(0.0); + vec2 delta; + float total = 0.0; + float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); + delta = vec2(0.0, u_size/vResolution.y); + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + + for (float t = -4.0; t <= 4.0; t++) { + float percent = (t + offset - 0.5) / 4.0; + float weight = 1.0 - abs(percent); + vec4 sample = texture2D(u_diffuseTexture, testCoord + delta * percent); + sample.rgb *= sample.a; + finalColor += sample * weight; + total += weight; + } + finalColor = finalColor / total; + finalColor.rgb /= finalColor.a + 0.00001; + gl_FragColor = finalColor ; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_BlurY`, + description : ` + X축 블러 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_BlurY.html', + example : ` + var effect; + effect = RedFilter_BlurY(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_BlurY Instance' + } + :DOC*/ + RedFilter_BlurY = function (redGL) { + if (!(this instanceof RedFilter_BlurY)) return new RedFilter_BlurY(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_BlurY : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['size'] = 25; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_BlurY.prototype = new RedBaseFilter(); + RedFilter_BlurY.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_BlurY', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`size`, + description : ` + 블러 사이즈 + 기본값 : 50 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['size', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_BlurY); +})(); \ No newline at end of file diff --git a/src/filter/blur/RedFilter_GaussianBlur.js b/src/filter/blur/RedFilter_GaussianBlur.js new file mode 100644 index 00000000..2cedf315 --- /dev/null +++ b/src/filter/blur/RedFilter_GaussianBlur.js @@ -0,0 +1,74 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_GaussianBlur; +(function () { + /*DOC: + { + constructorYn : true, + title :`RedFilter_GaussianBlur`, + description : ` + 가우시안 블러 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/blur/RedFilter_GaussianBlur.html', + example : ` + var effect; + effect = RedFilter_GaussianBlur(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_GaussianBlur Instance' + } + :DOC*/ + RedFilter_GaussianBlur = function (redGL) { + if (!(this instanceof RedFilter_GaussianBlur)) return new RedFilter_GaussianBlur(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_GaussianBlur : RedGL Instance만 허용.', redGL); + ///////////////////////////////////////// + // 일반 프로퍼티 + this['_UUID'] = RedGL.makeUUID(); + this['_process'] = [ + RedFilter_BlurX(redGL), + RedFilter_BlurY(redGL) + ]; + this['radius'] = 1; + console.log(this); + }; + RedFilter_GaussianBlur.prototype = new RedBaseFilter(); + RedFilter_GaussianBlur.prototype['updateTexture'] = function () { + }; + /*DOC: + { + code : 'PROPERTY', + title :`radius`, + description : ` + 가우시간 블러강도 + 기본값 : 1 + min: 0.1 + max: 255 + `, + return : 'Number' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedFilter_GaussianBlur', 'radius', 'number', { + min: 0.1, max: 255, callback: function (v) { + this['_process'][0]['size'] = v; + this['_process'][1]['size'] = v; + } + }); + Object.freeze(RedFilter_GaussianBlur); +})(); \ No newline at end of file diff --git a/src/filter/pixelate/RedFilter_HalfTone.js b/src/filter/pixelate/RedFilter_HalfTone.js new file mode 100644 index 00000000..eacffb07 --- /dev/null +++ b/src/filter/pixelate/RedFilter_HalfTone.js @@ -0,0 +1,166 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_HalfTone; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterHalfToneProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_centerX; + uniform float u_centerY; + uniform float u_angle; + uniform float u_radius; + uniform bool u_grayMode; + + float pattern(float angle, vec2 testCoord) { + angle = angle * 3.141592653589793/180.0; + float s = sin(angle), c = cos(angle); + vec2 tex = testCoord; + tex.x -= u_centerX + 0.5; + tex.y -= u_centerY + 0.5; + vec2 point = vec2( + c * tex.x - s * tex.y, + s * tex.x + c * tex.y + ) * vResolution / u_radius; + return (sin(point.x) * sin(point.y)) * 4.0; + } + void main(void) { + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec4 finalColor = texture2D(u_diffuseTexture, testCoord); + if(u_grayMode) { + float average = (finalColor.r + finalColor.g + finalColor.b) / 3.0; + gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern(u_angle,testCoord)), finalColor.a); + }else{ + vec3 cmy = 1.0 - finalColor.rgb; + float k = min(cmy.x, min(cmy.y, cmy.z)); + cmy = (cmy - k) / (1.0 - k); + cmy = clamp(cmy * 10.0 - 3.0 + vec3(pattern(u_angle + 0.26179,testCoord), pattern(u_angle + 1.30899,testCoord), pattern(u_angle,testCoord)), 0.0, 1.0); + k = clamp(k * 10.0 - 5.0 + pattern(u_angle + 0.78539,testCoord), 0.0, 1.0); + gl_FragColor = vec4(1.0 - cmy - k, finalColor.a); + } + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_HalfTone`, + description : ` + HalfTone 이펙트 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/pixelate/RedFilter_HalfTone.html', + example : ` + var effect; + effect = RedFilter_HalfTone(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_HalfTone Instance' + } + :DOC*/ + RedFilter_HalfTone = function (redGL) { + if (!(this instanceof RedFilter_HalfTone)) return new RedFilter_HalfTone(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_HalfTone : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['centerX'] = 0.0; + this['centerY'] = 0.0; + this['angle'] = 0; + this['radius'] = 2; + this['grayMode'] = false; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_HalfTone.prototype = new RedBaseFilter(); + RedFilter_HalfTone.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_HalfTone', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`centerX`, + description : ` + 기본값 0.0 + `, + return : 'Number' + } + :DOC*/ + ['centerX', 'number'], + /*DOC: + { + code : 'PROPERTY', + title :`centerY`, + description : ` + 기본값 0.0 + `, + return : 'Number' + } + :DOC*/ + ['centerY', 'number'], + /*DOC: + { + code : 'PROPERTY', + title :`angle`, + description : ` + 기본값 0.0 + `, + return : 'Number' + } + :DOC*/ + ['angle', 'number'], + /*DOC: + { + code : 'PROPERTY', + title :`grayMode`, + description : ` + 기본값 false + `, + return : 'Boolean' + } + :DOC*/ + ['grayMode', 'boolean'], + /*DOC: + { + code : 'PROPERTY', + title :`radius`, + description : ` + 기본값 2 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['radius', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_HalfTone); +})(); \ No newline at end of file diff --git a/src/filter/pixelate/RedFilter_Pixelize.js b/src/filter/pixelate/RedFilter_Pixelize.js new file mode 100644 index 00000000..d38ee363 --- /dev/null +++ b/src/filter/pixelate/RedFilter_Pixelize.js @@ -0,0 +1,114 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.6 14:20:40 + * + */ + +"use strict"; +var RedFilter_Pixelize; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterPixelizeProgram'; + var checked; + vSource = RedBaseFilter['baseVertexShaderSource1'] + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + uniform float u_width; + uniform float u_height; + void main(void) { + vec4 finalColor; + float dx = 1.0/vResolution.x * u_width; + float dy = 1.0/vResolution.y * u_height; + vec2 testCoord = gl_FragCoord.xy/vResolution.xy; + vec2 coord = vec2( + dx * (floor(testCoord.x / dx) + 0.5), + dy * (floor(testCoord.y / dy) + 0.5) + ); + finalColor = texture2D(u_diffuseTexture, coord); + gl_FragColor = finalColor; + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilter_Pixelize`, + description : ` + Pixelize 효과 + `, + params : { + redGL : [ + {type:'RedGL'} + ] + }, + extends : [ + 'RedBaseFilter', + 'RedBaseMaterial' + ], + demo : '../example/postEffect/pixelate/RedFilter_Pixelize.html', + example : ` + var effect; + effect = RedFilter_Pixelize(RedGL Instance); // 포스트이펙트 생성 + // postEffectManager는 RedView 생성시 자동생성됨. + (RedView Instance)['postEffectManager'].addEffect(effect); // 뷰에 이펙트 추가 + `, + return : 'RedFilter_Pixelize Instance' + } + :DOC*/ + RedFilter_Pixelize = function (redGL) { + if (!(this instanceof RedFilter_Pixelize)) return new RedFilter_Pixelize(redGL); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilter_Pixelize : RedGL Instance만 허용.', redGL); + this['frameBuffer'] = RedFilterFrameBuffer(redGL); + this['diffuseTexture'] = null; + this['width'] = 5; + this['height'] = 5; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilter_Pixelize.prototype = new RedBaseFilter(); + RedFilter_Pixelize.prototype['updateTexture'] = function (lastFrameBufferTexture) { + this['diffuseTexture'] = lastFrameBufferTexture; + }; + RedDefinePropertyInfo.definePrototypes( + 'RedFilter_Pixelize', + ['diffuseTexture', 'sampler2D'], + /*DOC: + { + code : 'PROPERTY', + title :`width`, + description : ` + 픽셀화 가로 크기 + 기본값 : 5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['width', 'number', {'min': 0}], + /*DOC: + { + code : 'PROPERTY', + title :`height`, + description : ` + 픽셀화 세로 크기 + 기본값 : 5 + min : 0 + `, + return : 'Number' + } + :DOC*/ + ['height', 'number', {'min': 0}] + ); + Object.freeze(RedFilter_Pixelize); +})(); \ No newline at end of file diff --git a/src/material/system/RedFilterMaterial.js b/src/material/system/RedFilterMaterial.js new file mode 100644 index 00000000..a58819d1 --- /dev/null +++ b/src/material/system/RedFilterMaterial.js @@ -0,0 +1,85 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * + */ + +"use strict"; +var RedFilterMaterial; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedFilterMaterialProgram'; + var checked; + vSource = function () { + /* @preserve + void main(void) { + vTexcoord = aTexcoord; + gl_Position = uPMatrix * uCameraMatrix * uMMatrix * vec4(aVertexPosition, 1.0); + vResolution = uResolution; + } + */ + }; + fSource = function () { + /* @preserve + precision lowp float; + uniform sampler2D u_diffuseTexture; + void main(void) { + gl_FragColor = texture2D(u_diffuseTexture, gl_FragCoord.xy/vResolution.xy); + // gl_FragColor.r = 1.0; + // gl_FragColor.a = 0.5; + if(gl_FragColor.a == 0.0) discard; + + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedFilterMaterial`, + description : ` + 메쉬 필터 최종 이미지를 생성하기 위한재질. + 시스템적으로 사용됨. + `, + params : { + redGL : [ + {type:'RedGL'} + ], + diffuseTexture : [ + {type:'RedBitmapTexture'}, + 'RedBitmapTexture Instance' + ] + }, + extends : ['RedBaseMaterial'], + return : 'RedFilterMaterial Instance' + } + :DOC*/ + RedFilterMaterial = function (redGL, diffuseTexture) { + if (!(this instanceof RedFilterMaterial)) return new RedFilterMaterial(redGL, diffuseTexture); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedFilterMaterial : RedGL Instance만 허용.', redGL); + ///////////////////////////////////////// + // 유니폼 프로퍼티 + this['diffuseTexture'] = diffuseTexture; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['program'] = RedProgram['makeProgram'](redGL, PROGRAM_NAME, vSource, fSource); + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedFilterMaterial.prototype = new RedBaseMaterial(); + /*DOC: + { + code : 'PROPERTY', + title :`diffuseTexture`, + description :`diffuseTexture`, + return : 'RedFilterMaterial' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedFilterMaterial', 'diffuseTexture', 'sampler2D', {essential: true}); + Object.freeze(RedFilterMaterial); +})(); \ No newline at end of file diff --git a/src/material/system/RedOutlineMaterial.js b/src/material/system/RedOutlineMaterial.js new file mode 100644 index 00000000..c41b7ff9 --- /dev/null +++ b/src/material/system/RedOutlineMaterial.js @@ -0,0 +1,160 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.7.12 14:22:52 + * + */ + +"use strict"; +var RedOutlineMaterial; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedOutlineMaterialProgram'; + var PROGRAM_OPTION_LIST = []; + var checked; + vSource = function () { + /* @preserve + // 스키닝 + //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# + + // Sprite3D + //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# + void main(void) { + gl_PointSize = uPointSize; + float outlineSize = uOutlineThickness; + + // position 계산 + //#REDGL_DEFINE#skin#true# mat4 targetMatrix = uMMatrix * getSkinMatrix() ; + //#REDGL_DEFINE#skin#false# mat4 targetMatrix = uMMatrix; + vVertexPosition = targetMatrix * vec4(aVertexPosition, 1.0); + float tScaleX = length(vec3(uMMatrix[0][0], uMMatrix[0][1], uMMatrix[0][2])); + float tScaleY = length(vec3(uMMatrix[1][0], uMMatrix[1][1], uMMatrix[1][2])); + float tScaleZ = length(vec3(uMMatrix[2][0], uMMatrix[2][1], uMMatrix[2][2])); + + //#REDGL_DEFINE#sprite3D#true# gl_Position = uPMatrix * getSprite3DMatrix(uCameraMatrix , targetMatrix) * vec4(aVertexPosition, 1.0); + //#REDGL_DEFINE#sprite3D#true# if(!u_PerspectiveScale){ + //#REDGL_DEFINE#sprite3D#true# gl_Position /= gl_Position.w; + //#REDGL_DEFINE#sprite3D#true# gl_Position.xy += aVertexPosition.xy * vec2((uPMatrix * targetMatrix)[0][0],(uPMatrix * targetMatrix)[1][1]); + //#REDGL_DEFINE#sprite3D#true# } + //#REDGL_DEFINE#skin#false#//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition * vec3(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY,1.0+outlineSize/tScaleZ) , 1.0); + //#REDGL_DEFINE#skin#true#//#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition + vec3( aVertexNormal * vec3(outlineSize/tScaleX,outlineSize/tScaleY,outlineSize/tScaleZ)), 1.0); + + + //#REDGL_DEFINE#directionalShadow#true# vResolution = uResolution; + //#REDGL_DEFINE#directionalShadow#true# vShadowPos = cTexUnitConverter * uDirectionalShadowLightMatrix * targetMatrix * vec4(aVertexPosition, 1.0); + } + */ + }; + fSource = function () { + /* @preserve + precision mediump float; + // 안개 + //#REDGL_DEFINE#fragmentShareFunc#fogFactor# + //#REDGL_DEFINE#fragmentShareFunc#fog# + + // 그림자 + //#REDGL_DEFINE#fragmentShareFunc#decodeFloatShadow# + //#REDGL_DEFINE#fragmentShareFunc#getShadowColor# + + void main(void) { + vec4 finalColor = uOutlineColor; + //#REDGL_DEFINE#directionalShadow#true# finalColor.rgb *= getShadowColor( vShadowPos, vResolution, uDirectionalShadowTexture); + //#REDGL_DEFINE#fog#false# gl_FragColor = finalColor; + //#REDGL_DEFINE#fog#true# gl_FragColor = fog( fogFactor(u_FogDistance, u_FogDensity), uFogColor, finalColor); + } + */ + }; + /*DOC: + { + constructorYn : true, + title :`RedOutlineMaterial`, + description : ` + RedOutlineMaterial Instance 생성 + `, + params : { + redGL : [ + {type:'RedGL'} + ], + hexColor : [ + {type:'hex'}, + '기본값 : #ff0000' + ], + alpha : [ + {type:'number'}, + '기본값 : 1' + ] + }, + extends : ['RedBaseMaterial'], + demo : '../example/material/RedOutlineMaterial.html', + example : ` + RedOutlineMaterial(RedGL Instance, hex) + `, + return : 'RedOutlineMaterial Instance' + } + :DOC*/ + RedOutlineMaterial = function (redGL, hexColor, alpha) { + if (!(this instanceof RedOutlineMaterial)) return new RedOutlineMaterial(redGL, hexColor, alpha); + redGL instanceof RedGL || RedGLUtil.throwFunc('RedOutlineMaterial : RedGL Instance만 허용.', '입력값 : ' + redGL); + this.makeProgramList(this, redGL, PROGRAM_NAME, vSource, fSource, PROGRAM_OPTION_LIST); + ///////////////////////////////////////// + // 유니폼 프로퍼티 + this['_color'] = new Float32Array(4); + this['alpha'] = alpha == undefined ? 1 : alpha; + ///////////////////////////////////////// + // 일반 프로퍼티 + this['color'] = hexColor ? hexColor : '#ff0000'; + this['_UUID'] = RedGL.makeUUID(); + if (!checked) { + this.checkUniformAndProperty(); + checked = true; + } + console.log(this); + }; + RedOutlineMaterial.prototype = new RedBaseMaterial(); + RedOutlineMaterial['DEFINE_OBJECT_COLOR'] = { + get: function () { + return this['_colorHex'] + }, + set: (function () { + var t0; + return function (hex) { + this['_colorHex'] = hex ? hex : '#ff2211'; + t0 = RedGLUtil.hexToRGB_ZeroToOne.call(this, this['_colorHex']); + this['_color'][0] = t0[0]; + this['_color'][1] = t0[1]; + this['_color'][2] = t0[2]; + this['_color'][3] = this['_alpha']; + } + })() + }; + RedOutlineMaterial['DEFINE_OBJECT_ALPHA'] = { + 'min': 0, 'max': 1, + callback: function (v) { + this['_color'][3] = this['_alpha'] = v + } + }; + /*DOC: + { + code : 'PROPERTY', + title :`color`, + description : `기본값 : #ff2211`, + return : 'hex' + } + :DOC*/ + Object.defineProperty(RedOutlineMaterial.prototype, 'color', RedOutlineMaterial['DEFINE_OBJECT_COLOR']); + /*DOC: + { + code : 'PROPERTY', + title :`alpha`, + description : ` + 기본값 : 1 + 최소값 : 0 + 최대값 : 1 + `, + return : 'Number' + } + :DOC*/ + RedDefinePropertyInfo.definePrototype('RedOutlineMaterial', 'alpha', 'number', RedOutlineMaterial['DEFINE_OBJECT_ALPHA']); + Object.freeze(RedOutlineMaterial); +})(); \ No newline at end of file diff --git a/src/material/system/RedOutlinePlaneMaterial.js b/src/material/system/RedOutlinePlaneMaterial.js new file mode 100644 index 00000000..4def3254 --- /dev/null +++ b/src/material/system/RedOutlinePlaneMaterial.js @@ -0,0 +1,166 @@ +/* + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.7.11 18:28:15 + * + */ + +"use strict"; +var RedOutlinePlaneMaterial; +(function () { + var vSource, fSource; + var PROGRAM_NAME = 'RedOutlinePlaneMaterialProgram'; + var PROGRAM_OPTION_LIST = []; + var checked; + vSource = function () { + /* @preserve + // 스키닝 + //#REDGL_DEFINE#vertexShareFunc#getSkinMatrix# + + // Sprite3D + //#REDGL_DEFINE#vertexShareFunc#getSprite3DMatrix# + void main(void) { + gl_PointSize = uPointSize; + float outlineSize = uOutlineThickness; + + // position 계산 + //#REDGL_DEFINE#skin#true# mat4 targetMatrix = uMMatrix * getSkinMatrix() ; + //#REDGL_DEFINE#skin#false# mat4 targetMatrix = uMMatrix; + vVertexPosition = targetMatrix * vec4(aVertexPosition, 1.0); + float tScaleX = length(vec3(targetMatrix[0][0], targetMatrix[0][1], targetMatrix[0][2])); + float tScaleY = length(vec3(targetMatrix[1][0], targetMatrix[1][1], targetMatrix[1][2])); + float tScaleZ = length(vec3(targetMatrix[2][0], targetMatrix[2][1], targetMatrix[2][2])); + + //#REDGL_DEFINE#sprite3D#true# gl_Position = uPMatrix * getSprite3DMatrix(uCameraMatrix , targetMatrix) * vec4(aVertexPosition, 1.0); + //#REDGL_DEFINE#sprite3D#true# if(!u_PerspectiveScale){ + //#REDGL_DEFINE#sprite3D#true# gl_Position /= gl_Position.w; + //#REDGL_DEFINE#sprite3D#true# gl_Position.xy += aVertexPosition.xy * vec2((uPMatrix * targetMatrix)[0][0],(uPMatrix * targetMatrix)[1][1]); + //#REDGL_DEFINE#sprite3D#true# } + //#REDGL_DEFINE#sprite3D#false# gl_Position = uPMatrix * uCameraMatrix * targetMatrix * vec4(aVertexPosition * vec3(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY,1.0+outlineSize/tScaleZ) , 1.0); + vTexcoord = aTexcoord-0.5; + vTexcoord *= vec2(1.0+outlineSize/tScaleX,1.0+outlineSize/tScaleY); + + + //#REDGL_DEFINE#directionalShadow#true# vResolution = uResolution; + //#REDGL_DEFINE#directionalShadow#true# vShadowPos = cTexUnitConverter * uDirectionalShadowLightMatrix * targetMatrix * vec4(aVertexPosition, 1.0); + } + */ + }; + fSource = function () { + /* @preserve + precision mediump float; + // 안개 + //#REDGL_DEFINE#fragmentShareFunc#fogFactor# + //#REDGL_DEFINE#fragmentShareFunc#fog# + + // 그림자 + //#REDGL_DEFINE#fragmentShareFunc#decodeFloatShadow# + //#REDGL_DEFINE#fragmentShareFunc#getShadowColor# + + void main(void) { + vec4 finalColor = uOutlineColor; + if(-0.495 + + + + + RedGL TestCase - RedBaseFlter + + + + + + + + +

TODO

+ + + \ No newline at end of file diff --git a/testCase/object3D/RedMesh.js b/testCase/object3D/RedMesh.js index ac2c20da..868b4f25 100644 --- a/testCase/object3D/RedMesh.js +++ b/testCase/object3D/RedMesh.js @@ -1,8 +1,9 @@ /* - * RedGL - MIT License - * Copyright (c) 2018 - 2019 By RedCamel(webseon@gmail.com) - * https://github.com/redcamel/RedGL2/blob/dev/LICENSE - * Last modification time of this file - 2019.4.30 18:53 + * RedGL - MIT License + * Copyright (c) 2018 - 2019 By RedCamel( webseon@gmail.com ) + * https://github.com/redcamel/RedGL2/blob/dev/LICENSE + * Last modification time of this file - 2019.8.2 18:16:21 + * */ "use strict"; @@ -235,6 +236,174 @@ RedGL(document.createElement('canvas'), function () { ); } ); + RedTest.testGroup( + "(RedBaseObject3D extended Instance).addFilter( filter )", + function () { + RedTest.test( + "실패테스트 : 미입력", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + try { + t0.addFilter(null); + RedTest.run(true); + + } catch (error) { + RedTest.run(false, error); + + } + + }, + false + ); + RedTest.test( + "성공테스트 : RedBaseFilter 확장 인스턴스 입력", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + var tFilter0 = RedFilter_Gray(tRedGL); + t0.addFilter(tFilter0); + RedTest.run(t0['_filterList'][0] === tFilter0); + + + }, + true + ); + RedTest.test( + "실패테스트 : 문자입력", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + try { + t0.addFilter('failTest'); + RedTest.run(true); + + } catch (error) { + RedTest.run(false, error); + + } + + }, + false + ); + RedTest.test( + "성공테스트 : 추가후 _filterList.length 정상적으로 늘어나는지 확인", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + var tFilter0 = RedFilter_Gray(tRedGL); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + RedTest.run(t0['_filterList'].length); + + + }, 2) + } + ); + RedTest.testGroup( + "(RedBaseObject3D extended Instance).removeFilter( filter )", + function () { + RedTest.test( + "성공테스트 : 동작 확인", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + var tFilter0 = RedFilter_Gray(tRedGL); + t0.addFilter(tFilter0); + t0.removeFilter(tFilter0); + RedTest.run(t0['_filterList'].length); + + + }, 0); + RedTest.test( + "성공테스트 : 미입력 해도 에러가 안나야함", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + try { + t0.removeFilter(); + RedTest.run(true); + + } catch (error) { + RedTest.run(false, error); + + } + + }, + true + ); + RedTest.test( + "성공테스트 : _filterList에 없는 녀석을 제거를 시도해도 에러가 안나야함", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + var tFilter0 = RedFilter_Gray(tRedGL); + t0.addFilter(tFilter0); + t0.removeFilter(RedFilter_Threshold(tRedGL)); + RedTest.run(t0['_filterList'].length); + + + }, 1) + } + ); + RedTest.testGroup( + "(RedBaseObject3D extended Instance).removeAllFilter()", + function () { + RedTest.test( + "동작 확인", + function () { + + var t0 = RedMesh( + tRedGL, + RedBox(tRedGL), + RedColorMaterial(tRedGL) + ); + var tFilter0 = RedFilter_Gray(tRedGL); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + t0.addFilter(tFilter0); + console.log(t0['_filterList'].length); + t0.removeAllFilter(); + RedTest.run(t0['_filterList'].length); + + + }, 0) + } + ); } ); }