postprocessing-fork
Version:
A post processing library for three.js.
1,525 lines (1,491 loc) • 2.05 MB
JavaScript
/**
* postprocessing-fork v6.37.4 build Mon Sep 15 2025
* https://github.com/pmndrs/postprocessing
* Copyright 2015-2025 Raoul van Rüschen
* @license Zlib
*/
if(typeof window==="object"&&!window.require)window.require=()=>window.THREE;
"use strict";
var POSTPROCESSINGFORK = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/index.js
var index_exports = {};
__export(index_exports, {
ASCIIEffect: () => ASCIIEffect,
ASCIITexture: () => ASCIITexture,
AdaptiveLuminanceMaterial: () => AdaptiveLuminanceMaterial,
AdaptiveLuminancePass: () => AdaptiveLuminancePass,
AdaptiveSharpenEffect: () => AdaptiveSharpenEffect,
BlendFunction: () => BlendFunction,
BlendMode: () => BlendMode,
BloomEffect: () => BloomEffect,
BlurPass: () => KawaseBlurPass,
BokehEffect: () => BokehEffect,
BokehMaterial: () => BokehMaterial,
BoxBlurMaterial: () => BoxBlurMaterial,
BoxBlurPass: () => BoxBlurPass,
BrightnessContrastEffect: () => BrightnessContrastEffect,
ChromaticAberrationEffect: () => ChromaticAberrationEffect,
CircleOfConfusionMaterial: () => CircleOfConfusionMaterial,
ClearMaskPass: () => ClearMaskPass,
ClearPass: () => ClearPass,
ColorAverageEffect: () => ColorAverageEffect,
ColorChannel: () => ColorChannel,
ColorDepthEffect: () => ColorDepthEffect,
ColorEdgesMaterial: () => EdgeDetectionMaterial,
ConvolutionMaterial: () => KawaseBlurMaterial,
CopyMaterial: () => CopyMaterial,
CopyPass: () => CopyPass,
CustomSSGIEffect: () => CustomSSGIEffect,
DayNightCycleEffect: () => DayNightCycleEffect,
DenoiseEffect: () => DenoiseEffect,
DepthComparisonMaterial: () => DepthComparisonMaterial,
DepthCopyMaterial: () => DepthCopyMaterial,
DepthCopyMode: () => DepthCopyMode,
DepthCopyPass: () => DepthCopyPass,
DepthDownsamplingMaterial: () => DepthDownsamplingMaterial,
DepthDownsamplingPass: () => DepthDownsamplingPass,
DepthEffect: () => DepthEffect,
DepthMaskMaterial: () => DepthMaskMaterial,
DepthOfFieldEffect: () => DepthOfFieldEffect,
DepthPass: () => DepthPass,
DepthPickingPass: () => DepthPickingPass,
DepthSavePass: () => DepthCopyPass,
DepthTestStrategy: () => DepthTestStrategy,
Disposable: () => Disposable,
DotScreenEffect: () => DotScreenEffect,
DownsamplingMaterial: () => DownsamplingMaterial,
EdgeDetectionMaterial: () => EdgeDetectionMaterial,
EdgeDetectionMode: () => EdgeDetectionMode,
Effect: () => Effect,
EffectAttribute: () => EffectAttribute,
EffectComposer: () => EffectComposer,
EffectMaterial: () => EffectMaterial,
EffectPass: () => EffectPass,
EffectShaderData: () => EffectShaderData,
EffectShaderSection: () => EffectShaderSection,
EnhancedThreeCompatPass: () => EnhancedThreeCompatPass,
FXAAEffect: () => FXAAEffect,
FakeInteriorMaterial: () => FakeInteriorMaterial,
FlowRiverMaterial: () => FlowRiverMaterial,
FoggyFlyoverEffect: () => FoggyFlyoverEffect,
FoggyMountainsEffect: () => FoggyMountainsEffect,
FoggyTerrainEffect: () => FoggyTerrainEffect,
FrozenWastelandEffect: () => FrozenWastelandEffect,
GammaCorrectionEffect: () => GammaCorrectionEffect,
GaussKernel: () => GaussKernel,
GaussianBlurMaterial: () => GaussianBlurMaterial,
GaussianBlurPass: () => GaussianBlurPass,
GlitchEffect: () => GlitchEffect,
GlitchMode: () => GlitchMode,
GodRaysEffect: () => GodRaysEffect,
GodRaysMaterial: () => GodRaysMaterial,
GridEffect: () => GridEffect,
HBAOEffect: () => HBAOEffect,
HueSaturationEffect: () => HueSaturationEffect,
IdManager: () => IdManager,
ImmutableTimer: () => ImmutableTimer,
Initializable: () => Initializable,
InteriorMappingMaterial: () => InteriorMappingMaterial,
InteriorRoomMaterial: () => InteriorRoomMaterial,
KawaseBlurMaterial: () => KawaseBlurMaterial,
KawaseBlurPass: () => KawaseBlurPass,
KernelSize: () => KernelSize,
LUT1DEffect: () => LUT1DEffect,
LUT3DEffect: () => LUT3DEffect,
LUT3dlLoader: () => LUT3dlLoader,
LUTCubeLoader: () => LUTCubeLoader,
LUTEffect: () => LUT3DEffect,
LUTOperation: () => LUTOperation,
LakesMountainsEffect: () => LakesMountainsEffect,
LambdaPass: () => LambdaPass,
LensDistortionEffect: () => LensDistortionEffect,
LookupTexture: () => LookupTexture,
LookupTexture3D: () => LookupTexture,
LuminanceMaterial: () => LuminanceMaterial,
LuminancePass: () => LuminancePass,
MRTRenderPass: () => MRTRenderPass,
MaskFunction: () => MaskFunction,
MaskMaterial: () => MaskMaterial,
MaskPass: () => MaskPass,
MipmapBlurPass: () => MipmapBlurPass,
MotionBlurEffect: () => MotionBlurEffect2,
MultiSampleDepthMaskMaterial: () => MultiSampleDepthMaskMaterial,
NoiseEffect: () => NoiseEffect,
NoiseTexture: () => NoiseTexture,
NormalPass: () => NormalPass,
OceanMaterial: () => OceanMaterial,
OutlineEdgesMaterial: () => OutlineMaterial,
OutlineEffect: () => OutlineEffect,
OutlineManager: () => OutlineManager,
OutlineMaterial: () => OutlineMaterial,
OutlineMultiEffect: () => OutlineMultiEffect,
OverrideMaterialManager: () => OverrideMaterialManager,
Pass: () => Pass,
PerformanceLogger: () => PerformanceLogger,
PixelationEffect: () => PixelationEffect,
PoissionDenoisePass: () => PoissionDenoisePass2,
PoissonDenoisePass: () => PoissonDenoisePass,
PredicationMode: () => PredicationMode,
RAOPass: () => AOPass,
RSSAOEffect: () => SSAOEffect3,
RainfallEffect: () => RainfallEffect,
RawImageData: () => RawImageData,
RealismNew: () => realism_new_exports,
RealismSSAOEffect: () => SSAOEffect3,
RealisticBokehEffect: () => RealisticBokehEffect,
ReflectorForSSRPass: () => ReflectorForSSRPass,
RenderPass: () => RenderPass,
Resizable: () => Resizable,
Resizer: () => Resolution,
Resolution: () => Resolution,
RiverMaterial: () => RiverMaterial,
SMAAAreaImageData: () => SMAAAreaImageData,
SMAAEffect: () => SMAAEffect,
SMAAImageGenerator: () => SMAAImageGenerator,
SMAAImageLoader: () => SMAAImageLoader,
SMAAPreset: () => SMAAPreset,
SMAASearchImageData: () => SMAASearchImageData,
SMAAWeightsMaterial: () => SMAAWeightsMaterial,
SSAOEffect: () => SSAOEffect,
SSAOMaterial: () => SSAOMaterial,
SSDOEffect: () => SSDOEffect,
SSGIEffect: () => SSGIEffect,
SSREffect: () => SSREffect,
SSRPass: () => SSRPass,
SandStormEffect: () => SandStormEffect,
SavePass: () => CopyPass,
ScanlineEffect: () => ScanlineEffect,
Section: () => EffectShaderSection,
Selection: () => Selection,
SelectiveBloomEffect: () => SelectiveBloomEffect,
SelectiveSSAOEffect: () => SelectiveSSAOEffect,
SelectiveSSRPass: () => SelectiveSSRPass,
SepiaEffect: () => SepiaEffect,
ShaderPass: () => ShaderPass,
SharedOutlineEffect: () => SharedOutlineEffect,
SharpenEffect: () => SharpenEffect,
SharpnessEffect: () => SharpnessEffect,
ShockWaveEffect: () => ShockWaveEffect,
SkyAtmosphereEffect: () => SkyAtmosphereEffect,
SkyAtmosphereUtils: () => SkyAtmosphereUtils,
SnowOverlayEffect: () => SnowOverlayEffect,
SnowfallEffect: () => SnowfallEffect,
TRAAEffect: () => TRAAEffect,
TangentSpaceInteriorMaterial: () => TangentSpaceInteriorMaterial,
TetrahedralUpscaler: () => TetrahedralUpscaler,
TextureEffect: () => TextureEffect,
ThreeCompatPass: () => ThreeCompatPass,
TiltShiftBlurMaterial: () => TiltShiftBlurMaterial,
TiltShiftBlurPass: () => TiltShiftBlurPass,
TiltShiftEffect: () => TiltShiftEffect,
Timer: () => Timer,
ToneMappingEffect: () => ToneMappingEffect,
ToneMappingMode: () => ToneMappingMode,
UniformFogEffect: () => UniformFogEffect,
UpsamplingMaterial: () => UpsamplingMaterial,
VelocityDepthNormalPass: () => VelocityDepthNormalPass,
VelocityPass: () => VelocityPass2,
VignetteEffect: () => VignetteEffect,
VignetteTechnique: () => VignetteTechnique,
VolumetricAtmosphereEffect: () => VolumetricAtmosphereEffect,
VolumetricFogEffect: () => VolumetricFogEffect,
VolumetricShadowEffect: () => VolumetricShadowEffect,
WeatherManager: () => WeatherManager,
WeatherSystemEffect: () => WeatherSystemEffect,
WebGLExtension: () => WebGLExtension,
clearTimeData: () => clearTimeData,
disableLogs: () => disableLogs,
disableTimeCollection: () => disableTimeCollection,
enableLogs: () => enableLogs,
enableTimeCollection: () => enableTimeCollection,
error: () => error,
getAssets: () => getAssets,
getTimeData: () => getTimeData,
log: () => log,
orthographicDepthToViewZ: () => orthographicDepthToViewZ,
printSummary: () => printSummary,
renderUtils: () => renderUtils,
timeEndLog: () => timeEndLog,
timeLog: () => timeLog,
version: () => version,
viewZToOrthographicDepth: () => viewZToOrthographicDepth,
warn: () => warn
});
// package.json
var version = "6.37.4";
// src/core/index.js
var import_three9 = __require("three");
// src/core/Disposable.js
var Disposable = class {
/**
* Frees internal resources.
*/
dispose() {
}
};
// src/core/EffectComposer.js
var import_three7 = __require("three");
// src/core/Timer.js
var MILLISECONDS_TO_SECONDS = 1 / 1e3;
var SECONDS_TO_MILLISECONDS = 1e3;
var Timer = class {
/**
* Constructs a new timer.
*/
constructor() {
this.startTime = performance.now();
this.previousTime = 0;
this.currentTime = 0;
this._delta = 0;
this._elapsed = 0;
this._fixedDelta = 1e3 / 60;
this.timescale = 1;
this.useFixedDelta = false;
this._autoReset = false;
}
/**
* Enables or disables auto reset based on page visibility.
*
* If enabled, the timer will be reset when the page becomes visible. This effectively pauses the timer when the page
* is hidden. Has no effect if the API is not supported.
*
* @type {Boolean}
* @see https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
*/
get autoReset() {
return this._autoReset;
}
set autoReset(value) {
if (typeof document !== "undefined" && document.hidden !== void 0) {
if (value) {
document.addEventListener("visibilitychange", this);
} else {
document.removeEventListener("visibilitychange", this);
}
this._autoReset = value;
}
}
get delta() {
return this._delta * MILLISECONDS_TO_SECONDS;
}
get fixedDelta() {
return this._fixedDelta * MILLISECONDS_TO_SECONDS;
}
set fixedDelta(value) {
this._fixedDelta = value * SECONDS_TO_MILLISECONDS;
}
get elapsed() {
return this._elapsed * MILLISECONDS_TO_SECONDS;
}
/**
* Updates this timer.
*
* @param {Boolean} [timestamp] - The current time in milliseconds.
*/
update(timestamp) {
if (this.useFixedDelta) {
this._delta = this.fixedDelta;
} else {
this.previousTime = this.currentTime;
this.currentTime = (timestamp !== void 0 ? timestamp : performance.now()) - this.startTime;
this._delta = this.currentTime - this.previousTime;
}
this._delta *= this.timescale;
this._elapsed += this._delta;
}
/**
* Resets this timer.
*/
reset() {
this._delta = 0;
this._elapsed = 0;
this.currentTime = performance.now() - this.startTime;
}
getDelta() {
return this.delta;
}
getElapsed() {
return this.elapsed;
}
handleEvent(e) {
if (!document.hidden) {
this.currentTime = performance.now() - this.startTime;
}
}
dispose() {
this.autoReset = false;
}
};
// src/passes/Pass.js
var import_run_scene_core = __require("run-scene-core");
var fullscreenGeometry = /* @__PURE__ */ (() => {
const vertices = new Float32Array([-1, -1, 0, 3, -1, 0, -1, 3, 0]);
const uvs = new Float32Array([0, 0, 2, 0, 0, 2]);
const geometry = new import_run_scene_core.BufferGeometry();
geometry.setAttribute("position", new import_run_scene_core.BufferAttribute(vertices, 3));
geometry.setAttribute("uv", new import_run_scene_core.BufferAttribute(uvs, 2));
return geometry;
})();
var Pass = class _Pass {
/**
* A shared fullscreen triangle.
*
* The screen size is 2x2 units (NDC). A triangle needs to be 4x4 units to fill the screen.
* @see https://michaldrobot.com/2014/04/01/gcn-execution-patterns-in-full-screen-passes/
* @type {BufferGeometry}
* @internal
*/
static get fullscreenGeometry() {
return fullscreenGeometry;
}
/**
* Constructs a new pass.
*
* @param {String} [name] - The name of this pass. Does not have to be unique.
* @param {Scene} [scene] - The scene to render. The default scene contains a single mesh that fills the screen.
* @param {Camera} [camera] - A camera. Fullscreen effect passes don't require a camera.
*/
constructor(name = "Pass", scene = new import_run_scene_core.Scene(), camera = new import_run_scene_core.Camera()) {
this.name = name;
this.renderer = null;
this.scene = scene;
this.camera = camera;
this.screen = null;
this.rtt = true;
this.needsSwap = true;
this.needsDepthTexture = false;
this.needsNormalTexture = false;
this.enabled = true;
}
/**
* Sets the render to screen flag.
*
* If this flag is changed, the fullscreen material will be updated as well.
*
* @type {Boolean}
*/
get renderToScreen() {
return !this.rtt;
}
set renderToScreen(value) {
if (this.rtt === value) {
const material = this.fullscreenMaterial;
if (material !== null) {
material.needsUpdate = true;
}
this.rtt = !value;
}
}
/**
* Sets the main scene.
*
* @type {Scene}
*/
set mainScene(value) {
}
/**
* Sets the main camera.
*
* @type {Camera}
*/
set mainCamera(value) {
}
/**
* Sets the renderer
*
* @deprecated
* @param {WebGLRenderer} renderer - The renderer.
*/
setRenderer(renderer) {
this.renderer = renderer;
}
/**
* Indicates whether this pass is enabled.
*
* @deprecated Use enabled instead.
* @return {Boolean} Whether this pass is enabled.
*/
isEnabled() {
return this.enabled;
}
/**
* Enables or disables this pass.
*
* @deprecated Use enabled instead.
* @param {Boolean} value - Whether the pass should be enabled.
*/
setEnabled(value) {
this.enabled = value;
}
/**
* The fullscreen material.
*
* @type {Material}
*/
get fullscreenMaterial() {
return this.screen !== null ? this.screen.material : null;
}
set fullscreenMaterial(value) {
let screen = this.screen;
if (screen !== null) {
screen.material = value;
} else {
screen = new import_run_scene_core.Mesh(_Pass.fullscreenGeometry, value);
screen.frustumCulled = false;
if (this.scene === null) {
this.scene = new import_run_scene_core.Scene();
}
this.scene.add(screen);
this.screen = screen;
}
}
/**
* Returns the current fullscreen material.
*
* @deprecated Use fullscreenMaterial instead.
* @return {Material} The current fullscreen material, or null if there is none.
*/
getFullscreenMaterial() {
return this.fullscreenMaterial;
}
/**
* Sets the fullscreen material.
*
* @deprecated Use fullscreenMaterial instead.
* @protected
* @param {Material} value - A fullscreen material.
*/
setFullscreenMaterial(value) {
this.fullscreenMaterial = value;
}
/**
* Returns the current depth texture.
*
* @deprecated Use getDepthTexture instead.
* @return {Texture} The current depth texture, or null if there is none.
*/
getDepthTexture() {
return null;
}
/**
* Sets the depth texture.
*
* This method will be called automatically by the {@link EffectComposer}.
* You may override this method if your pass relies on the depth information of a preceding {@link RenderPass}.
*
* @param {Texture} depthTexture - A depth texture.
* @param {DepthPackingStrategy} [depthPacking=BasicDepthPacking] - The depth packing.
*/
setDepthTexture(depthTexture, depthPacking = import_run_scene_core.BasicDepthPacking) {
}
/**
* Returns the current normal texture.
*
* @return {Texture} The current normal texture, or null if there is none.
*/
getNormalTexture() {
return null;
}
/**
* Sets the normal texture.
*
* @param {Texture} normalTexture - A normal texture.
*/
setNormalTexture(normalTexture) {
}
/**
* Renders this pass.
*
* This is an abstract method that must be overridden.
*
* @abstract
* @throws {Error} An error is thrown if the method is not overridden.
* @param {WebGLRenderer} renderer - The renderer.
* @param {WebGLRenderTarget} inputBuffer - A frame buffer that contains the result of the previous pass.
* @param {WebGLRenderTarget} outputBuffer - A frame buffer that serves as the output render target unless this pass renders to screen.
* @param {Number} [deltaTime] - The time between the last frame and the current one in seconds.
* @param {Boolean} [stencilTest] - Indicates whether a stencil mask is active.
* @param {DepthPass} [depthPass] - An optional shared depth pass for optimizing multiple effects.
*/
render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest, depthPass) {
throw new Error("Render method not implemented!");
}
/**
* Sets the size.
*
* You may override this method if you want to be informed about the size of the backbuffer/canvas.
* This method is called before {@link initialize} and every time the size of the {@link EffectComposer} changes.
*
* @param {Number} width - The width.
* @param {Number} height - The height.
*/
setSize(width, height) {
}
/**
* Performs initialization tasks.
*
* This method is called when this pass is added to an {@link EffectComposer}.
*
* @param {WebGLRenderer} renderer - The renderer.
* @param {Boolean} alpha - Whether the renderer uses the alpha channel or not.
* @param {Number} frameBufferType - The type of the main frame buffers.
*/
initialize(renderer, alpha, frameBufferType) {
}
/**
* Performs a shallow search for disposable properties and deletes them.
*
* The {@link EffectComposer} calls this method when it is being destroyed. You can use it independently to free
* memory when you're certain that you don't need this pass anymore.
*/
dispose() {
for (const key of Object.keys(this)) {
const property = this[key];
const isDisposable = property instanceof import_run_scene_core.WebGLRenderTarget || property instanceof import_run_scene_core.Material || property instanceof import_run_scene_core.Texture || property instanceof _Pass;
if (isDisposable) {
this[key].dispose();
}
}
if (this.fullscreenMaterial !== null) {
this.fullscreenMaterial.dispose();
}
}
};
// src/passes/ClearMaskPass.js
var ClearMaskPass = class extends Pass {
/**
* Constructs a new clear mask pass.
*/
constructor() {
super("ClearMaskPass", null, null);
this.needsSwap = false;
}
/**
* Disables the global stencil test.
*
* @param {WebGLRenderer} renderer - The renderer.
* @param {WebGLRenderTarget} inputBuffer - A frame buffer that contains the result of the previous pass.
* @param {WebGLRenderTarget} outputBuffer - A frame buffer that serves as the output render target unless this pass renders to screen.
* @param {Number} [deltaTime] - The time between the last frame and the current one in seconds.
* @param {Boolean} [stencilTest] - Indicates whether a stencil mask is active.
*/
render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) {
const stencil = renderer.state.buffers.stencil;
stencil.setLocked(false);
stencil.setTest(false);
}
};
// src/passes/CopyPass.js
var import_three2 = __require("three");
// src/materials/CopyMaterial.js
var import_three = __require("three");
// src/materials/glsl/copy.frag
var copy_default = `#include <common>
#include <dithering_pars_fragment>
#ifdef FRAMEBUFFER_PRECISION_HIGH
uniform mediump sampler2D inputBuffer;
#else
uniform lowp sampler2D inputBuffer;
#endif
uniform float opacity;
varying vec2 vUv;
void main() {
vec4 texel = texture2D(inputBuffer, vUv);
gl_FragColor = opacity * texel;
#include <colorspace_fragment>
#include <dithering_fragment>
}
`;
// src/materials/glsl/common.vert
var common_default = `varying vec2 vUv;
void main() {
vUv = position.xy * 0.5 + 0.5;
gl_Position = vec4(position.xy, 1.0, 1.0);
}
`;
// src/materials/CopyMaterial.js
var CopyMaterial = class extends import_three.ShaderMaterial {
/**
* Constructs a new copy material.
*/
constructor() {
super({
name: "CopyMaterial",
uniforms: {
inputBuffer: new import_three.Uniform(null),
opacity: new import_three.Uniform(1)
},
blending: import_three.NoBlending,
toneMapped: false,
depthWrite: false,
depthTest: false,
fragmentShader: copy_default,
vertexShader: common_default
});
}
/**
* The input buffer.
*
* @type {Texture}
*/
set inputBuffer(value) {
this.uniforms.inputBuffer.value = value;
}
/**
* Sets the input buffer.
*
* @deprecated Use inputBuffer instead.
* @param {Number} value - The buffer.
*/
setInputBuffer(value) {
this.uniforms.inputBuffer.value = value;
}
/**
* Returns the opacity.
*
* @deprecated Use opacity instead.
* @return {Number} The opacity.
*/
getOpacity(value) {
return this.uniforms.opacity.value;
}
/**
* Sets the opacity.
*
* @deprecated Use opacity instead.
* @param {Number} value - The opacity.
*/
setOpacity(value) {
this.uniforms.opacity.value = value;
}
};
// src/passes/CopyPass.js
var CopyPass = class extends Pass {
/**
* Constructs a new save pass.
*
* @param {WebGLRenderTarget} [renderTarget] - A render target.
* @param {Boolean} [autoResize=true] - Whether the render target size should be updated automatically.
*/
constructor(renderTarget, autoResize = true) {
super("CopyPass");
this.fullscreenMaterial = new CopyMaterial();
this.needsSwap = false;
this.renderTarget = renderTarget;
if (renderTarget === void 0) {
this.renderTarget = new import_three2.WebGLRenderTarget(1, 1, {
minFilter: import_three2.LinearFilter,
magFilter: import_three2.LinearFilter,
stencilBuffer: false,
depthBuffer: false
});
this.renderTarget.texture.name = "CopyPass.Target";
}
this.autoResize = autoResize;
}
/**
* Enables or disables auto resizing of the render target.
*
* @deprecated Use autoResize instead.
* @type {Boolean}
*/
get resize() {
return this.autoResize;
}
set resize(value) {
this.autoResize = value;
}
/**
* The output texture.
*
* @type {Texture}
*/
get texture() {
return this.renderTarget.texture;
}
/**
* Returns the output texture.
*
* @deprecated Use texture instead.
* @return {Texture} The texture.
*/
getTexture() {
return this.renderTarget.texture;
}
/**
* Enables or disables auto resizing of the render target.
*
* @deprecated Use autoResize instead.
* @param {Boolean} value - Whether the render target size should be updated automatically.
*/
setAutoResizeEnabled(value) {
this.autoResize = value;
}
/**
* Saves the input buffer.
*
* @param {WebGLRenderer} renderer - The renderer.
* @param {WebGLRenderTarget} inputBuffer - A frame buffer that contains the result of the previous pass.
* @param {WebGLRenderTarget} outputBuffer - A frame buffer that serves as the output render target unless this pass renders to screen.
* @param {Number} [deltaTime] - The time between the last frame and the current one in seconds.
* @param {Boolean} [stencilTest] - Indicates whether a stencil mask is active.
*/
render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) {
this.fullscreenMaterial.inputBuffer = inputBuffer.texture;
renderer.setRenderTarget(this.renderToScreen ? null : this.renderTarget);
renderer.render(this.scene, this.camera);
}
/**
* Updates the size of this pass.
*
* @param {Number} width - The width.
* @param {Number} height - The height.
*/
setSize(width, height) {
if (this.autoResize) {
this.renderTarget.setSize(width, height);
}
}
/**
* Performs initialization tasks.
*
* @param {WebGLRenderer} renderer - A renderer.
* @param {Boolean} alpha - Whether the renderer uses the alpha channel.
* @param {Number} frameBufferType - The type of the main frame buffers.
*/
initialize(renderer, alpha, frameBufferType) {
if (frameBufferType !== void 0) {
this.renderTarget.texture.type = frameBufferType;
if (frameBufferType !== import_three2.UnsignedByteType) {
this.fullscreenMaterial.defines.FRAMEBUFFER_PRECISION_HIGH = "1";
} else if (renderer !== null && renderer.outputColorSpace === import_three2.SRGBColorSpace) {
this.renderTarget.texture.colorSpace = import_three2.SRGBColorSpace;
}
}
}
};
// src/passes/DepthPass.js
var import_three6 = __require("three");
// src/core/Resolution.js
var import_three3 = __require("three");
var AUTO_SIZE = -1;
var Resolution = class extends import_three3.EventDispatcher {
/**
* Constructs a new resolution.
*
* TODO Remove resizable param.
* @param {Resizable} resizable - A resizable object.
* @param {Number} [width=Resolution.AUTO_SIZE] - The preferred width.
* @param {Number} [height=Resolution.AUTO_SIZE] - The preferred height.
* @param {Number} [scale=1.0] - A resolution scale.
*/
constructor(resizable, width = AUTO_SIZE, height = AUTO_SIZE, scale = 1) {
super();
this.resizable = resizable;
this.baseSize = new import_three3.Vector2(1, 1);
this.preferredSize = new import_three3.Vector2(width, height);
this.target = this.preferredSize;
this.s = scale;
this.effectiveSize = new import_three3.Vector2();
this.addEventListener("change", () => this.updateEffectiveSize());
this.updateEffectiveSize();
}
/**
* Calculates the effective size.
*
* @private
*/
updateEffectiveSize() {
const base3 = this.baseSize;
const preferred = this.preferredSize;
const effective = this.effectiveSize;
const scale = this.scale;
if (preferred.width !== AUTO_SIZE) {
effective.width = preferred.width;
} else if (preferred.height !== AUTO_SIZE) {
effective.width = Math.round(preferred.height * (base3.width / Math.max(base3.height, 1)));
} else {
effective.width = Math.round(base3.width * scale);
}
if (preferred.height !== AUTO_SIZE) {
effective.height = preferred.height;
} else if (preferred.width !== AUTO_SIZE) {
effective.height = Math.round(preferred.width / Math.max(base3.width / Math.max(base3.height, 1), 1));
} else {
effective.height = Math.round(base3.height * scale);
}
}
/**
* The effective width.
*
* If the preferred width and height are set to {@link Resizer.AUTO_SIZE}, the base width will be returned.
*
* @type {Number}
*/
get width() {
return this.effectiveSize.width;
}
set width(value) {
this.preferredWidth = value;
}
/**
* The effective height.
*
* If the preferred width and height are set to {@link Resizer.AUTO_SIZE}, the base height will be returned.
*
* @type {Number}
*/
get height() {
return this.effectiveSize.height;
}
set height(value) {
this.preferredHeight = value;
}
/**
* Returns the effective width.
*
* If the preferred width and height are set to {@link Resizer.AUTO_SIZE}, the base width will be returned.
*
* @deprecated Use width instead.
* @return {Number} The effective width.
*/
getWidth() {
return this.width;
}
/**
* Returns the effective height.
*
* If the preferred width and height are set to {@link Resizer.AUTO_SIZE}, the base height will be returned.
*
* @deprecated Use height instead.
* @return {Number} The effective height.
*/
getHeight() {
return this.height;
}
/**
* The resolution scale.
*
* @type {Number}
*/
get scale() {
return this.s;
}
set scale(value) {
if (this.s !== value) {
this.s = value;
this.preferredSize.setScalar(AUTO_SIZE);
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* Returns the current resolution scale.
*
* @deprecated Use scale instead.
* @return {Number} The scale.
*/
getScale() {
return this.scale;
}
/**
* Sets the resolution scale.
*
* Also sets the preferred resolution to {@link Resizer.AUTO_SIZE}.
*
* @deprecated Use scale instead.
* @param {Number} value - The scale.
*/
setScale(value) {
this.scale = value;
}
/**
* The base width.
*
* @type {Number}
*/
get baseWidth() {
return this.baseSize.width;
}
set baseWidth(value) {
if (this.baseSize.width !== value) {
this.baseSize.width = value;
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* Returns the base width.
*
* @deprecated Use baseWidth instead.
* @return {Number} The base width.
*/
getBaseWidth() {
return this.baseWidth;
}
/**
* Sets the base width.
*
* @deprecated Use baseWidth instead.
* @param {Number} value - The width.
*/
setBaseWidth(value) {
this.baseWidth = value;
}
/**
* The base height.
*
* @type {Number}
*/
get baseHeight() {
return this.baseSize.height;
}
set baseHeight(value) {
if (this.baseSize.height !== value) {
this.baseSize.height = value;
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* Returns the base height.
*
* @deprecated Use baseHeight instead.
* @return {Number} The base height.
*/
getBaseHeight() {
return this.baseHeight;
}
/**
* Sets the base height.
*
* @deprecated Use baseHeight instead.
* @param {Number} value - The height.
*/
setBaseHeight(value) {
this.baseHeight = value;
}
/**
* Sets the base size.
*
* @param {Number} width - The width.
* @param {Number} height - The height.
*/
setBaseSize(width, height) {
if (this.baseSize.width !== width || this.baseSize.height !== height) {
this.baseSize.set(width, height);
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* The preferred width.
*
* @type {Number}
*/
get preferredWidth() {
return this.preferredSize.width;
}
set preferredWidth(value) {
if (this.preferredSize.width !== value) {
this.preferredSize.width = value;
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* Returns the preferred width.
*
* @deprecated Use preferredWidth instead.
* @return {Number} The preferred width.
*/
getPreferredWidth() {
return this.preferredWidth;
}
/**
* Sets the preferred width.
*
* Use {@link Resizer.AUTO_SIZE} to automatically calculate the width based on the height and aspect ratio.
*
* @deprecated Use preferredWidth instead.
* @param {Number} value - The width.
*/
setPreferredWidth(value) {
this.preferredWidth = value;
}
/**
* The preferred height.
*
* @type {Number}
*/
get preferredHeight() {
return this.preferredSize.height;
}
set preferredHeight(value) {
if (this.preferredSize.height !== value) {
this.preferredSize.height = value;
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* Returns the preferred height.
*
* @deprecated Use preferredHeight instead.
* @return {Number} The preferred height.
*/
getPreferredHeight() {
return this.preferredHeight;
}
/**
* Sets the preferred height.
*
* Use {@link Resizer.AUTO_SIZE} to automatically calculate the height based on the width and aspect ratio.
*
* @deprecated Use preferredHeight instead.
* @param {Number} value - The height.
*/
setPreferredHeight(value) {
this.preferredHeight = value;
}
/**
* Sets the preferred size.
*
* @param {Number} width - The width.
* @param {Number} height - The height.
*/
setPreferredSize(width, height) {
if (this.preferredSize.width !== width || this.preferredSize.height !== height) {
this.preferredSize.set(width, height);
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
}
/**
* Copies the given resolution.
*
* @param {Resolution} resolution - The resolution.
*/
copy(resolution) {
this.s = resolution.scale;
this.baseSize.set(resolution.baseWidth, resolution.baseHeight);
this.preferredSize.set(resolution.preferredWidth, resolution.preferredHeight);
this.dispatchEvent({ type: "change" });
this.resizable.setSize(this.baseSize.width, this.baseSize.height);
}
/**
* An auto sizing constant.
*
* Can be used to automatically calculate the width or height based on the original aspect ratio.
*
* @type {Number}
*/
static get AUTO_SIZE() {
return AUTO_SIZE;
}
};
// src/core/OverrideMaterialManager.js
var import_three4 = __require("three");
var workaroundEnabled = false;
var OverrideMaterialManager = class {
/**
* Constructs a new override material manager.
*
* @param {Material} [material=null] - An override material.
*/
constructor(material = null) {
this.originalMaterials = /* @__PURE__ */ new Map();
this.material = null;
this.materials = null;
this.materialsBackSide = null;
this.materialsDoubleSide = null;
this.materialsFlatShaded = null;
this.materialsFlatShadedBackSide = null;
this.materialsFlatShadedDoubleSide = null;
this.setMaterial(material);
this.meshCount = 0;
this.replaceMaterial = (node) => {
if (node.isMesh) {
let materials;
if (node.material.flatShading) {
switch (node.material.side) {
case import_three4.DoubleSide:
materials = this.materialsFlatShadedDoubleSide;
break;
case import_three4.BackSide:
materials = this.materialsFlatShadedBackSide;
break;
default:
materials = this.materialsFlatShaded;
break;
}
} else {
switch (node.material.side) {
case import_three4.DoubleSide:
materials = this.materialsDoubleSide;
break;
case import_three4.BackSide:
materials = this.materialsBackSide;
break;
default:
materials = this.materials;
break;
}
}
this.originalMaterials.set(node, node.material);
if (node.isSkinnedMesh) {
node.material = materials[2];
} else if (node.isInstancedMesh) {
node.material = materials[1];
} else {
node.material = materials[0];
}
++this.meshCount;
}
};
}
/**
* Clones the given material.
*
* @private
* @param {Material} material - The material.
* @return {Material} The cloned material.
*/
cloneMaterial(material) {
if (!(material instanceof import_three4.ShaderMaterial)) {
return material.clone();
}
const uniforms = material.uniforms;
const textureUniforms = /* @__PURE__ */ new Map();
for (const key in uniforms) {
const value = uniforms[key].value;
if (value.isRenderTargetTexture) {
uniforms[key].value = null;
textureUniforms.set(key, value);
}
}
const clone = material.clone();
for (const entry of textureUniforms) {
uniforms[entry[0]].value = entry[1];
clone.uniforms[entry[0]].value = entry[1];
}
return clone;
}
/**
* Sets the override material.
*
* @param {Material} material - The material.
*/
setMaterial(material) {
this.disposeMaterials();
this.material = material;
if (material !== null) {
const materials = this.materials = [
this.cloneMaterial(material),
this.cloneMaterial(material),
this.cloneMaterial(material)
];
for (const m2 of materials) {
m2.uniforms = Object.assign({}, material.uniforms);
m2.side = import_three4.FrontSide;
}
materials[2].skinning = true;
this.materialsBackSide = materials.map((m2) => {
const c2 = this.cloneMaterial(m2);
c2.uniforms = Object.assign({}, material.uniforms);
c2.side = import_three4.BackSide;
return c2;
});
this.materialsDoubleSide = materials.map((m2) => {
const c2 = this.cloneMaterial(m2);
c2.uniforms = Object.assign({}, material.uniforms);
c2.side = import_three4.DoubleSide;
return c2;
});
this.materialsFlatShaded = materials.map((m2) => {
const c2 = this.cloneMaterial(m2);
c2.uniforms = Object.assign({}, material.uniforms);
c2.flatShading = true;
return c2;
});
this.materialsFlatShadedBackSide = materials.map((m2) => {
const c2 = this.cloneMaterial(m2);
c2.uniforms = Object.assign({}, material.uniforms);
c2.flatShading = true;
c2.side = import_three4.BackSide;
return c2;
});
this.materialsFlatShadedDoubleSide = materials.map((m2) => {
const c2 = this.cloneMaterial(m2);
c2.uniforms = Object.assign({}, material.uniforms);
c2.flatShading = true;
c2.side = import_three4.DoubleSide;
return c2;
});
}
}
/**
* Renders the scene with the override material.
*
* @private
* @param {WebGLRenderer} renderer - The renderer.
* @param {Scene} scene - A scene.
* @param {Camera} camera - A camera.
*/
render(renderer, scene, camera, renderOpts = {}) {
const shadowMapEnabled = renderer.shadowMap.enabled;
renderer.shadowMap.enabled = false;
let renderResult = null;
if (workaroundEnabled) {
const originalMaterials = this.originalMaterials;
this.meshCount = 0;
scene.traverse(this.replaceMaterial);
renderResult = renderer.render(scene, camera, renderOpts);
for (const entry of originalMaterials) {
entry[0].material = entry[1];
}
if (this.meshCount !== originalMaterials.size) {
originalMaterials.clear();
}
} else {
const overrideMaterial2 = scene.overrideMaterial;
scene.overrideMaterial = this.material;
renderResult = renderer.render(scene, camera, renderOpts);
scene.overrideMaterial = overrideMaterial2;
}
renderer.shadowMap.enabled = shadowMapEnabled;
return renderResult;
}
/**
* Deletes cloned override materials.
*
* @private
*/
disposeMaterials() {
if (this.material !== null) {
const materials = this.materials.concat(this.materialsBackSide).concat(this.materialsDoubleSide).concat(this.materialsFlatShaded).concat(this.materialsFlatShadedBackSide).concat(this.materialsFlatShadedDoubleSide);
for (const m2 of materials) {
m2.dispose();
}
}
}
/**
* Performs cleanup tasks.
*/
dispose() {
this.originalMaterials.clear();
this.disposeMaterials();
}
/**
* Indicates whether the override material workaround is enabled.
*
* @type {Boolean}
*/
static get workaroundEnabled() {
return workaroundEnabled;
}
/**
* Enables or disables the override material workaround globally.
*
* This only affects post processing passes and effects.
*
* @type {Boolean}
*/
static set workaroundEnabled(value) {
workaroundEnabled = value;
}
};
// src/passes/ClearPass.js
var import_three5 = __require("three");
var color = /* @__PURE__ */ new import_three5.Color();
var ClearPass = class extends Pass {
/**
* Constructs a new clear pass.
*
* @param {Boolean} [color=true] - Determines whether the color buffer should be cleared.
* @param {Boolean} [depth=true] - Determines whether the depth buffer should be cleared.
* @param {Boolean} [stencil=false] - Determines whether the stencil buffer should be cleared.
*/
constructor(color2 = true, depth = true, stencil = false) {
super("ClearPass", null, null);
this.needsSwap = false;
this.color = color2;
this.depth = depth;
this.stencil = stencil;
this.overrideClearColor = null;
this.overrideClearAlpha = -1;
}
/**
* Sets the clear flags.
*
* @param {Boolean} color - Whether the color buffer should be cleared.
* @param {Boolean} depth - Whether the depth buffer should be cleared.
* @param {Boolean} stencil - Whether the stencil buffer should be cleared.
*/
setClearFlags(color2, depth, stencil) {
this.color = color2;
this.depth = depth;
this.stencil = stencil;
}
/**
* Returns the override clear color. Default is null.
*
* @deprecated Use overrideClearColor instead.
* @return {Color} The clear color.
*/
getOverrideClearColor() {
return this.overrideClearColor;
}
/**
* Sets the override clear color.
*
* @deprecated Use overrideClearColor instead.
* @param {Color} value - The clear color.
*/
setOverrideClearColor(value) {
this.overrideClearColor = value;
}
/**
* Returns the override clear alpha. Default is -1.
*
* @deprecated Use overrideClearAlpha instead.
* @return {Number} The clear alpha.
*/
getOverrideClearAlpha() {
return this.overrideClearAlpha;
}
/**
* Sets the override clear alpha.
*
* @deprecated Use overrideClearAlpha instead.
* @param {Number} value - The clear alpha.
*/
setOverrideClearAlpha(value) {
this.overrideClearAlpha = value;
}
/**
* Clears the input buffer or the screen.
*
* @param {WebGLRenderer} renderer - The renderer.
* @param {WebGLRenderTarget} inputBuffer - A frame buffer that contains the result of the previous pass.
* @param {WebGLRenderTarget} outputBuffer - A frame buffer that serves as the output render target unless this pass renders to screen.
* @param {Number} [deltaTime] - The time between the last frame and the current one in seconds.
* @param {Boolean} [stencilTest] - Indicates whether a stencil mask is active.
*/
render(renderer, inputBuffer, outputBuffer, deltaTime, stencilTest) {
const overrideClearColor = this.overrideClearColor;
const overrideClearAlpha = this.overrideClearAlpha;
const clearAlpha = renderer.getClearAlpha();
const hasOverrideClearColor = overrideClearColor !== null;
const hasOverrideClearAlpha = overrideClearAlpha >= 0;
if (hasOverrideClearColor) {
renderer.getClearColor(color);
renderer.setClearColor(overrideClearColor, hasOverrideClearAlpha ? overrideClearAlpha : clearAlpha);
} else if (hasOverrideClearAlpha) {
renderer.setClearAlpha(overrideClearAlpha);
}
renderer.setRenderTarget(this.renderToScreen ? null : inputBuffer);
renderer.clear(this.color, this.depth, this.stencil);
if (hasOverrideClearColor) {
renderer.setClearColor(color, clearAlpha);
} else if (hasOverrideClearAlpha) {
renderer.setClearAlpha(clearAlpha);
}
}
};
// src/utils/PerformanceLogger.js
var theEnabled = false;
var _PerformanceLogger = class _PerformanceLogger {
/**
* 获取单例实例
* @return {PerformanceLogger} 日志实例
*/
static getInstance() {
if (_PerformanceLogger.instance === null) {
_PerformanceLogger.instance = new _PerformanceLogger();
}
return _PerformanceLogger.instance;
}
/**
* 创建一个新的性能日志实例
* @param {Boolean} enabled - 是否启用日志
*/
constructor(enabled = theEnabled) {
this.enabled = enabled;
this.timers = /* @__PURE__ */ new Map();
this.collectTimes = false;
this.timeData = /* @__PURE__ */ new Map();
}
/**
* 启用日志
*/
enable() {
this.enabled = true;
}
/**
* 禁用日志
*/
disable() {
this.enabled = false;
}
/**
* 启用时间数据收集,用于性能分析
*/
enableTimeCollection() {
this.collectTimes = true;
}
/**
* 禁用时间数据收集
*/
disableTimeCollection() {
this.collectTimes = false;
}
/**
* 获取收集的时间数据
* @return {Object} 时间数据
*/
getTimeData() {
const result = {};
for (const [key, times] of this.timeData.entries()) {
if (times.length > 0) {
const sum = times.reduce((a, b) => a + b, 0);
result[key] = {
count: times.length,
total: sum,
average: sum / times.length,
min: Math.min(...times),