(function (global, factory) { if (typeof define === "function" && define.amd) { define(["exports", "three"], factory); } else if (typeof exports !== "undefined") { factory(exports, require("three")); } else { var mod = { exports: {} }; factory(mod.exports, global.three); global.Lensflare = mod.exports; } })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _three) { "use strict"; Object.defineProperty(_exports, "__esModule", { value: true }); _exports.LensflareElement = _exports.Lensflare = void 0; function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } Object.defineProperty(subClass, "prototype", { value: Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }), writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var Lensflare = /*#__PURE__*/function (_Mesh) { _inherits(Lensflare, _Mesh); var _super = _createSuper(Lensflare); function Lensflare() { var _this; _classCallCheck(this, Lensflare); _this = _super.call(this, Lensflare.Geometry, new _three.MeshBasicMaterial({ opacity: 0, transparent: true })); _this.type = 'Lensflare'; _this.frustumCulled = false; _this.renderOrder = Infinity; // var positionScreen = new _three.Vector3(); var positionView = new _three.Vector3(); // textures var tempMap = new _three.DataTexture(new Uint8Array(16 * 16 * 3), 16, 16, _three.RGBFormat); tempMap.minFilter = _three.NearestFilter; tempMap.magFilter = _three.NearestFilter; tempMap.wrapS = _three.ClampToEdgeWrapping; tempMap.wrapT = _three.ClampToEdgeWrapping; var occlusionMap = new _three.DataTexture(new Uint8Array(16 * 16 * 3), 16, 16, _three.RGBFormat); occlusionMap.minFilter = _three.NearestFilter; occlusionMap.magFilter = _three.NearestFilter; occlusionMap.wrapS = _three.ClampToEdgeWrapping; occlusionMap.wrapT = _three.ClampToEdgeWrapping; // material var geometry = Lensflare.Geometry; var material1a = new _three.RawShaderMaterial({ uniforms: { 'scale': { value: null }, 'screenPosition': { value: null } }, vertexShader: /* glsl */ "\n\n\t\t\t\tprecision highp float;\n\n\t\t\t\tuniform vec3 screenPosition;\n\t\t\t\tuniform vec2 scale;\n\n\t\t\t\tattribute vec3 position;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tgl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );\n\n\t\t\t\t}", fragmentShader: /* glsl */ "\n\n\t\t\t\tprecision highp float;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tgl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );\n\n\t\t\t\t}", depthTest: true, depthWrite: false, transparent: false }); var material1b = new _three.RawShaderMaterial({ uniforms: { 'map': { value: tempMap }, 'scale': { value: null }, 'screenPosition': { value: null } }, vertexShader: /* glsl */ "\n\n\t\t\t\tprecision highp float;\n\n\t\t\t\tuniform vec3 screenPosition;\n\t\t\t\tuniform vec2 scale;\n\n\t\t\t\tattribute vec3 position;\n\t\t\t\tattribute vec2 uv;\n\n\t\t\t\tvarying vec2 vUV;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvUV = uv;\n\n\t\t\t\t\tgl_Position = vec4( position.xy * scale + screenPosition.xy, screenPosition.z, 1.0 );\n\n\t\t\t\t}", fragmentShader: /* glsl */ "\n\n\t\t\t\tprecision highp float;\n\n\t\t\t\tuniform sampler2D map;\n\n\t\t\t\tvarying vec2 vUV;\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tgl_FragColor = texture2D( map, vUV );\n\n\t\t\t\t}", depthTest: false, depthWrite: false, transparent: false }); // the following object is used for occlusionMap generation var mesh1 = new _three.Mesh(geometry, material1a); // var elements = []; var shader = LensflareElement.Shader; var material2 = new _three.RawShaderMaterial({ uniforms: { 'map': { value: null }, 'occlusionMap': { value: occlusionMap }, 'color': { value: new _three.Color(0xffffff) }, 'scale': { value: new _three.Vector2() }, 'screenPosition': { value: new _three.Vector3() } }, vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader, blending: _three.AdditiveBlending, transparent: true, depthWrite: false }); var mesh2 = new _three.Mesh(geometry, material2); _this.addElement = function (element) { elements.push(element); }; // var scale = new _three.Vector2(); var screenPositionPixels = new _three.Vector2(); var validArea = new _three.Box2(); var viewport = new _three.Vector4(); _this.onBeforeRender = function (renderer, scene, camera) { renderer.getCurrentViewport(viewport); var invAspect = viewport.w / viewport.z; var halfViewportWidth = viewport.z / 2.0; var halfViewportHeight = viewport.w / 2.0; var size = 16 / viewport.w; scale.set(size * invAspect, size); validArea.min.set(viewport.x, viewport.y); validArea.max.set(viewport.x + (viewport.z - 16), viewport.y + (viewport.w - 16)); // calculate position in screen space positionView.setFromMatrixPosition(this.matrixWorld); positionView.applyMatrix4(camera.matrixWorldInverse); if (positionView.z > 0) return; // lensflare is behind the camera positionScreen.copy(positionView).applyMatrix4(camera.projectionMatrix); // horizontal and vertical coordinate of the lower left corner of the pixels to copy screenPositionPixels.x = viewport.x + positionScreen.x * halfViewportWidth + halfViewportWidth - 8; screenPositionPixels.y = viewport.y + positionScreen.y * halfViewportHeight + halfViewportHeight - 8; // screen cull if (validArea.containsPoint(screenPositionPixels)) { // save current RGB to temp texture renderer.copyFramebufferToTexture(screenPositionPixels, tempMap); // render pink quad var uniforms = material1a.uniforms; uniforms['scale'].value = scale; uniforms['screenPosition'].value = positionScreen; renderer.renderBufferDirect(camera, null, geometry, material1a, mesh1, null); // copy result to occlusionMap renderer.copyFramebufferToTexture(screenPositionPixels, occlusionMap); // restore graphics uniforms = material1b.uniforms; uniforms['scale'].value = scale; uniforms['screenPosition'].value = positionScreen; renderer.renderBufferDirect(camera, null, geometry, material1b, mesh1, null); // render elements var vecX = -positionScreen.x * 2; var vecY = -positionScreen.y * 2; for (var i = 0, l = elements.length; i < l; i++) { var element = elements[i]; var _uniforms = material2.uniforms; _uniforms['color'].value.copy(element.color); _uniforms['map'].value = element.texture; _uniforms['screenPosition'].value.x = positionScreen.x + vecX * element.distance; _uniforms['screenPosition'].value.y = positionScreen.y + vecY * element.distance; size = element.size / viewport.w; var _invAspect = viewport.w / viewport.z; _uniforms['scale'].value.set(size * _invAspect, size); material2.uniformsNeedUpdate = true; renderer.renderBufferDirect(camera, null, geometry, material2, mesh2, null); } } }; _this.dispose = function () { material1a.dispose(); material1b.dispose(); material2.dispose(); tempMap.dispose(); occlusionMap.dispose(); for (var i = 0, l = elements.length; i < l; i++) { elements[i].texture.dispose(); } }; return _this; } return _createClass(Lensflare); }(_three.Mesh); _exports.Lensflare = Lensflare; Lensflare.prototype.isLensflare = true; // var LensflareElement = /*#__PURE__*/_createClass(function LensflareElement(texture) { var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; var distance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var color = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new _three.Color(0xffffff); _classCallCheck(this, LensflareElement); this.texture = texture; this.size = size; this.distance = distance; this.color = color; }); _exports.LensflareElement = LensflareElement; LensflareElement.Shader = { uniforms: { 'map': { value: null }, 'occlusionMap': { value: null }, 'color': { value: null }, 'scale': { value: null }, 'screenPosition': { value: null } }, vertexShader: /* glsl */ "\n\n\t\tprecision highp float;\n\n\t\tuniform vec3 screenPosition;\n\t\tuniform vec2 scale;\n\n\t\tuniform sampler2D occlusionMap;\n\n\t\tattribute vec3 position;\n\t\tattribute vec2 uv;\n\n\t\tvarying vec2 vUV;\n\t\tvarying float vVisibility;\n\n\t\tvoid main() {\n\n\t\t\tvUV = uv;\n\n\t\t\tvec2 pos = position.xy;\n\n\t\t\tvec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\n\t\t\tvisibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\n\n\t\t\tvVisibility = visibility.r / 9.0;\n\t\t\tvVisibility *= 1.0 - visibility.g / 9.0;\n\t\t\tvVisibility *= visibility.b / 9.0;\n\n\t\t\tgl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n\n\t\t}", fragmentShader: /* glsl */ "\n\n\t\tprecision highp float;\n\n\t\tuniform sampler2D map;\n\t\tuniform vec3 color;\n\n\t\tvarying vec2 vUV;\n\t\tvarying float vVisibility;\n\n\t\tvoid main() {\n\n\t\t\tvec4 texture = texture2D( map, vUV );\n\t\t\ttexture.a *= vVisibility;\n\t\t\tgl_FragColor = texture;\n\t\t\tgl_FragColor.rgb *= color;\n\n\t\t}" }; Lensflare.Geometry = function () { var geometry = new _three.BufferGeometry(); var float32Array = new Float32Array([-1, -1, 0, 0, 0, 1, -1, 0, 1, 0, 1, 1, 0, 1, 1, -1, 1, 0, 0, 1]); var interleavedBuffer = new _three.InterleavedBuffer(float32Array, 5); geometry.setIndex([0, 1, 2, 0, 2, 3]); geometry.setAttribute('position', new _three.InterleavedBufferAttribute(interleavedBuffer, 3, 0, false)); geometry.setAttribute('uv', new _three.InterleavedBufferAttribute(interleavedBuffer, 2, 3, false)); return geometry; }(); });