the-world-engine
Version:
three.js based, unity like game engine for browser
187 lines (183 loc) • 5.67 kB
JavaScript
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
import { Component } from "../../hierarchy_object/Component";
class EffectComposerRc {
static _map=new Map;
ic=0;
br;
ka=(e, t) => {
this.br.setSize(e, t);
};
constructor(e, t) {
this.br = t;
EffectComposerRc._map.set(e, this);
}
static createOraddReference(e, t) {
let i = EffectComposerRc._map.get(e);
if (i === undefined) {
const s = new EffectComposer(t);
const n = e.screen;
s.setSize(n.width, n.height);
i = new EffectComposerRc(e, s);
n.onResize.addListener(i.ka);
EffectComposerRc._map.set(e, i);
e.webGL.effectComposer = s;
}
i.ic += 1;
return i.br;
}
static removeReference(e) {
const t = EffectComposerRc._map.get(e);
if (t !== undefined) {
t.ic -= 1;
if (t.ic === 0) {
t.br.dispose();
const i = e.screen;
i.onResize.removeListener(t.ka);
EffectComposerRc._map.delete(e);
e.webGL.effectComposer = null;
}
}
}
}
export class WebGLGlobalPostProcessVolume extends Component {
sc=null;
br=null;
nc=true;
rc=true;
hc=true;
oc=[];
cc=null;
lc=null;
ac=e => {
if (this.sc !== null) {
this.sc.camera = e.threeCamera;
}
if (this.rc && this.cc && this.br) {
const t = this.engine.scene.unsafeGetThreeScene();
const [i, s] = this.cc(t, e.threeCamera, this.engine.screen);
this.fc(this.br, this.oc, i, this.lc ?? undefined);
this.oc = i;
this.lc = s ?? null;
}
};
ka=() => {
if (this.hc && this.cc && this.br) {
const e = this.engine.scene.unsafeGetThreeScene();
const t = this.engine.cameraContainer.camera;
const [i, s] = this.cc(e, t.threeCamera, this.engine.screen);
this.fc(this.br, this.oc, i, this.lc ?? undefined);
this.oc = i;
this.lc = s ?? null;
}
};
onEnable() {
const e = this.engine.scene.unsafeGetThreeScene();
const t = this.engine.cameraContainer;
const i = t.camera;
const s = this.engine.webGL;
if (i === null) {
throw new Error("WebGLGlobalPostProcessVolume must be loaded after camera.");
}
if (s === null) {
throw new Error("WebGLRenderer is not initialized.");
}
if (s.webglRenderer === null) {
throw new Error("You can't use WebGLRenderer wrapper for post processing.");
}
const n = this.br = EffectComposerRc.createOraddReference(this.engine, s.webglRenderer);
t.onCameraChanged.addListener(this.ac);
this.engine.screen.onResize.addListener(this.ka);
if (this.nc) {
const t = this.sc = new RenderPass(e, i.threeCamera);
n.addPass(t);
}
if (this.cc) {
const [t, s] = this.cc(e, i.threeCamera, this.engine.screen);
this.fc(n, this.oc, t, this.lc ?? undefined);
this.oc = t;
this.lc = s ?? null;
}
}
onDisable() {
const e = this.br;
if (this.sc !== null) {
e?.removePass(this.sc);
this.sc = null;
}
const t = this.oc;
if (e !== null) {
this.dc(e, t, this.lc ?? undefined);
this.oc = [];
this.lc = null;
EffectComposerRc.removeReference(this.engine);
this.br = null;
}
const i = this.engine.cameraContainer;
i.onCameraChanged.removeListener(this.ac);
this.engine.screen.onResize.removeListener(this.ka);
}
dc(e, t, i) {
const s = e.passes.indexOf(t[0]);
if (s !== -1) {
for (let i = 0; i < t.length; ++i) {
e.removePass(t[i]);
}
}
i?.();
}
fc(e, t, i, s) {
let n = -1;
if (0 < t.length) {
n = e.passes.indexOf(t[0]);
if (n !== -1) {
for (let i = 0; i < t.length; ++i) {
e.removePass(t[i]);
}
}
s?.();
}
if (n === -1) {
for (let t = 0; t < i.length; ++t) {
e.addPass(i[t]);
}
} else {
for (let t = 0; t < i.length; ++t) {
e.insertPass(i[t], n + t);
}
}
}
initializer(e) {
if (this.br) {
this.dc(this.br, this.oc, this.lc ?? undefined);
this.oc = [];
}
this.cc = e;
if (this.br) {
const e = this.engine.scene.unsafeGetThreeScene();
const t = this.engine.cameraContainer.camera;
const [i, s] = this.cc(e, t.threeCamera, this.engine.screen);
this.fc(this.br, this.oc, i, this.lc ?? undefined);
this.oc = i;
this.lc = s ?? null;
}
}
get willAddRenderPass() {
return this.nc;
}
set willAddRenderPass(e) {
this.nc = e;
}
get reInitializeWhenCameraChanged() {
return this.rc;
}
set reInitializeWhenCameraChanged(e) {
this.rc = e;
}
get reinitializeWhenScreenSizeChanged() {
return this.hc;
}
set reinitializeWhenScreenSizeChanged(e) {
this.hc = e;
}
}