UNPKG

@tresjs/post-processing

Version:
1,555 lines (1,496 loc) 151 kB
/** * name: @tresjs/post-processing * version: v2.3.1 * (c) 2025 * description: Post-processing library for TresJS * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/) */ import { defineComponent as u, shallowRef as W, provide as Be, computed as L, watch as S, onUnmounted as U, renderSlot as Ne, inject as te, watchEffect as x, nextTick as oe, toRaw as ie } from "vue"; import { EffectComposer as ne, RenderPass as Ve, NormalPass as Ye, DepthDownsamplingPass as ke, EffectPass as qe, BloomEffect as le, DepthOfFieldEffect as ue, GlitchEffect as X, GlitchMode as Qe, NoiseEffect as ce, OutlineEffect as de, PixelationEffect as fe, VignetteEffect as he, Effect as q, BlendFunction as Q, ToneMappingEffect as pe, ChromaticAberrationEffect as K, HueSaturationEffect as me, ScanlineEffect as J, ColorAverageEffect as Z, LensDistortionEffect as ve, ShockWaveEffect as ge, TiltShiftEffect as xe, DotScreenEffect as be, SepiaEffect as Se, DepthPickingPass as Ke, GodRaysEffect as _, ColorDepthEffect as I, GridEffect as we, BrightnessContrastEffect as Ae } from "postprocessing"; import { useTresContext as y, useLoop as G, normalizeColor as $ } from "@tresjs/core"; import { HalfFloatType as T, Uniform as M, Vector2 as d, Vector3 as O, Mesh as ze, SphereGeometry as Je, MeshBasicMaterial as We, OrthographicCamera as Ze, BufferGeometry as _e, Float32BufferAttribute as ye, ShaderMaterial as A, UniformsUtils as P, WebGLRenderTarget as D, NoBlending as $e, Clock as et, Color as k, MathUtils as w, DataTexture as tt, RedFormat as ot, FloatType as st, MeshNormalMaterial as at, NearestFilter as F, DepthTexture as rt, Vector4 as it, RawShaderMaterial as nt, ColorManagement as lt, SRGBTransfer as ut, LinearToneMapping as ct, ReinhardToneMapping as dt, CineonToneMapping as ft, ACESFilmicToneMapping as ht, AgXToneMapping as pt, NeutralToneMapping as mt, CustomToneMapping as vt, Texture as Me, LinearFilter as gt, AdditiveBlending as xt } from "three"; import { useDevicePixelRatio as Ue } from "@vueuse/core"; class Te { static isWebGL2Available() { try { const e = document.createElement("canvas"); return !!(window.WebGL2RenderingContext && e.getContext("webgl2")); } catch { return !1; } } static isColorSpaceAvailable(e) { try { const t = document.createElement("canvas"), o = window.WebGL2RenderingContext && t.getContext("webgl2"); return o.drawingBufferColorSpace = e, o.drawingBufferColorSpace === e; } catch { return !1; } } static getWebGL2ErrorMessage() { return this.getErrorMessage(2); } static getErrorMessage(e) { const t = { 1: "WebGL", 2: "WebGL 2" }, o = { 1: window.WebGLRenderingContext, 2: window.WebGL2RenderingContext }; let s = 'Your $0 does not seem to support <a href="http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation" style="color:#000">$1</a>'; const a = document.createElement("div"); return a.id = "webglmessage", a.style.fontFamily = "monospace", a.style.fontSize = "13px", a.style.fontWeight = "normal", a.style.textAlign = "center", a.style.background = "#fff", a.style.color = "#000", a.style.padding = "1.5em", a.style.width = "400px", a.style.margin = "5em auto 0", o[e] ? s = s.replace("$0", "graphics card") : s = s.replace("$0", "browser"), s = s.replace("$1", t[e]), a.innerHTML = s, a; } // @deprecated, r168 static isWebGLAvailable() { console.warn("isWebGLAvailable() has been deprecated and will be removed in r178. Use isWebGL2Available() instead."); try { const e = document.createElement("canvas"); return !!(window.WebGLRenderingContext && (e.getContext("webgl") || e.getContext("experimental-webgl"))); } catch { return !1; } } static getWebGLErrorMessage() { return console.warn("getWebGLErrorMessage() has been deprecated and will be removed in r178. Use getWebGL2ErrorMessage() instead."), this.getErrorMessage(1); } } const se = Symbol("effectComposerPmndrs"), Gt = /* @__PURE__ */ u({ __name: "EffectComposerPmndrs", props: { enabled: { type: Boolean, default: !0 }, depthBuffer: { type: Boolean, default: void 0 }, disableNormalPass: { type: Boolean, default: !1 }, stencilBuffer: { type: Boolean, default: void 0 }, resolutionScale: {}, autoClear: { type: Boolean, default: !0 }, multisampling: { default: 0 }, frameBufferType: { default: T } }, emits: ["render"], setup(r, { expose: e, emit: t }) { const o = r, s = t, { scene: a, camera: i, renderer: n, sizes: l, render: f } = y(), h = W(null); let v = null, c = null; Be(se, h), e({ composer: h }); const b = () => { h.value && (c = new Ye(a.value, i.value), c.enabled = !1, h.value.addPass(c), o.resolutionScale !== void 0 && Te.isWebGL2Available() && (v = new ke({ normalBuffer: c.texture, resolutionScale: o.resolutionScale }), v.enabled = !1, h.value.addPass(v))); }, E = L(() => { const g = new ne(), z = { depthBuffer: o.depthBuffer !== void 0 ? o.depthBuffer : g.inputBuffer.depthBuffer, stencilBuffer: o.stencilBuffer !== void 0 ? o.stencilBuffer : g.inputBuffer.stencilBuffer, multisampling: Te.isWebGL2Available() ? o.multisampling !== void 0 ? o.multisampling : g.multisampling : 0, frameBufferType: o.frameBufferType !== void 0 ? o.frameBufferType : T }; return g.dispose(), z; }), re = () => { var g; !n.value && !a.value && !i.value || ((g = h.value) == null || g.dispose(), h.value = new ne(n.value, E.value), h.value.addPass(new Ve(a.value, i.value)), o.disableNormalPass || b()); }; S([n, a, i, () => o.disableNormalPass], () => { !l.width.value || !l.height.value || re(); }), S(() => [l.width.value, l.height.value], ([g, z]) => { !g && !z || (h.value ? h.value.setSize(g, z) : re()); }, { immediate: !0 }); const { render: je } = G(); return je(() => { if (o.enabled && n.value && h.value && l.width.value && l.height.value && f.frames.value > 0) { const g = n.value.autoClear; n.value.autoClear = o.autoClear, o.stencilBuffer && !o.autoClear && n.value.clearStencil(), h.value.render(), s("render", h.value), n.value.autoClear = g; } f.frames.value = f.mode.value === "always" ? 1 : Math.max(0, f.frames.value - 1); }), U(() => { var g; (g = h.value) == null || g.dispose(); }), (g, z) => Ne(g.$slots, "default"); } }), p = (r, e, t) => { const o = te(se), s = W(null), a = W(null), { scene: i, camera: n, invalidate: l } = y(); S(e, () => l()); const f = () => { var c, b, E; s.value && ((c = o == null ? void 0 : o.value) == null || c.removePass(s.value)), (b = a.value) == null || b.dispose(), (E = s.value) == null || E.dispose(); }, h = (c) => { !n.value || !(o != null && o.value) || !i.value || (a.value = r(), s.value = new qe(n.value, a.value), o.value.addPass(s.value, c)); }; t && S( () => t.map((c) => e[c]), () => { var b; if (!(o != null && o.value)) return; const c = (b = o.value) == null ? void 0 : b.passes.findIndex((E) => E === s.value); ~c && (f(), h(c)); } ), x(() => { !n.value || !(a != null && a.value) || (a.value.mainCamera = n.value); }); const v = x(() => { !n.value || !(o != null && o.value) || !i.value || (oe(() => v()), !a.value && h()); }); return U(() => { f(); }), { pass: s, effect: a }; }, Ge = /([^[.\]])+/g, bt = (r, e) => { if (!e) return; const t = Array.isArray(e) ? e : e.match(Ge); return t == null ? void 0 : t.reduce((o, s) => o && o[s], r); }, Ce = (r, e, t) => { const o = Array.isArray(e) ? e : e.match(Ge); o && o.reduce((s, a, i) => (s[a] === void 0 && (s[a] = {}), i === o.length - 1 && (s[a] = t), s[a]), r); }, St = (r, e) => { const t = { ...r }; return e.forEach((o) => delete t[o]), t; }, H = (r, e, t, o, s = {}) => S(r, (a) => { var i; if (e.value) if (a === void 0) { const n = o(); Ce(e.value, t, bt(n, t)), (i = n.dispose) == null || i.call(n); } else Ce(e.value, t, r()); }, s), m = (r, e, t) => r.map(([o, s]) => H( o, e, s, t )), ae = (r, e, t) => Object.keys(r).map((o) => H( () => r[o], e, o, t )), Ht = /* @__PURE__ */ u({ __name: "BloomPmndrs", props: { blendFunction: {}, intensity: {}, kernelSize: {}, luminanceThreshold: {}, luminanceSmoothing: {}, mipmapBlur: { type: Boolean, default: void 0 } }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new le(t), t, ["mipmapBlur"]); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.intensity, "intensity"], [() => t.kernelSize, "kernelSize"], [() => t.luminanceSmoothing, "luminanceMaterial.smoothing"], [() => t.luminanceThreshold, "luminanceMaterial.threshold"] ], s, () => new le() ), () => { }; } }), Xt = /* @__PURE__ */ u({ __name: "DepthOfFieldPmndrs", props: { blendFunction: {}, worldFocusDistance: {}, worldFocusRange: {}, focusDistance: {}, focusRange: {}, bokehScale: {}, resolutionScale: {}, resolutionX: {}, resolutionY: {} }, setup(r, { expose: e }) { const t = r, { camera: o } = y(), { pass: s, effect: a } = p(() => new ue(o.value, t), t); return e({ pass: s, effect: a }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.worldFocusDistance, "circleOfConfusionMaterial.worldFocusDistance"], [() => t.focusDistance, "circleOfConfusionMaterial.focusDistance"], [() => t.worldFocusRange, "circleOfConfusionMaterial.worldFocusRange"], [() => t.focusRange, "circleOfConfusionMaterial.focusRange"], [() => t.bokehScale, "bokehScale"], [() => t.resolutionScale, "blurPass.resolution.scale"], [() => t.resolutionX, "resolution.width"], [() => t.resolutionY, "resolution.height"] ], a, () => new ue() ), () => { }; } }), It = /* @__PURE__ */ u({ __name: "GlitchPmndrs", props: { blendFunction: {}, delay: {}, duration: {}, strength: {}, mode: {}, active: { type: Boolean }, ratio: {}, columns: {}, chromaticAberrationOffset: {}, perturbationMap: {}, dtSize: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new X(t), t, ["dtSize"]); e({ pass: o, effect: s }); const { onBeforeRender: a } = G(); return a(({ invalidate: i }) => i()), x(() => { const i = () => { if (t.mode !== void 0) return t.active === !1 ? Qe.DISABLED : t.mode; const n = new X(), l = n.mode; return n.dispose(), l; }; s.value && (s.value.mode = i()); }), H( () => t.blendFunction, s, "blendMode.blendFunction", () => new X() ), ae( St(t, ["active", "blendFunction"]), s, () => new X() ), () => { }; } }), jt = /* @__PURE__ */ u({ __name: "NoisePmndrs", props: { premultiply: { type: Boolean, default: void 0 }, blendFunction: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new ce(t), t); e({ pass: o, effect: s }); const { onBeforeRender: a } = G(); return a(({ invalidate: i }) => i()), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.premultiply, "premultiply"] ], s, () => new ce() ), () => { }; } }), Vt = /* @__PURE__ */ u({ __name: "OutlinePmndrs", props: { outlinedObjects: {}, blur: { type: Boolean, default: void 0 }, xRay: { type: Boolean, default: void 0 }, kernelSize: {}, pulseSpeed: {}, resolutionX: {}, resolutionY: {}, edgeStrength: {}, patternScale: {}, multisampling: {}, blendFunction: {}, patternTexture: {}, resolutionScale: {}, hiddenEdgeColor: {}, visibleEdgeColor: {} }, setup(r, { expose: e }) { const t = r, o = (f) => f !== void 0 ? $(f).getHex() : void 0, { camera: s, scene: a } = y(), { pass: i, effect: n } = p( () => new de( a.value, s.value, { blur: t.blur, xRay: t.xRay, kernelSize: t.kernelSize, pulseSpeed: t.pulseSpeed, resolutionX: t.resolutionX, resolutionY: t.resolutionY, patternScale: t.patternScale, edgeStrength: t.edgeStrength, blendFunction: t.blendFunction, multisampling: t.multisampling, patternTexture: t.patternTexture, resolutionScale: t.resolutionScale, hiddenEdgeColor: o(t.hiddenEdgeColor), visibleEdgeColor: o(t.visibleEdgeColor) // width and height are explicitly omitted, because they are deprecated in postprocessing's OutlineEffect } ), t ); e({ pass: i, effect: n }), S( [() => t.outlinedObjects, n], // watchEffect is intentionally not used here as it would result in an endless loop () => { var f; (f = n.value) == null || f.selection.set(t.outlinedObjects || []); }, { immediate: !0 } ); const l = L(() => ({ hiddenEdgeColor: t.hiddenEdgeColor ? $(t.hiddenEdgeColor) : void 0, visibleEdgeColor: t.visibleEdgeColor ? $(t.visibleEdgeColor) : void 0 })); return m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.blur, "blur"], [() => t.xRay, "xRay"], [() => t.pulseSpeed, "pulseSpeed"], [() => t.kernelSize, "kernelSize"], [() => t.edgeStrength, "edgeStrength"], [() => t.patternScale, "patternScale"], [() => t.multisampling, "multisampling"], [() => t.resolutionX, "resolution.width"], [() => t.resolutionY, "resolution.height"], [() => t.patternTexture, "patternTexture"], [() => t.resolutionScale, "resolution.scale"], [() => l.value.hiddenEdgeColor, "hiddenEdgeColor"], [() => l.value.visibleEdgeColor, "visibleEdgeColor"] ], n, () => new de() ), () => { }; } }), Yt = /* @__PURE__ */ u({ __name: "PixelationPmndrs", props: { granularity: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new fe(t.granularity), t); return e({ pass: o, effect: s }), ae( t, s, () => new fe() ), () => { }; } }), kt = /* @__PURE__ */ u({ __name: "VignettePmndrs", props: { technique: {}, blendFunction: {}, offset: {}, darkness: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new he(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.offset, "offset"], [() => t.darkness, "darkness"], [() => t.technique, "technique"] ], s, () => new he() ), () => { }; } }); class Ee extends q { /** * Creates a new BarrelBlurEffect instance. * * @param {object} [options] - Configuration options for the effect. * @param {BlendFunction} [options.blendFunction] - Blend mode. * @param {number} [options.amount] - Intensity of the barrel distortion (0 to 1). * @param {Vector2} [options.offset] - Offset of the barrel distortion center (0 to 1 for both x and y). This allows you to change the position of the distortion effect. * */ constructor({ blendFunction: e = Q.NORMAL, amount: t = 0.15, offset: o = new d(0.5, 0.5) } = {}) { super("BarrelBlurEffect", ` uniform float amount; uniform vec2 offset; #define NUM_ITER 16 #define RECIP_NUM_ITER 0.0625 #define GAMMA 1.0 vec3 spectrum_offset(float t) { float lo = step(t, 0.5); float hi = 1.0 - lo; float w = 1.0 - abs(2.0 * t - 1.0); return pow(vec3(lo, 1.0, hi) * vec3(1.0 - w, w, 1.0 - w), vec3(1.0 / GAMMA)); } vec2 barrelDistortion(vec2 p, float amt) { p = p - offset; float theta = atan(p.y, p.x); float radius = pow(length(p), 1.0 + 3.0 * amt); return vec2(cos(theta), sin(theta)) * radius + offset; } void mainUv(inout vec2 uv) { uv = barrelDistortion(uv, amount * 0.5); } void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { vec3 sumcol = vec3(0.0); vec3 sumw = vec3(0.0); for (int i = 0; i < NUM_ITER; ++i) { float t = float(i) * RECIP_NUM_ITER; vec3 w = spectrum_offset(t); vec2 distortedUV = barrelDistortion(uv, amount * t); sumcol += w * texture(inputBuffer, distortedUV).rgb; sumw += w; } vec3 outcol = pow(sumcol / sumw, vec3(1.0 / GAMMA)); outcol = clamp(outcol, 0.0, 1.0); // Ensures normalized color values outputColor = vec4(outcol, inputColor.a); // Preserves original alpha } `, { blendFunction: e, uniforms: /* @__PURE__ */ new Map([ ["amount", new M(t)], // Uniform controlling the intensity of distortion ["offset", new M(o)] // Uniform controlling the offset of distortion ]) }); } /** * The amount. * * @type {number} */ get amount() { var e; return (e = this.uniforms.get("amount")) == null ? void 0 : e.value; } set amount(e) { this.uniforms.get("amount").value = e; } /** * The offset. * * @type {Vector2} */ get offset() { var e; return (e = this.uniforms.get("offset")) == null ? void 0 : e.value; } set offset(e) { this.uniforms.get("offset").value = e; } } const qt = /* @__PURE__ */ u({ __name: "BarrelBlurPmndrs", props: { blendFunction: {}, amount: {}, offset: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p( () => new Ee({ ...t, offset: Array.isArray(t.offset) ? new d(...t.offset) : t.offset }), t ); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.amount, "amount"], [() => t.offset, "offset"] ], s, () => new Ee() ), () => { }; } }), Qt = /* @__PURE__ */ u({ __name: "ToneMappingPmndrs", props: { mode: {}, blendFunction: {}, resolution: {}, averageLuminance: {}, middleGrey: {}, minLuminance: {}, whitePoint: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new pe(t), t); return e({ pass: o, effect: s }), m( [ [() => t.mode, "mode"], [() => t.blendFunction, "blendMode.blendFunction"], [() => t.resolution, "resolution"], [() => t.averageLuminance, "averageLuminance"], [() => t.middleGrey, "middleGrey"], [() => t.minLuminance, "adaptiveLuminanceMaterial.minLuminance"], [() => t.whitePoint, "whitePoint"] ], s, () => new pe() ), () => { }; } }), Kt = /* @__PURE__ */ u({ __name: "ChromaticAberrationPmndrs", props: { blendFunction: {}, offset: {}, radialModulation: { type: Boolean, default: void 0 }, modulationOffset: {} }, setup(r, { expose: e }) { const t = r, o = new K(), { pass: s, effect: a } = p(() => new K({ ...t, // Unfortunately, these defaults must be set this way as the type in postprocessing is not correct. // The arguments are optional in the actual constructor, but not in the type. radialModulation: t.radialModulation ?? o.radialModulation, modulationOffset: t.modulationOffset ?? o.modulationOffset }), t); return o.dispose(), e({ pass: s, effect: a }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.offset, "offset"], [() => t.radialModulation, "radialModulation"], [() => t.modulationOffset, "modulationOffset"] ], a, () => new K() ), () => { }; } }), Jt = /* @__PURE__ */ u({ __name: "HueSaturationPmndrs", props: { saturation: {}, hue: {}, blendFunction: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new me(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.hue, "hue"], [() => t.saturation, "saturation"] ], s, () => new me() ), () => { }; } }), Zt = /* @__PURE__ */ u({ __name: "ScanlinePmndrs", props: { blendFunction: {}, density: {}, scrollSpeed: {}, opacity: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new J(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.density, "density"], [() => t.scrollSpeed, "scrollSpeed"] ], s, () => new J() ), S( [() => t.opacity], () => { var a, i; if (t.opacity !== void 0) (a = s.value) == null || a.blendMode.setOpacity(t.opacity); else { const n = new J(); (i = s.value) == null || i.blendMode.setOpacity(n.blendMode.getOpacity()), n.dispose(); } }, { immediate: !0 } ), () => { }; } }), wt = ` uniform float radius; uniform int sectorCount; const int MAX_SECTOR_COUNT = 8; float polynomialWeight(float x, float y, float eta, float lambda) { float polyValue = (x + eta) - lambda * (y * y); return max(0.0, polyValue * polyValue); } void getSectorVarianceAndAverageColor(mat2 anisotropyMat, float angle, float radius, out vec3 avgColor, out float variance) { vec3 weightedColorSum = vec3(0.0); vec3 weightedSquaredColorSum = vec3(0.0); float totalWeight = 0.0; float eta = 0.1; float lambda = 0.5; float angleStep = 0.196349; // Precompute angle step float halfAngleRange = 0.392699; // Precompute half angle range float cosAngle = cos(angle); float sinAngle = sin(angle); for (float r = 1.0; r <= radius; r += 1.0) { float rCosAngle = r * cosAngle; float rSinAngle = r * sinAngle; for (float a = -halfAngleRange; a <= halfAngleRange; a += angleStep) { float cosA = cos(a); float sinA = sin(a); vec2 sampleOffset = vec2(rCosAngle * cosA - rSinAngle * sinA, rCosAngle * sinA + rSinAngle * cosA) / resolution; sampleOffset *= anisotropyMat; vec3 color = texture2D(inputBuffer, vUv + sampleOffset).rgb; float weight = polynomialWeight(sampleOffset.x, sampleOffset.y, eta, lambda); weightedColorSum += color * weight; weightedSquaredColorSum += color * color * weight; totalWeight += weight; } } // Calculate average color and variance avgColor = weightedColorSum / totalWeight; vec3 varianceRes = (weightedSquaredColorSum / totalWeight) - (avgColor * avgColor); variance = dot(varianceRes, vec3(0.299, 0.587, 0.114)); // Convert to luminance } vec4 getDominantOrientation(vec4 structureTensor) { float Jxx = structureTensor.r; float Jyy = structureTensor.g; float Jxy = structureTensor.b; float trace = Jxx + Jyy; float det = Jxx * Jyy - Jxy * Jxy; float lambda1 = 0.5 * (trace + sqrt(trace * trace - 4.0 * det)); float lambda2 = 0.5 * (trace - sqrt(trace * trace - 4.0 * det)); float dominantOrientation = atan(2.0 * Jxy, Jxx - Jyy) / 2.0; return vec4(dominantOrientation, lambda1, lambda2, 0.0); } void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { vec4 structureTensor = texture2D(inputBuffer, uv); vec3 sectorAvgColors[MAX_SECTOR_COUNT]; float sectorVariances[MAX_SECTOR_COUNT]; vec4 orientationAndAnisotropy = getDominantOrientation(structureTensor); vec2 orientation = orientationAndAnisotropy.xy; float anisotropy = (orientationAndAnisotropy.z - orientationAndAnisotropy.w) / (orientationAndAnisotropy.z + orientationAndAnisotropy.w + 1e-7); float alpha = 25.0; float scaleX = alpha / (anisotropy + alpha); float scaleY = (anisotropy + alpha) / alpha; mat2 anisotropyMat = mat2(orientation.x, -orientation.y, orientation.y, orientation.x) * mat2(scaleX, 0.0, 0.0, scaleY); for (int i = 0; i < sectorCount; i++) { float angle = float(i) * 6.28318 / float(sectorCount); // 2π / sectorCount getSectorVarianceAndAverageColor(anisotropyMat, angle, float(radius), sectorAvgColors[i], sectorVariances[i]); } float minVariance = sectorVariances[0]; vec3 finalColor = sectorAvgColors[0]; for (int i = 1; i < sectorCount; i++) { if (sectorVariances[i] < minVariance) { minVariance = sectorVariances[i]; finalColor = sectorAvgColors[i]; } } outputColor = vec4(finalColor, inputColor.a); } `; class Pe extends q { /** * Creates a new KuwaharaEffect instance. * * @param {object} [options] - Configuration options for the effect. * @param {BlendFunction} [options.blendFunction] - Blend mode. * @param {number} [options.radius] - Intensity of the effect. * @param {number} [options.sectorCount] - Number of sectors. * */ constructor({ blendFunction: e = Q.NORMAL, radius: t = 1, sectorCount: o = 4 } = {}) { super("KuwaharaEffect", wt, { blendFunction: e, uniforms: /* @__PURE__ */ new Map([ ["radius", new M(t)], ["sectorCount", new M(o)] ]) }); } /** * The radius. * * @type {number} */ get radius() { var e; return (e = this.uniforms.get("radius")) == null ? void 0 : e.value; } set radius(e) { this.uniforms.get("radius").value = e; } /** * The sector count. * * @type {number} */ get sectorCount() { var e; return (e = this.uniforms.get("sectorCount")) == null ? void 0 : e.value; } set sectorCount(e) { this.uniforms.get("sectorCount").value = e; } } const _t = /* @__PURE__ */ u({ __name: "KuwaharaPmndrs", props: { blendFunction: {}, radius: {}, sectorCount: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p( () => new Pe(t), t ); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.radius, "radius"], [() => t.sectorCount, "sectorCount"] ], s, () => new Pe() ), () => { }; } }), $t = /* @__PURE__ */ u({ __name: "ColorAveragePmndrs", props: { blendFunction: {}, opacity: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new Z(t.blendFunction), t); return e({ pass: o, effect: s }), H( () => t.blendFunction, s, "blendMode.blendFunction", () => new Z() ), S( [s, () => t.opacity], () => { var a, i; if (s.value) if (t.opacity !== void 0) (a = s.value) == null || a.blendMode.setOpacity(t.opacity); else { const n = new Z(); (i = s.value) == null || i.blendMode.setOpacity(n.blendMode.getOpacity()), n.dispose(); } } ), () => { }; } }), eo = /* @__PURE__ */ u({ __name: "LensDistortionPmndrs", props: { distortion: {}, principalPoint: {}, focalLength: {}, skew: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p( () => new ve({ ...t, distortion: t.distortion ? Array.isArray(t.distortion) ? new d(...t.distortion) : t.distortion : new d(), principalPoint: t.principalPoint ? Array.isArray(t.principalPoint) ? new d(...t.principalPoint) : t.principalPoint : new d(), focalLength: t.focalLength ? Array.isArray(t.focalLength) ? new d(...t.focalLength) : t.focalLength : new d() }), t ); return e({ pass: o, effect: s }), ae( t, s, () => new ve() ), () => { }; } }), to = /* @__PURE__ */ u({ __name: "ShockWavePmndrs", props: { position: {}, amplitude: {}, speed: {}, maxRadius: {}, waveSize: {} }, setup(r, { expose: e }) { const t = r, { camera: o } = y(), { pass: s, effect: a } = p( () => new ge(o.value, Array.isArray(t.position) ? new O(...t.position) : t.position, t), t ); return e({ pass: s, effect: a }), S( () => t.position, (i) => { a.value && (Array.isArray(i) ? a.value.position.set(...i) : i instanceof O && a.value.position.copy(i)); }, { immediate: !0 } ), m( [ [() => t.amplitude, "amplitude"], [() => t.waveSize, "waveSize"], [() => t.maxRadius, "maxRadius"], [() => t.speed, "speed"] ], a, () => new ge() ), () => { }; } }), oo = /* @__PURE__ */ u({ __name: "TiltShiftPmndrs", props: { blendFunction: {}, offset: {}, rotation: {}, focusArea: {}, feather: {}, kernelSize: {}, resolutionScale: {}, resolutionX: {}, resolutionY: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new xe(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.offset, "offset"], [() => t.rotation, "rotation"], [() => t.focusArea, "focusArea"], [() => t.feather, "feather"], [() => t.kernelSize, "kernelSize"], [() => t.resolutionScale, "resolution.scale"], [() => t.resolutionX, "resolution.width"], [() => t.resolutionY, "resolution.height"] ], s, () => new xe() ), () => { }; } }), so = /* @__PURE__ */ u({ __name: "DotScreenPmndrs", props: { angle: {}, scale: {}, blendFunction: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new be(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.angle, "angle"], [() => t.scale, "scale"] ], s, () => new be() ), () => { }; } }), ao = /* @__PURE__ */ u({ __name: "SepiaPmndrs", props: { blendFunction: {}, intensity: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new Se(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.intensity, "intensity"] ], s, () => new Se() ), () => { }; } }); class De extends q { /** * Creates a new LinocutEffect instance. * * @param {LinocutPmndrsProps} [options] - Configuration options for the effect. * */ constructor({ blendFunction: e = Q.NORMAL, scale: t = 0.85, noiseScale: o = 0, center: s = [0.5, 0.5], rotation: a = 0 } = {}) { const i = Array.isArray(s) ? new d().fromArray(s) : s; super("LinocutEffect", ` uniform float scale; uniform float noiseScale; uniform vec2 center; uniform float rotation; float luma(vec3 color) { return dot(color, vec3(0.299, 0.587, 0.114)); } float luma(vec4 color) { return dot(color.rgb, vec3(0.299, 0.587, 0.114)); } // Simple pseudo-random noise function float noise(vec2 p) { return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453123); } void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { // Calculate the center based on center vec2 fragCoord = uv * resolution.xy; // Apply rotation to the coordinates vec2 d = fragCoord - center * resolution.xy; mat2 rotMat = mat2(cos(rotation), -sin(rotation), sin(rotation), cos(rotation)); vec2 rotatedD = d * rotMat; // Calculate radial distance and angle float r = length(rotatedD) / (1000.0 / max(scale, 0.01)); // Normalization to avoid artifacts float a = atan(rotatedD.y, rotatedD.x) + scale * (0.5 - r) / 0.5; // Calculate transformed coordinates vec2 uvt = center * resolution.xy + r * vec2(cos(a), sin(a)); // Normalize UV coordinates vec2 uv2 = fragCoord / resolution.xy; // Generate sinusoidal line patterns float c = (0.75 + 0.25 * sin(uvt.x * 1000.0 * max(scale, 0.01))); // Prevent excessive distortions // Load the texture and convert to grayscale vec4 color = texture(inputBuffer, uv2); color.rgb = color.rgb * color.rgb; // Convert from sRGB to linear float l = luma(color); // Add noise based on noiseScale float n = noise(uv2 * 10.0); // Generate noise l += noiseScale * (n - 0.5); // Apply noise as a perturbation // Apply smoothing to achieve the linocut effect float f = smoothstep(0.5 * c, c, l); f = smoothstep(0.0, 0.5, f); // Convert the final value back to sRGB f = sqrt(f); // Output the final color in black and white outputColor = vec4(vec3(f), 1.0); } `, { blendFunction: e, uniforms: /* @__PURE__ */ new Map([ ["scale", new M(t)], ["noiseScale", new M(o)], ["center", new M(i)], ["rotation", new M(a)] ]) }); } get scale() { var e; return (e = this.uniforms.get("scale")) == null ? void 0 : e.value; } set scale(e) { this.uniforms.get("scale").value = e; } get noiseScale() { var e; return (e = this.uniforms.get("noiseScale")) == null ? void 0 : e.value; } set noiseScale(e) { this.uniforms.get("noiseScale").value = e; } get center() { var e; return (e = this.uniforms.get("center")) == null ? void 0 : e.value; } set center(e) { this.uniforms.get("center").value = Array.isArray(e) ? new d().fromArray(e) : e; } get rotation() { var e; return (e = this.uniforms.get("rotation")) == null ? void 0 : e.value; } set rotation(e) { this.uniforms.get("rotation").value = e; } } const ro = /* @__PURE__ */ u({ __name: "LinocutPmndrs", props: { blendFunction: {}, scale: {}, noiseScale: {}, center: {}, rotation: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p( () => new De({ ...t, center: t.center instanceof d ? [t.center.x, t.center.y] : t.center }), t ); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.scale, "scale"], [() => t.noiseScale, "noiseScale"], [() => t.center, "center"], [() => t.rotation, "rotation"] ], s, () => new De() ), () => { }; } }), io = /* @__PURE__ */ u({ __name: "DepthPickingPassPmndrs", props: { depthPacking: {}, mode: {} }, setup(r, { expose: e }) { const t = r, o = te(se), s = new Ke(t), a = x(() => { o != null && o.value && (oe(() => a()), o.value.addPass(s)); }); return U(() => { var i; !(o != null && o.value) || !s || ((i = o == null ? void 0 : o.value) == null || i.removePass(s), s.dispose()); }), e({ pass: s }), () => { }; } }), no = /* @__PURE__ */ u({ __name: "GodRaysPmndrs", props: { blendFunction: {}, lightSource: {}, opacity: {}, density: {}, decay: {}, kernelSize: {}, resolutionScale: {}, blur: { type: Boolean }, resolutionX: {}, resolutionY: {}, weight: {}, exposure: {}, samples: {}, clampMax: {} }, setup(r, { expose: e }) { const t = r, { camera: o } = y(), s = L( () => t.lightSource ?? new ze( new Je(1e-5), new We({ visible: !1 }) ) ), { pass: a, effect: i } = p( () => new _(o.value, s.value, t), t ); return e({ pass: a, effect: i }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.density, "godRaysMaterial.density"], [() => t.decay, "godRaysMaterial.decay"], [() => t.weight, "godRaysMaterial.weight"], [() => t.exposure, "godRaysMaterial.exposure"], [() => t.samples, "godRaysMaterial.samples"], [() => t.clampMax, "godRaysMaterial.maxIntensity"], [() => t.resolutionScale, "resolution.scale"], [() => t.resolutionX, "resolution.width"], [() => t.resolutionY, "resolution.height"], [() => t.kernelSize, "blurPass.kernelSize"], [() => t.blur, "blurPass.enabled"] ], i, () => new _() ), S( [() => t.lightSource, i], () => { i.value && (i.value.lightSource = ie(s.value)); }, { immediate: !0 } ), S( [() => t.opacity], () => { var n, l; if (t.opacity !== void 0) (n = i.value) == null || n.blendMode.setOpacity(t.opacity); else { const f = new _( o.value, ie(s.value) ); (l = i.value) == null || l.blendMode.setOpacity(f.blendMode.getOpacity()), f.dispose(); } }, { immediate: !0 } ), () => { }; } }), lo = /* @__PURE__ */ u({ __name: "ColorDepthPmndrs", props: { blendFunction: {}, bits: {}, opacity: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new I(t), t); return e({ pass: o, effect: s }), H( () => t.blendFunction, s, "blendMode.blendFunction", () => new I() ), S( [s, () => t.bits], () => { var a, i; if (s.value) if (t.bits !== void 0) (a = s.value) == null || a.setBitDepth(t.bits); else { const n = new I(); (i = s.value) == null || i.setBitDepth(n.getBitDepth()), n.dispose(); } } ), S( [s, () => t.opacity], () => { var a, i; if (s.value) if (t.opacity !== void 0) (a = s.value) == null || a.blendMode.setOpacity(t.opacity); else { const n = new I(); (i = s.value) == null || i.blendMode.setOpacity(n.blendMode.getOpacity()), n.dispose(); } } ), () => { }; } }), uo = /* @__PURE__ */ u({ __name: "GridPmndrs", props: { blendFunction: {}, scale: {}, lineWidth: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new we(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.scale, "scale"], [() => t.lineWidth, "lineWidth"] ], s, () => new we() ), () => { }; } }); class Le extends q { /** * Creates a new FishEyeEffect instance. * * @param {object} [options] - Configuration options for the effect. * @param {BlendFunction} [options.blendFunction] - Blend mode. * @param {Vector2} [options.lensS] - Lens scale. * @param {Vector2} [options.lensF] - Lens factor. * @param {number} [options.scale] - Scale. * */ constructor({ blendFunction: e = Q.NORMAL, lensS: t = new d(1, 1), lensF: o = new d(0, 1), scale: s = 1 } = {}) { super("FishEyeEffect", ` uniform vec2 lensS; uniform vec2 lensF; uniform float scale; void mainUv(inout vec2 uv) { vec2 newUv = uv * 2.0 - 1.0; newUv.x = newUv.x + ((pow(newUv.y, 2.0) / scale) * newUv.x / scale) * -lensF.x; newUv.y = newUv.y + ((pow(newUv.x, 2.0) / scale) * newUv.y / scale) * -lensF.y; newUv = newUv * lensS; newUv = newUv / scale * 0.5 + 0.5; uv = newUv; } void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { outputColor = vec4(inputColor.rgb, inputColor.a); // Preserves original alpha } `, { blendFunction: e, uniforms: /* @__PURE__ */ new Map([ ["lensS", new M(t)], ["lensF", new M(o)], ["scale", new M(s)] ]) }); } /** * The lensS. * * @type {Vector2} */ get lensS() { var e; return (e = this.uniforms.get("lensS")) == null ? void 0 : e.value; } set lensS(e) { this.uniforms.get("lensS").value = e; } /** * The lensF. * * @type {Vector2} */ get lensF() { var e; return (e = this.uniforms.get("lensF")) == null ? void 0 : e.value; } set lensF(e) { this.uniforms.get("lensF").value = e; } /** * The scale. * * @type {number} */ get scale() { var e; return (e = this.uniforms.get("scale")) == null ? void 0 : e.value; } set scale(e) { this.uniforms.get("scale").value = e; } } const co = /* @__PURE__ */ u({ __name: "FishEyePmndrs", props: { blendFunction: {}, lensS: {}, lensF: {}, scale: {} }, setup(r, { expose: e }) { const t = r, o = L( () => Array.isArray(t.lensS) ? new d(...t.lensS) : t.lensS ), s = L( () => Array.isArray(t.lensF) ? new d(...t.lensF) : t.lensF ), { pass: a, effect: i } = p( () => new Le({ ...t, lensS: o.value, lensF: s.value }), t ); return e({ pass: a, effect: i }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => o.value, "lensS"], [() => s.value, "lensF"], [() => t.scale, "scale"] ], i, () => new Le() ), () => { }; } }), fo = /* @__PURE__ */ u({ __name: "BrightnessContrastPmndrs", props: { blendFunction: {}, brightness: {}, contrast: {} }, setup(r, { expose: e }) { const t = r, { pass: o, effect: s } = p(() => new Ae(t), t); return e({ pass: o, effect: s }), m( [ [() => t.blendFunction, "blendMode.blendFunction"], [() => t.brightness, "brightness"], [() => t.contrast, "contrast"] ], s, () => new Ae() ), () => { }; } }), He = { name: "CopyShader", uniforms: { tDiffuse: { value: null }, opacity: { value: 1 } }, vertexShader: ( /* glsl */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }` ), fragmentShader: ( /* glsl */ ` uniform float opacity; uniform sampler2D tDiffuse; varying vec2 vUv; void main() { vec4 texel = texture2D( tDiffuse, vUv ); gl_FragColor = opacity * texel; }` ) }; class C { constructor() { this.isPass = !0, this.enabled = !0, this.needsSwap = !0, this.clear = !1, this.renderToScreen = !1; } setSize() { } render() { console.error("THREE.Pass: .render() must be implemented in derived pass."); } dispose() { } } const At = new Ze(-1, 1, 1, -1, 0, 1); class yt extends _e { constructor() { super(), this.setAttribute("position", new ye([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3)), this.setAttribute("uv", new ye([0, 2, 0, 0, 2, 0], 2)); } } const Mt = new yt(); class R { constructor(e) { this._mesh = new ze(Mt, e); } dispose() { this._mesh.geometry.dispose(); } render(e) { e.render(this._mesh, At); } get material() { return this._mesh.material; } set material(e) { this._mesh.material = e; } } class Tt extends C { constructor(e, t) { super(), this.textureID = t !== void 0 ? t : "tDiffuse", e instanceof A ? (this.uniforms = e.uniforms, this.material = e) : e && (this.uniforms = P.clone(e.uniforms), this.material = new A({ name: e.name !== void 0 ? e.name : "unspecified", defines: Object.assign({}, e.defines), uniforms: this.uniforms, vertexShader: e.vertexShader, fragmentShader: e.fragmentShader })), this.fsQuad = new R(this.material); } render(e, t, o) { this.uniforms[this.textureID] && (this.uniforms[this.textureID].value = o.texture), this.fsQuad.material = this.material, this.renderToScreen ? (e.setRenderTarget(null), this.fsQuad.render(e)) : (e.setRenderTarget(t), this.clear && e.clear(e.autoClearColor, e.autoClearDepth, e.autoClearStencil), this.fsQuad.render(e)); } dispose() { this.material.dispose(), this.fsQuad.dispose(); } } class Oe extends C { constructor(e, t) { super(), this.scene = e, this.camera = t, this.clear = !0, this.needsSwap = !1, this.inverse = !1; } render(e, t, o) { const s = e.getContext(), a = e.state; a.buffers.color.setMask(!1), a.buffers.depth.setMask(!1), a.buffers.color.setLocked(!0), a.buffers.depth.setLocked(!0); let i, n; this.inverse ? (i = 0, n = 1) : (i = 1, n = 0), a.buffers.stencil.setTest(!0), a.buffers.stencil.setOp(s.REPLACE, s.REPLACE, s.REPLACE), a.buffers.stencil.setFunc(s.ALWAYS, i, 4294967295), a.buffers.stencil.setClear(n), a.buffers.stencil.setLocked(!0), e.setRenderTarget(o), this.clear && e.clear(), e.render(this.scene, this.camera), e.setRenderTarget(t), this.clear && e.clear(), e.render(this.scene, this.camera), a.buffers.color.setLocked(!1), a.buffers.depth.setLocked(!1), a.buffers.color.setMask(!0), a.buffers.depth.setMask(!0), a.buffers.stencil.setLocked(!1), a.buffers.stencil.setFunc(s.EQUAL, 1, 4294967295), a.buffers.stencil.setOp(s.KEEP, s.KEEP, s.KEEP), a.buffers.stencil.setLocked(!0); } } class Ct extends C { constructor() { super(), this.needsSwap = !1; } render(e) { e.state.buffers.stencil.setLocked(!1), e.state.buffers.stencil.setTest(!1); } } class Et { constructor(e, t) { if (this.renderer = e, this._pixelRatio = e.getPixelRatio(), t === void 0) { const o = e.getSize(new d()); this._width = o.width, this._height = o.height, t = new D(this._width * this._pixelRatio, this._height * this._pixelRatio, { type: T }), t.texture.name = "EffectComposer.rt1"; } else this._width = t.width, this._height = t.height; this.renderTarget1 = t, this.renderTarget2 = t.clone(), this.renderTarget2.texture.name = "EffectComposer.rt2", this.writeBuffer = this.renderTarget1, this.readBuffer = this.renderTarget2, this.renderToScreen = !0, this.passes = [], this.copyPass = new Tt(He), this.copyPass.material.blending = $e, this.clock = new et(); } swapBuffers() { const e = this.readBuffer; this.readBuffer = this.writeBuffer, this.writeBuffer = e; } addPass(e) { this.passes.push(e), e.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio); } insertPass(e, t) { this.passes.splice(t, 0, e), e.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio); } removePass(e) { const t = this.passes.indexOf(e); t !== -1 && this.passes.splice(t, 1); } isLastEnabledPass(e) { for (let t = e + 1; t < this.passes.length; t++) if (this.passes[t].enabled) return !1; return !0; } render(e) { e === void 0 && (e = this.clock.getDelta()); const t = this.renderer.getRenderTarget(); let o = !1; for (let s = 0, a = this.passes.length; s < a; s++) { const i = this.passes[s]; if (i.enabled !== !1) { if (i.renderToScreen = this.renderToScreen && this.isLastEnabledPass(s), i.render(this.renderer, this.writeBuffer, this.readBuffer, e, o), i.needsSwap) { if (o) { const n = this.renderer.getContext(), l = this.renderer.state.buffers.stencil; l.setFunc(n.NOTEQUAL, 1, 4294967295), this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, e), l.setFunc(n.EQUAL, 1, 4294967295); } this.swapBuffers(); } Oe !== void 0 && (i instanceof Oe ? o = !0 : i instanceof Ct && (o = !1)); } } this.renderer.setRenderTarget(t); } reset(e) { if (e === void 0) { const t = this.renderer.getSize(new d()); this._pixelRatio = this.renderer.getPixelRatio(), this._width = t.width, this._height = t.height, e = this.renderTarget1.clone(), e.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio); } this.renderTarget1.dispose(), this.renderTarget2.dispose(), this.renderTarget1 = e, this.renderTarget2 = e.clone(), this.writeBuffer = this.renderTarget1, this.readBuffer = this.renderTarget2; } setSize(e, t) { this._width = e, this._height = t; const o = this._width * this._pixelRatio, s = this._height * this._pixelRatio; this.renderTarget1.setSize(o, s), this.renderTarget2.setSize(o, s); for (let a = 0; a < this.passes.length; a++) this.passes[a].setSize(o, s); } setPixelRatio(e) { this._pixelRatio = e, this.setSize(this._width, this._height); } dispose() { this.renderTarget1.dispose(), this.renderTarget2.dispose(), this.copyPass.dispose(); } } class Pt extends C { constructor(e, t, o = null, s = null, a = null) { super(), this.scene = e, this.camera = t, this.overrideMaterial = o, this.clearColor = s, this.clearAlpha = a, this.clear = !0, this.clearDepth = !1, this.needsSwap = !1, this._oldClearColor = new k(); } render(e, t, o) { const s = e.autoClear; e.autoClear = !1; let a, i; this.overrideMaterial !== null && (i = this.scene.overrideMaterial, this.scene.overrideMaterial = this.overrideMaterial), this.clearColor !== null && (e.getClearColor(this._oldClearColor), e.setClearColor(this.clearColor, e.getClearAlpha())), this.clearAlpha !== null && (a = e.getClearAlpha(), e.setClearAlpha(this.clearAlpha)), this.clearDepth == !0 && e.clearDepth(), e.setRenderTarget(this.renderToScreen ? null : o), this.clear === !0 && e.clear(e.autoClearColor, e.autoClearDepth, e.autoClearStencil), e.render(this.scene, this.camera), this.clearColor !== null && e.setClearColor(this._oldClearColor), this.clearAlpha !== null && e.setClearAlpha(a), this.overrideMaterial !== null && (this.scene.overrideMaterial = i), e.autoClea