Favivon - Correção

This commit is contained in:
2026-05-30 19:59:39 -03:00
parent 76ddaa815d
commit d7dfd221f0
32859 changed files with 5459654 additions and 404 deletions
+219
View File
@@ -0,0 +1,219 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
const CopyShader = require("../shaders/CopyShader.cjs");
const LuminosityShader = require("../shaders/LuminosityShader.cjs");
const ToneMapShader = require("../shaders/ToneMapShader.cjs");
class AdaptiveToneMappingPass extends Pass.Pass {
constructor(adaptive, resolution) {
super();
this.resolution = resolution !== void 0 ? resolution : 256;
this.needsInit = true;
this.adaptive = adaptive !== void 0 ? !!adaptive : true;
this.luminanceRT = null;
this.previousLuminanceRT = null;
this.currentLuminanceRT = null;
const copyShader = CopyShader.CopyShader;
this.copyUniforms = THREE.UniformsUtils.clone(copyShader.uniforms);
this.materialCopy = new THREE.ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
blending: THREE.NoBlending,
depthTest: false
});
this.materialLuminance = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(LuminosityShader.LuminosityShader.uniforms),
vertexShader: LuminosityShader.LuminosityShader.vertexShader,
fragmentShader: LuminosityShader.LuminosityShader.fragmentShader,
blending: THREE.NoBlending
});
this.adaptLuminanceShader = {
defines: {
MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2)).toFixed(1)
},
uniforms: {
lastLum: { value: null },
currentLum: { value: null },
minLuminance: { value: 0.01 },
delta: { value: 0.016 },
tau: { value: 1 }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec2 vUv;
uniform sampler2D lastLum;
uniform sampler2D currentLum;
uniform float minLuminance;
uniform float delta;
uniform float tau;
void main() {
vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );
vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );
float fLastLum = max( minLuminance, lastLum.r );
float fCurrentLum = max( minLuminance, currentLum.r );
//The adaption seems to work better in extreme lighting differences
//if the input luminance is squared.
fCurrentLum *= fCurrentLum;
// Adapt the luminance using Pattanaik's technique
float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));
// "fAdaptedLum = sqrt(fAdaptedLum);
gl_FragColor.r = fAdaptedLum;
}`
};
this.materialAdaptiveLum = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(this.adaptLuminanceShader.uniforms),
vertexShader: this.adaptLuminanceShader.vertexShader,
fragmentShader: this.adaptLuminanceShader.fragmentShader,
defines: Object.assign({}, this.adaptLuminanceShader.defines),
blending: THREE.NoBlending
});
this.materialToneMap = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(ToneMapShader.ToneMapShader.uniforms),
vertexShader: ToneMapShader.ToneMapShader.vertexShader,
fragmentShader: ToneMapShader.ToneMapShader.fragmentShader,
blending: THREE.NoBlending
});
this.fsQuad = new Pass.FullScreenQuad(null);
}
render(renderer, writeBuffer, readBuffer, deltaTime) {
if (this.needsInit) {
this.reset(renderer);
this.luminanceRT.texture.type = readBuffer.texture.type;
this.previousLuminanceRT.texture.type = readBuffer.texture.type;
this.currentLuminanceRT.texture.type = readBuffer.texture.type;
this.needsInit = false;
}
if (this.adaptive) {
this.fsQuad.material = this.materialLuminance;
this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture;
renderer.setRenderTarget(this.currentLuminanceRT);
this.fsQuad.render(renderer);
this.fsQuad.material = this.materialAdaptiveLum;
this.materialAdaptiveLum.uniforms.delta.value = deltaTime;
this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture;
this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture;
renderer.setRenderTarget(this.luminanceRT);
this.fsQuad.render(renderer);
this.fsQuad.material = this.materialCopy;
this.copyUniforms.tDiffuse.value = this.luminanceRT.texture;
renderer.setRenderTarget(this.previousLuminanceRT);
this.fsQuad.render(renderer);
}
this.fsQuad.material = this.materialToneMap;
this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
reset() {
if (this.luminanceRT) {
this.luminanceRT.dispose();
}
if (this.currentLuminanceRT) {
this.currentLuminanceRT.dispose();
}
if (this.previousLuminanceRT) {
this.previousLuminanceRT.dispose();
}
this.luminanceRT = new THREE.WebGLRenderTarget(this.resolution, this.resolution);
this.luminanceRT.texture.name = "AdaptiveToneMappingPass.l";
this.luminanceRT.texture.generateMipmaps = false;
this.previousLuminanceRT = new THREE.WebGLRenderTarget(this.resolution, this.resolution);
this.previousLuminanceRT.texture.name = "AdaptiveToneMappingPass.pl";
this.previousLuminanceRT.texture.generateMipmaps = false;
const pars = { minFilter: THREE.LinearMipmapLinearFilter, generateMipmaps: true };
this.currentLuminanceRT = new THREE.WebGLRenderTarget(this.resolution, this.resolution, pars);
this.currentLuminanceRT.texture.name = "AdaptiveToneMappingPass.cl";
if (this.adaptive) {
this.materialToneMap.defines["ADAPTED_LUMINANCE"] = "";
this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture;
}
this.fsQuad.material = new THREE.MeshBasicMaterial({ color: 7829367 });
this.materialLuminance.needsUpdate = true;
this.materialAdaptiveLum.needsUpdate = true;
this.materialToneMap.needsUpdate = true;
}
setAdaptive(adaptive) {
if (adaptive) {
this.adaptive = true;
this.materialToneMap.defines["ADAPTED_LUMINANCE"] = "";
this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture;
} else {
this.adaptive = false;
delete this.materialToneMap.defines["ADAPTED_LUMINANCE"];
this.materialToneMap.uniforms.luminanceMap.value = null;
}
this.materialToneMap.needsUpdate = true;
}
setAdaptionRate(rate) {
if (rate) {
this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate);
}
}
setMinLuminance(minLum) {
if (minLum) {
this.materialToneMap.uniforms.minLuminance.value = minLum;
this.materialAdaptiveLum.uniforms.minLuminance.value = minLum;
}
}
setMaxLuminance(maxLum) {
if (maxLum) {
this.materialToneMap.uniforms.maxLuminance.value = maxLum;
}
}
setAverageLuminance(avgLum) {
if (avgLum) {
this.materialToneMap.uniforms.averageLuminance.value = avgLum;
}
}
setMiddleGrey(middleGrey) {
if (middleGrey) {
this.materialToneMap.uniforms.middleGrey.value = middleGrey;
}
}
dispose() {
if (this.luminanceRT) {
this.luminanceRT.dispose();
}
if (this.previousLuminanceRT) {
this.previousLuminanceRT.dispose();
}
if (this.currentLuminanceRT) {
this.currentLuminanceRT.dispose();
}
if (this.materialLuminance) {
this.materialLuminance.dispose();
}
if (this.materialAdaptiveLum) {
this.materialAdaptiveLum.dispose();
}
if (this.materialCopy) {
this.materialCopy.dispose();
}
if (this.materialToneMap) {
this.materialToneMap.dispose();
}
}
}
exports.AdaptiveToneMappingPass = AdaptiveToneMappingPass;
//# sourceMappingURL=AdaptiveToneMappingPass.cjs.map
File diff suppressed because one or more lines are too long
+29
View File
@@ -0,0 +1,29 @@
import { WebGLRenderTarget, ShaderMaterial } from 'three'
import { Pass, FullScreenQuad } from './Pass'
export class AdaptiveToneMappingPass extends Pass {
constructor(adaptive?: boolean, resolution?: number)
adaptive: boolean
resolution: number
needsInit: number
luminanceRT: WebGLRenderTarget
previousLuminanceRT: WebGLRenderTarget
currentLuminanceRT: WebGLRenderTarget
copyUniforms: object
materialCopy: ShaderMaterial
materialLuminance: ShaderMaterial
adaptLuminanceShader: object
materialAdaptiveLum: ShaderMaterial
materialToneMap: ShaderMaterial
fsQuad: FullScreenQuad
reset(): void
setAdaptive(adaptive: boolean): void
setAdaptionRate(rate: number): void
setMinLuminance(minLum: number): void
setMaxLuminance(maxLum: number): void
setAverageLuminance(avgLum: number): void
setMiddleGrey(middleGrey: number): void
dispose(): void
}
+219
View File
@@ -0,0 +1,219 @@
import { UniformsUtils, ShaderMaterial, NoBlending, WebGLRenderTarget, MeshBasicMaterial, LinearMipmapLinearFilter } from "three";
import { Pass, FullScreenQuad } from "./Pass.js";
import { CopyShader } from "../shaders/CopyShader.js";
import { LuminosityShader } from "../shaders/LuminosityShader.js";
import { ToneMapShader } from "../shaders/ToneMapShader.js";
class AdaptiveToneMappingPass extends Pass {
constructor(adaptive, resolution) {
super();
this.resolution = resolution !== void 0 ? resolution : 256;
this.needsInit = true;
this.adaptive = adaptive !== void 0 ? !!adaptive : true;
this.luminanceRT = null;
this.previousLuminanceRT = null;
this.currentLuminanceRT = null;
const copyShader = CopyShader;
this.copyUniforms = UniformsUtils.clone(copyShader.uniforms);
this.materialCopy = new ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
blending: NoBlending,
depthTest: false
});
this.materialLuminance = new ShaderMaterial({
uniforms: UniformsUtils.clone(LuminosityShader.uniforms),
vertexShader: LuminosityShader.vertexShader,
fragmentShader: LuminosityShader.fragmentShader,
blending: NoBlending
});
this.adaptLuminanceShader = {
defines: {
MIP_LEVEL_1X1: (Math.log(this.resolution) / Math.log(2)).toFixed(1)
},
uniforms: {
lastLum: { value: null },
currentLum: { value: null },
minLuminance: { value: 0.01 },
delta: { value: 0.016 },
tau: { value: 1 }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec2 vUv;
uniform sampler2D lastLum;
uniform sampler2D currentLum;
uniform float minLuminance;
uniform float delta;
uniform float tau;
void main() {
vec4 lastLum = texture2D( lastLum, vUv, MIP_LEVEL_1X1 );
vec4 currentLum = texture2D( currentLum, vUv, MIP_LEVEL_1X1 );
float fLastLum = max( minLuminance, lastLum.r );
float fCurrentLum = max( minLuminance, currentLum.r );
//The adaption seems to work better in extreme lighting differences
//if the input luminance is squared.
fCurrentLum *= fCurrentLum;
// Adapt the luminance using Pattanaik's technique
float fAdaptedLum = fLastLum + (fCurrentLum - fLastLum) * (1.0 - exp(-delta * tau));
// "fAdaptedLum = sqrt(fAdaptedLum);
gl_FragColor.r = fAdaptedLum;
}`
};
this.materialAdaptiveLum = new ShaderMaterial({
uniforms: UniformsUtils.clone(this.adaptLuminanceShader.uniforms),
vertexShader: this.adaptLuminanceShader.vertexShader,
fragmentShader: this.adaptLuminanceShader.fragmentShader,
defines: Object.assign({}, this.adaptLuminanceShader.defines),
blending: NoBlending
});
this.materialToneMap = new ShaderMaterial({
uniforms: UniformsUtils.clone(ToneMapShader.uniforms),
vertexShader: ToneMapShader.vertexShader,
fragmentShader: ToneMapShader.fragmentShader,
blending: NoBlending
});
this.fsQuad = new FullScreenQuad(null);
}
render(renderer, writeBuffer, readBuffer, deltaTime) {
if (this.needsInit) {
this.reset(renderer);
this.luminanceRT.texture.type = readBuffer.texture.type;
this.previousLuminanceRT.texture.type = readBuffer.texture.type;
this.currentLuminanceRT.texture.type = readBuffer.texture.type;
this.needsInit = false;
}
if (this.adaptive) {
this.fsQuad.material = this.materialLuminance;
this.materialLuminance.uniforms.tDiffuse.value = readBuffer.texture;
renderer.setRenderTarget(this.currentLuminanceRT);
this.fsQuad.render(renderer);
this.fsQuad.material = this.materialAdaptiveLum;
this.materialAdaptiveLum.uniforms.delta.value = deltaTime;
this.materialAdaptiveLum.uniforms.lastLum.value = this.previousLuminanceRT.texture;
this.materialAdaptiveLum.uniforms.currentLum.value = this.currentLuminanceRT.texture;
renderer.setRenderTarget(this.luminanceRT);
this.fsQuad.render(renderer);
this.fsQuad.material = this.materialCopy;
this.copyUniforms.tDiffuse.value = this.luminanceRT.texture;
renderer.setRenderTarget(this.previousLuminanceRT);
this.fsQuad.render(renderer);
}
this.fsQuad.material = this.materialToneMap;
this.materialToneMap.uniforms.tDiffuse.value = readBuffer.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
reset() {
if (this.luminanceRT) {
this.luminanceRT.dispose();
}
if (this.currentLuminanceRT) {
this.currentLuminanceRT.dispose();
}
if (this.previousLuminanceRT) {
this.previousLuminanceRT.dispose();
}
this.luminanceRT = new WebGLRenderTarget(this.resolution, this.resolution);
this.luminanceRT.texture.name = "AdaptiveToneMappingPass.l";
this.luminanceRT.texture.generateMipmaps = false;
this.previousLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution);
this.previousLuminanceRT.texture.name = "AdaptiveToneMappingPass.pl";
this.previousLuminanceRT.texture.generateMipmaps = false;
const pars = { minFilter: LinearMipmapLinearFilter, generateMipmaps: true };
this.currentLuminanceRT = new WebGLRenderTarget(this.resolution, this.resolution, pars);
this.currentLuminanceRT.texture.name = "AdaptiveToneMappingPass.cl";
if (this.adaptive) {
this.materialToneMap.defines["ADAPTED_LUMINANCE"] = "";
this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture;
}
this.fsQuad.material = new MeshBasicMaterial({ color: 7829367 });
this.materialLuminance.needsUpdate = true;
this.materialAdaptiveLum.needsUpdate = true;
this.materialToneMap.needsUpdate = true;
}
setAdaptive(adaptive) {
if (adaptive) {
this.adaptive = true;
this.materialToneMap.defines["ADAPTED_LUMINANCE"] = "";
this.materialToneMap.uniforms.luminanceMap.value = this.luminanceRT.texture;
} else {
this.adaptive = false;
delete this.materialToneMap.defines["ADAPTED_LUMINANCE"];
this.materialToneMap.uniforms.luminanceMap.value = null;
}
this.materialToneMap.needsUpdate = true;
}
setAdaptionRate(rate) {
if (rate) {
this.materialAdaptiveLum.uniforms.tau.value = Math.abs(rate);
}
}
setMinLuminance(minLum) {
if (minLum) {
this.materialToneMap.uniforms.minLuminance.value = minLum;
this.materialAdaptiveLum.uniforms.minLuminance.value = minLum;
}
}
setMaxLuminance(maxLum) {
if (maxLum) {
this.materialToneMap.uniforms.maxLuminance.value = maxLum;
}
}
setAverageLuminance(avgLum) {
if (avgLum) {
this.materialToneMap.uniforms.averageLuminance.value = avgLum;
}
}
setMiddleGrey(middleGrey) {
if (middleGrey) {
this.materialToneMap.uniforms.middleGrey.value = middleGrey;
}
}
dispose() {
if (this.luminanceRT) {
this.luminanceRT.dispose();
}
if (this.previousLuminanceRT) {
this.previousLuminanceRT.dispose();
}
if (this.currentLuminanceRT) {
this.currentLuminanceRT.dispose();
}
if (this.materialLuminance) {
this.materialLuminance.dispose();
}
if (this.materialAdaptiveLum) {
this.materialAdaptiveLum.dispose();
}
if (this.materialCopy) {
this.materialCopy.dispose();
}
if (this.materialToneMap) {
this.materialToneMap.dispose();
}
}
}
export {
AdaptiveToneMappingPass
};
//# sourceMappingURL=AdaptiveToneMappingPass.js.map
File diff suppressed because one or more lines are too long
+69
View File
@@ -0,0 +1,69 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
const AfterimageShader = require("../shaders/AfterimageShader.cjs");
class AfterimagePass extends Pass.Pass {
constructor(damp = 0.96, shader = AfterimageShader.AfterimageShader) {
super();
__publicField(this, "shader");
__publicField(this, "uniforms");
__publicField(this, "textureComp");
__publicField(this, "textureOld");
__publicField(this, "shaderMaterial");
__publicField(this, "compFsQuad");
__publicField(this, "copyFsQuad");
this.shader = shader;
this.uniforms = THREE.UniformsUtils.clone(shader.uniforms);
this.uniforms["damp"].value = damp;
this.textureComp = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, {
minFilter: THREE.LinearFilter,
magFilter: THREE.NearestFilter,
format: THREE.RGBAFormat
});
this.textureOld = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, {
minFilter: THREE.LinearFilter,
magFilter: THREE.NearestFilter,
format: THREE.RGBAFormat
});
this.shaderMaterial = new THREE.ShaderMaterial({
uniforms: this.uniforms,
vertexShader: this.shader.vertexShader,
fragmentShader: this.shader.fragmentShader
});
this.compFsQuad = new Pass.FullScreenQuad(this.shaderMaterial);
let material = new THREE.MeshBasicMaterial();
this.copyFsQuad = new Pass.FullScreenQuad(material);
}
render(renderer, writeBuffer, readBuffer) {
this.uniforms["tOld"].value = this.textureOld.texture;
this.uniforms["tNew"].value = readBuffer.texture;
renderer.setRenderTarget(this.textureComp);
this.compFsQuad.render(renderer);
this.copyFsQuad.material.map = this.textureComp.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.copyFsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.copyFsQuad.render(renderer);
}
let temp = this.textureOld;
this.textureOld = this.textureComp;
this.textureComp = temp;
}
setSize(width, height) {
this.textureComp.setSize(width, height);
this.textureOld.setSize(width, height);
}
}
exports.AfterimagePass = AfterimagePass;
//# sourceMappingURL=AfterimagePass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"AfterimagePass.cjs","sources":["../../src/postprocessing/AfterimagePass.ts"],"sourcesContent":["import {\n LinearFilter,\n MeshBasicMaterial,\n NearestFilter,\n RGBAFormat,\n WebGLRenderer,\n ShaderMaterial,\n UniformsUtils,\n WebGLRenderTarget,\n} from 'three'\nimport { Pass, FullScreenQuad } from './Pass'\nimport { AfterimageShader } from '../shaders/AfterimageShader'\n\nclass AfterimagePass extends Pass {\n public shader\n public uniforms\n public textureComp: WebGLRenderTarget\n public textureOld: WebGLRenderTarget\n public shaderMaterial: ShaderMaterial\n public compFsQuad: FullScreenQuad<ShaderMaterial>\n public copyFsQuad: FullScreenQuad<MeshBasicMaterial>\n\n constructor(damp = 0.96, shader = AfterimageShader) {\n super()\n\n this.shader = shader\n this.uniforms = UniformsUtils.clone(shader.uniforms)\n this.uniforms['damp'].value = damp\n\n this.textureComp = new WebGLRenderTarget(window.innerWidth, window.innerHeight, {\n minFilter: LinearFilter,\n magFilter: NearestFilter,\n format: RGBAFormat,\n })\n\n this.textureOld = new WebGLRenderTarget(window.innerWidth, window.innerHeight, {\n minFilter: LinearFilter,\n magFilter: NearestFilter,\n format: RGBAFormat,\n })\n\n this.shaderMaterial = new ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: this.shader.vertexShader,\n fragmentShader: this.shader.fragmentShader,\n })\n\n this.compFsQuad = new FullScreenQuad(this.shaderMaterial)\n\n let material = new MeshBasicMaterial()\n this.copyFsQuad = new FullScreenQuad(material)\n }\n\n public render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void {\n this.uniforms['tOld'].value = this.textureOld.texture\n this.uniforms['tNew'].value = readBuffer.texture\n\n renderer.setRenderTarget(this.textureComp)\n this.compFsQuad.render(renderer)\n\n this.copyFsQuad.material.map = this.textureComp.texture\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.copyFsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n\n if (this.clear) renderer.clear()\n\n this.copyFsQuad.render(renderer)\n }\n\n // Swap buffers.\n let temp = this.textureOld\n this.textureOld = this.textureComp\n this.textureComp = temp\n // Now textureOld contains the latest image, ready for the next frame.\n }\n\n public setSize(width: number, height: number): void {\n this.textureComp.setSize(width, height)\n this.textureOld.setSize(width, height)\n }\n}\n\nexport { AfterimagePass }\n"],"names":["Pass","AfterimageShader","UniformsUtils","WebGLRenderTarget","LinearFilter","NearestFilter","RGBAFormat","ShaderMaterial","FullScreenQuad","MeshBasicMaterial"],"mappings":";;;;;;;;;;;AAaA,MAAM,uBAAuBA,KAAAA,KAAK;AAAA,EAShC,YAAY,OAAO,MAAM,SAASC,iBAAAA,kBAAkB;AAC5C;AATD;AACA;AACA;AACA;AACA;AACA;AACA;AAKL,SAAK,SAAS;AACd,SAAK,WAAWC,MAAA,cAAc,MAAM,OAAO,QAAQ;AAC9C,SAAA,SAAS,MAAM,EAAE,QAAQ;AAE9B,SAAK,cAAc,IAAIC,MAAA,kBAAkB,OAAO,YAAY,OAAO,aAAa;AAAA,MAC9E,WAAWC,MAAA;AAAA,MACX,WAAWC,MAAA;AAAA,MACX,QAAQC,MAAA;AAAA,IAAA,CACT;AAED,SAAK,aAAa,IAAIH,MAAA,kBAAkB,OAAO,YAAY,OAAO,aAAa;AAAA,MAC7E,WAAWC,MAAA;AAAA,MACX,WAAWC,MAAA;AAAA,MACX,QAAQC,MAAA;AAAA,IAAA,CACT;AAEI,SAAA,iBAAiB,IAAIC,qBAAe;AAAA,MACvC,UAAU,KAAK;AAAA,MACf,cAAc,KAAK,OAAO;AAAA,MAC1B,gBAAgB,KAAK,OAAO;AAAA,IAAA,CAC7B;AAED,SAAK,aAAa,IAAIC,KAAe,eAAA,KAAK,cAAc;AAEpD,QAAA,WAAW,IAAIC,MAAAA;AACd,SAAA,aAAa,IAAID,KAAA,eAAe,QAAQ;AAAA,EAC/C;AAAA,EAEO,OAAO,UAAyB,aAAgC,YAAqC;AAC1G,SAAK,SAAS,MAAM,EAAE,QAAQ,KAAK,WAAW;AAC9C,SAAK,SAAS,MAAM,EAAE,QAAQ,WAAW;AAEhC,aAAA,gBAAgB,KAAK,WAAW;AACpC,SAAA,WAAW,OAAO,QAAQ;AAE/B,SAAK,WAAW,SAAS,MAAM,KAAK,YAAY;AAEhD,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,WAAW,OAAO,QAAQ;AAAA,IAAA,OAC1B;AACL,eAAS,gBAAgB,WAAW;AAEpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAE1B,WAAA,WAAW,OAAO,QAAQ;AAAA,IACjC;AAGA,QAAI,OAAO,KAAK;AAChB,SAAK,aAAa,KAAK;AACvB,SAAK,cAAc;AAAA,EAErB;AAAA,EAEO,QAAQ,OAAe,QAAsB;AAC7C,SAAA,YAAY,QAAQ,OAAO,MAAM;AACjC,SAAA,WAAW,QAAQ,OAAO,MAAM;AAAA,EACvC;AACF;;"}
+15
View File
@@ -0,0 +1,15 @@
import { MeshBasicMaterial, WebGLRenderer, ShaderMaterial, WebGLRenderTarget } from 'three';
import { Pass, FullScreenQuad } from './Pass';
declare class AfterimagePass extends Pass {
shader: import("../shaders/AfterimageShader").IAfterimageShader;
uniforms: any;
textureComp: WebGLRenderTarget;
textureOld: WebGLRenderTarget;
shaderMaterial: ShaderMaterial;
compFsQuad: FullScreenQuad<ShaderMaterial>;
copyFsQuad: FullScreenQuad<MeshBasicMaterial>;
constructor(damp?: number, shader?: import("../shaders/AfterimageShader").IAfterimageShader);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
setSize(width: number, height: number): void;
}
export { AfterimagePass };
+69
View File
@@ -0,0 +1,69 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { UniformsUtils, WebGLRenderTarget, LinearFilter, NearestFilter, RGBAFormat, ShaderMaterial, MeshBasicMaterial } from "three";
import { Pass, FullScreenQuad } from "./Pass.js";
import { AfterimageShader } from "../shaders/AfterimageShader.js";
class AfterimagePass extends Pass {
constructor(damp = 0.96, shader = AfterimageShader) {
super();
__publicField(this, "shader");
__publicField(this, "uniforms");
__publicField(this, "textureComp");
__publicField(this, "textureOld");
__publicField(this, "shaderMaterial");
__publicField(this, "compFsQuad");
__publicField(this, "copyFsQuad");
this.shader = shader;
this.uniforms = UniformsUtils.clone(shader.uniforms);
this.uniforms["damp"].value = damp;
this.textureComp = new WebGLRenderTarget(window.innerWidth, window.innerHeight, {
minFilter: LinearFilter,
magFilter: NearestFilter,
format: RGBAFormat
});
this.textureOld = new WebGLRenderTarget(window.innerWidth, window.innerHeight, {
minFilter: LinearFilter,
magFilter: NearestFilter,
format: RGBAFormat
});
this.shaderMaterial = new ShaderMaterial({
uniforms: this.uniforms,
vertexShader: this.shader.vertexShader,
fragmentShader: this.shader.fragmentShader
});
this.compFsQuad = new FullScreenQuad(this.shaderMaterial);
let material = new MeshBasicMaterial();
this.copyFsQuad = new FullScreenQuad(material);
}
render(renderer, writeBuffer, readBuffer) {
this.uniforms["tOld"].value = this.textureOld.texture;
this.uniforms["tNew"].value = readBuffer.texture;
renderer.setRenderTarget(this.textureComp);
this.compFsQuad.render(renderer);
this.copyFsQuad.material.map = this.textureComp.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.copyFsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.copyFsQuad.render(renderer);
}
let temp = this.textureOld;
this.textureOld = this.textureComp;
this.textureComp = temp;
}
setSize(width, height) {
this.textureComp.setSize(width, height);
this.textureOld.setSize(width, height);
}
}
export {
AfterimagePass
};
//# sourceMappingURL=AfterimagePass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"AfterimagePass.js","sources":["../../src/postprocessing/AfterimagePass.ts"],"sourcesContent":["import {\n LinearFilter,\n MeshBasicMaterial,\n NearestFilter,\n RGBAFormat,\n WebGLRenderer,\n ShaderMaterial,\n UniformsUtils,\n WebGLRenderTarget,\n} from 'three'\nimport { Pass, FullScreenQuad } from './Pass'\nimport { AfterimageShader } from '../shaders/AfterimageShader'\n\nclass AfterimagePass extends Pass {\n public shader\n public uniforms\n public textureComp: WebGLRenderTarget\n public textureOld: WebGLRenderTarget\n public shaderMaterial: ShaderMaterial\n public compFsQuad: FullScreenQuad<ShaderMaterial>\n public copyFsQuad: FullScreenQuad<MeshBasicMaterial>\n\n constructor(damp = 0.96, shader = AfterimageShader) {\n super()\n\n this.shader = shader\n this.uniforms = UniformsUtils.clone(shader.uniforms)\n this.uniforms['damp'].value = damp\n\n this.textureComp = new WebGLRenderTarget(window.innerWidth, window.innerHeight, {\n minFilter: LinearFilter,\n magFilter: NearestFilter,\n format: RGBAFormat,\n })\n\n this.textureOld = new WebGLRenderTarget(window.innerWidth, window.innerHeight, {\n minFilter: LinearFilter,\n magFilter: NearestFilter,\n format: RGBAFormat,\n })\n\n this.shaderMaterial = new ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: this.shader.vertexShader,\n fragmentShader: this.shader.fragmentShader,\n })\n\n this.compFsQuad = new FullScreenQuad(this.shaderMaterial)\n\n let material = new MeshBasicMaterial()\n this.copyFsQuad = new FullScreenQuad(material)\n }\n\n public render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void {\n this.uniforms['tOld'].value = this.textureOld.texture\n this.uniforms['tNew'].value = readBuffer.texture\n\n renderer.setRenderTarget(this.textureComp)\n this.compFsQuad.render(renderer)\n\n this.copyFsQuad.material.map = this.textureComp.texture\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.copyFsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n\n if (this.clear) renderer.clear()\n\n this.copyFsQuad.render(renderer)\n }\n\n // Swap buffers.\n let temp = this.textureOld\n this.textureOld = this.textureComp\n this.textureComp = temp\n // Now textureOld contains the latest image, ready for the next frame.\n }\n\n public setSize(width: number, height: number): void {\n this.textureComp.setSize(width, height)\n this.textureOld.setSize(width, height)\n }\n}\n\nexport { AfterimagePass }\n"],"names":[],"mappings":";;;;;;;;;AAaA,MAAM,uBAAuB,KAAK;AAAA,EAShC,YAAY,OAAO,MAAM,SAAS,kBAAkB;AAC5C;AATD;AACA;AACA;AACA;AACA;AACA;AACA;AAKL,SAAK,SAAS;AACd,SAAK,WAAW,cAAc,MAAM,OAAO,QAAQ;AAC9C,SAAA,SAAS,MAAM,EAAE,QAAQ;AAE9B,SAAK,cAAc,IAAI,kBAAkB,OAAO,YAAY,OAAO,aAAa;AAAA,MAC9E,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,CACT;AAED,SAAK,aAAa,IAAI,kBAAkB,OAAO,YAAY,OAAO,aAAa;AAAA,MAC7E,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,CACT;AAEI,SAAA,iBAAiB,IAAI,eAAe;AAAA,MACvC,UAAU,KAAK;AAAA,MACf,cAAc,KAAK,OAAO;AAAA,MAC1B,gBAAgB,KAAK,OAAO;AAAA,IAAA,CAC7B;AAED,SAAK,aAAa,IAAI,eAAe,KAAK,cAAc;AAEpD,QAAA,WAAW,IAAI;AACd,SAAA,aAAa,IAAI,eAAe,QAAQ;AAAA,EAC/C;AAAA,EAEO,OAAO,UAAyB,aAAgC,YAAqC;AAC1G,SAAK,SAAS,MAAM,EAAE,QAAQ,KAAK,WAAW;AAC9C,SAAK,SAAS,MAAM,EAAE,QAAQ,WAAW;AAEhC,aAAA,gBAAgB,KAAK,WAAW;AACpC,SAAA,WAAW,OAAO,QAAQ;AAE/B,SAAK,WAAW,SAAS,MAAM,KAAK,YAAY;AAEhD,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,WAAW,OAAO,QAAQ;AAAA,IAAA,OAC1B;AACL,eAAS,gBAAgB,WAAW;AAEpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAE1B,WAAA,WAAW,OAAO,QAAQ;AAAA,IACjC;AAGA,QAAI,OAAO,KAAK;AAChB,SAAK,aAAa,KAAK;AACvB,SAAK,cAAc;AAAA,EAErB;AAAA,EAEO,QAAQ,OAAe,QAAsB;AAC7C,SAAA,YAAY,QAAQ,OAAO,MAAM;AACjC,SAAA,WAAW,QAAQ,OAAO,MAAM;AAAA,EACvC;AACF;"}
+110
View File
@@ -0,0 +1,110 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const ConvolutionShader = require("../shaders/ConvolutionShader.cjs");
class BloomPass extends Pass.Pass {
constructor(strength = 1, kernelSize = 25, sigma = 4, resolution = 256) {
super();
__publicField(this, "renderTargetX");
__publicField(this, "renderTargetY");
__publicField(this, "materialCombine");
__publicField(this, "materialConvolution");
__publicField(this, "fsQuad");
__publicField(this, "combineUniforms");
__publicField(this, "convolutionUniforms");
__publicField(this, "blurX", new THREE.Vector2(1953125e-9, 0));
__publicField(this, "blurY", new THREE.Vector2(0, 1953125e-9));
this.renderTargetX = new THREE.WebGLRenderTarget(resolution, resolution);
this.renderTargetX.texture.name = "BloomPass.x";
this.renderTargetY = new THREE.WebGLRenderTarget(resolution, resolution);
this.renderTargetY.texture.name = "BloomPass.y";
this.combineUniforms = THREE.UniformsUtils.clone(CombineShader.uniforms);
this.combineUniforms["strength"].value = strength;
this.materialCombine = new THREE.ShaderMaterial({
uniforms: this.combineUniforms,
vertexShader: CombineShader.vertexShader,
fragmentShader: CombineShader.fragmentShader,
blending: THREE.AdditiveBlending,
transparent: true
});
if (ConvolutionShader.ConvolutionShader === void 0)
console.error("BloomPass relies on ConvolutionShader");
const convolutionShader = ConvolutionShader.ConvolutionShader;
this.convolutionUniforms = THREE.UniformsUtils.clone(convolutionShader.uniforms);
this.convolutionUniforms["uImageIncrement"].value = this.blurX;
this.convolutionUniforms["cKernel"].value = ConvolutionShader.ConvolutionShader.buildKernel(sigma);
this.materialConvolution = new THREE.ShaderMaterial({
uniforms: this.convolutionUniforms,
vertexShader: convolutionShader.vertexShader,
fragmentShader: convolutionShader.fragmentShader,
defines: {
KERNEL_SIZE_FLOAT: kernelSize.toFixed(1),
KERNEL_SIZE_INT: kernelSize.toFixed(0)
}
});
this.needsSwap = false;
this.fsQuad = new Pass.FullScreenQuad(this.materialConvolution);
}
render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) {
if (maskActive)
renderer.state.buffers.stencil.setTest(false);
this.fsQuad.material = this.materialConvolution;
this.convolutionUniforms["tDiffuse"].value = readBuffer.texture;
this.convolutionUniforms["uImageIncrement"].value = this.blurX;
renderer.setRenderTarget(this.renderTargetX);
renderer.clear();
this.fsQuad.render(renderer);
this.convolutionUniforms["tDiffuse"].value = this.renderTargetX.texture;
this.convolutionUniforms["uImageIncrement"].value = this.blurY;
renderer.setRenderTarget(this.renderTargetY);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.materialCombine;
this.combineUniforms["tDiffuse"].value = this.renderTargetY.texture;
if (maskActive)
renderer.state.buffers.stencil.setTest(true);
renderer.setRenderTarget(readBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
const CombineShader = {
uniforms: {
tDiffuse: {
value: null
},
strength: {
value: 1
}
},
vertexShader: (
/* glsl */
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
uniform float strength;
uniform sampler2D tDiffuse;
varying vec2 vUv;
void main() {
vec4 texel = texture2D( tDiffuse, vUv );
gl_FragColor = strength * texel;
}`
)
};
exports.BloomPass = BloomPass;
//# sourceMappingURL=BloomPass.cjs.map
File diff suppressed because one or more lines are too long
+29
View File
@@ -0,0 +1,29 @@
import { Pass, FullScreenQuad } from './Pass';
import { IUniform, ShaderMaterial, Vector2, WebGLRenderer, WebGLRenderTarget } from 'three';
import { ConvolutionShader } from '../shaders/ConvolutionShader';
declare class BloomPass extends Pass {
renderTargetX: WebGLRenderTarget;
renderTargetY: WebGLRenderTarget;
materialCombine: ShaderMaterial;
materialConvolution: ShaderMaterial;
fsQuad: FullScreenQuad;
combineUniforms: Record<keyof typeof CombineShader['uniforms'], IUniform<any>>;
convolutionUniforms: Record<keyof typeof ConvolutionShader['uniforms'], IUniform<any>>;
blurX: Vector2;
blurY: Vector2;
constructor(strength?: number, kernelSize?: number, sigma?: number, resolution?: number);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean): void;
}
declare const CombineShader: {
uniforms: {
tDiffuse: {
value: null;
};
strength: {
value: number;
};
};
vertexShader: string;
fragmentShader: string;
};
export { BloomPass };
+110
View File
@@ -0,0 +1,110 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { Vector2, WebGLRenderTarget, UniformsUtils, ShaderMaterial, AdditiveBlending } from "three";
import { ConvolutionShader } from "../shaders/ConvolutionShader.js";
class BloomPass extends Pass {
constructor(strength = 1, kernelSize = 25, sigma = 4, resolution = 256) {
super();
__publicField(this, "renderTargetX");
__publicField(this, "renderTargetY");
__publicField(this, "materialCombine");
__publicField(this, "materialConvolution");
__publicField(this, "fsQuad");
__publicField(this, "combineUniforms");
__publicField(this, "convolutionUniforms");
__publicField(this, "blurX", new Vector2(1953125e-9, 0));
__publicField(this, "blurY", new Vector2(0, 1953125e-9));
this.renderTargetX = new WebGLRenderTarget(resolution, resolution);
this.renderTargetX.texture.name = "BloomPass.x";
this.renderTargetY = new WebGLRenderTarget(resolution, resolution);
this.renderTargetY.texture.name = "BloomPass.y";
this.combineUniforms = UniformsUtils.clone(CombineShader.uniforms);
this.combineUniforms["strength"].value = strength;
this.materialCombine = new ShaderMaterial({
uniforms: this.combineUniforms,
vertexShader: CombineShader.vertexShader,
fragmentShader: CombineShader.fragmentShader,
blending: AdditiveBlending,
transparent: true
});
if (ConvolutionShader === void 0)
console.error("BloomPass relies on ConvolutionShader");
const convolutionShader = ConvolutionShader;
this.convolutionUniforms = UniformsUtils.clone(convolutionShader.uniforms);
this.convolutionUniforms["uImageIncrement"].value = this.blurX;
this.convolutionUniforms["cKernel"].value = ConvolutionShader.buildKernel(sigma);
this.materialConvolution = new ShaderMaterial({
uniforms: this.convolutionUniforms,
vertexShader: convolutionShader.vertexShader,
fragmentShader: convolutionShader.fragmentShader,
defines: {
KERNEL_SIZE_FLOAT: kernelSize.toFixed(1),
KERNEL_SIZE_INT: kernelSize.toFixed(0)
}
});
this.needsSwap = false;
this.fsQuad = new FullScreenQuad(this.materialConvolution);
}
render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) {
if (maskActive)
renderer.state.buffers.stencil.setTest(false);
this.fsQuad.material = this.materialConvolution;
this.convolutionUniforms["tDiffuse"].value = readBuffer.texture;
this.convolutionUniforms["uImageIncrement"].value = this.blurX;
renderer.setRenderTarget(this.renderTargetX);
renderer.clear();
this.fsQuad.render(renderer);
this.convolutionUniforms["tDiffuse"].value = this.renderTargetX.texture;
this.convolutionUniforms["uImageIncrement"].value = this.blurY;
renderer.setRenderTarget(this.renderTargetY);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.materialCombine;
this.combineUniforms["tDiffuse"].value = this.renderTargetY.texture;
if (maskActive)
renderer.state.buffers.stencil.setTest(true);
renderer.setRenderTarget(readBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
const CombineShader = {
uniforms: {
tDiffuse: {
value: null
},
strength: {
value: 1
}
},
vertexShader: (
/* glsl */
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`
),
fragmentShader: (
/* glsl */
`
uniform float strength;
uniform sampler2D tDiffuse;
varying vec2 vUv;
void main() {
vec4 texel = texture2D( tDiffuse, vUv );
gl_FragColor = strength * texel;
}`
)
};
export {
BloomPass
};
//# sourceMappingURL=BloomPass.js.map
File diff suppressed because one or more lines are too long
+91
View File
@@ -0,0 +1,91 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const BokehShader = require("../shaders/BokehShader.cjs");
class BokehPass extends Pass.Pass {
constructor(scene, camera, params) {
super();
__publicField(this, "scene");
__publicField(this, "camera");
__publicField(this, "renderTargetDepth");
__publicField(this, "materialDepth");
__publicField(this, "materialBokeh");
__publicField(this, "fsQuad");
__publicField(this, "_oldClearColor");
__publicField(this, "uniforms");
this.scene = scene;
this.camera = camera;
const focus = params.focus !== void 0 ? params.focus : 1;
const aspect = params.aspect !== void 0 ? params.aspect : camera.aspect;
const aperture = params.aperture !== void 0 ? params.aperture : 0.025;
const maxblur = params.maxblur !== void 0 ? params.maxblur : 1;
const width = params.width || window.innerWidth || 1;
const height = params.height || window.innerHeight || 1;
this.renderTargetDepth = new THREE.WebGLRenderTarget(width, height, {
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter
});
this.renderTargetDepth.texture.name = "BokehPass.depth";
this.materialDepth = new THREE.MeshDepthMaterial();
this.materialDepth.depthPacking = THREE.RGBADepthPacking;
this.materialDepth.blending = THREE.NoBlending;
if (BokehShader.BokehShader === void 0) {
console.error("BokehPass relies on BokehShader");
}
const bokehShader = BokehShader.BokehShader;
const bokehUniforms = THREE.UniformsUtils.clone(bokehShader.uniforms);
bokehUniforms["tDepth"].value = this.renderTargetDepth.texture;
bokehUniforms["focus"].value = focus;
bokehUniforms["aspect"].value = aspect;
bokehUniforms["aperture"].value = aperture;
bokehUniforms["maxblur"].value = maxblur;
bokehUniforms["nearClip"].value = camera.near;
bokehUniforms["farClip"].value = camera.far;
this.materialBokeh = new THREE.ShaderMaterial({
defines: Object.assign({}, bokehShader.defines),
uniforms: bokehUniforms,
vertexShader: bokehShader.vertexShader,
fragmentShader: bokehShader.fragmentShader
});
this.uniforms = bokehUniforms;
this.needsSwap = false;
this.fsQuad = new Pass.FullScreenQuad(this.materialBokeh);
this._oldClearColor = new THREE.Color();
}
render(renderer, writeBuffer, readBuffer) {
this.scene.overrideMaterial = this.materialDepth;
renderer.getClearColor(this._oldClearColor);
const oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.setClearColor(16777215);
renderer.setClearAlpha(1);
renderer.setRenderTarget(this.renderTargetDepth);
renderer.clear();
renderer.render(this.scene, this.camera);
this.uniforms["tColor"].value = readBuffer.texture;
this.uniforms["nearClip"].value = this.camera.near;
this.uniforms["farClip"].value = this.camera.far;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
renderer.clear();
this.fsQuad.render(renderer);
}
this.scene.overrideMaterial = null;
renderer.setClearColor(this._oldClearColor);
renderer.setClearAlpha(oldClearAlpha);
renderer.autoClear = oldAutoClear;
}
}
exports.BokehPass = BokehPass;
//# sourceMappingURL=BokehPass.cjs.map
File diff suppressed because one or more lines are too long
+26
View File
@@ -0,0 +1,26 @@
/**
* Depth-of-field post-process with bokeh shader
*/
import { Pass, FullScreenQuad } from './Pass';
import { MeshDepthMaterial, PerspectiveCamera, Scene, ShaderMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
type BokehPassParams = {
focus?: number;
aspect?: number;
aperture?: number;
maxblur?: number;
width?: number;
height?: number;
};
declare class BokehPass extends Pass {
scene: Scene;
camera: PerspectiveCamera;
renderTargetDepth: WebGLRenderTarget;
materialDepth: MeshDepthMaterial;
materialBokeh: ShaderMaterial;
fsQuad: FullScreenQuad;
private _oldClearColor;
uniforms: any;
constructor(scene: Scene, camera: PerspectiveCamera, params: BokehPassParams);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
}
export { BokehPass };
+91
View File
@@ -0,0 +1,91 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { WebGLRenderTarget, NearestFilter, MeshDepthMaterial, RGBADepthPacking, NoBlending, UniformsUtils, ShaderMaterial, Color } from "three";
import { BokehShader } from "../shaders/BokehShader.js";
class BokehPass extends Pass {
constructor(scene, camera, params) {
super();
__publicField(this, "scene");
__publicField(this, "camera");
__publicField(this, "renderTargetDepth");
__publicField(this, "materialDepth");
__publicField(this, "materialBokeh");
__publicField(this, "fsQuad");
__publicField(this, "_oldClearColor");
__publicField(this, "uniforms");
this.scene = scene;
this.camera = camera;
const focus = params.focus !== void 0 ? params.focus : 1;
const aspect = params.aspect !== void 0 ? params.aspect : camera.aspect;
const aperture = params.aperture !== void 0 ? params.aperture : 0.025;
const maxblur = params.maxblur !== void 0 ? params.maxblur : 1;
const width = params.width || window.innerWidth || 1;
const height = params.height || window.innerHeight || 1;
this.renderTargetDepth = new WebGLRenderTarget(width, height, {
minFilter: NearestFilter,
magFilter: NearestFilter
});
this.renderTargetDepth.texture.name = "BokehPass.depth";
this.materialDepth = new MeshDepthMaterial();
this.materialDepth.depthPacking = RGBADepthPacking;
this.materialDepth.blending = NoBlending;
if (BokehShader === void 0) {
console.error("BokehPass relies on BokehShader");
}
const bokehShader = BokehShader;
const bokehUniforms = UniformsUtils.clone(bokehShader.uniforms);
bokehUniforms["tDepth"].value = this.renderTargetDepth.texture;
bokehUniforms["focus"].value = focus;
bokehUniforms["aspect"].value = aspect;
bokehUniforms["aperture"].value = aperture;
bokehUniforms["maxblur"].value = maxblur;
bokehUniforms["nearClip"].value = camera.near;
bokehUniforms["farClip"].value = camera.far;
this.materialBokeh = new ShaderMaterial({
defines: Object.assign({}, bokehShader.defines),
uniforms: bokehUniforms,
vertexShader: bokehShader.vertexShader,
fragmentShader: bokehShader.fragmentShader
});
this.uniforms = bokehUniforms;
this.needsSwap = false;
this.fsQuad = new FullScreenQuad(this.materialBokeh);
this._oldClearColor = new Color();
}
render(renderer, writeBuffer, readBuffer) {
this.scene.overrideMaterial = this.materialDepth;
renderer.getClearColor(this._oldClearColor);
const oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.setClearColor(16777215);
renderer.setClearAlpha(1);
renderer.setRenderTarget(this.renderTargetDepth);
renderer.clear();
renderer.render(this.scene, this.camera);
this.uniforms["tColor"].value = readBuffer.texture;
this.uniforms["nearClip"].value = this.camera.near;
this.uniforms["farClip"].value = this.camera.far;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
renderer.clear();
this.fsQuad.render(renderer);
}
this.scene.overrideMaterial = null;
renderer.setClearColor(this._oldClearColor);
renderer.setClearAlpha(oldClearAlpha);
renderer.autoClear = oldAutoClear;
}
}
export {
BokehPass
};
//# sourceMappingURL=BokehPass.js.map
File diff suppressed because one or more lines are too long
+37
View File
@@ -0,0 +1,37 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
class ClearPass extends Pass.Pass {
constructor(clearColor, clearAlpha) {
super();
__publicField(this, "clearColor");
__publicField(this, "clearAlpha");
__publicField(this, "_oldClearColor");
this.needsSwap = false;
this.clearColor = clearColor !== void 0 ? clearColor : 0;
this.clearAlpha = clearAlpha !== void 0 ? clearAlpha : 0;
this._oldClearColor = new THREE.Color();
}
render(renderer, writeBuffer, readBuffer) {
let oldClearAlpha;
if (this.clearColor) {
renderer.getClearColor(this._oldClearColor);
oldClearAlpha = renderer.getClearAlpha();
renderer.setClearColor(this.clearColor, this.clearAlpha);
}
renderer.setRenderTarget(this.renderToScreen ? null : readBuffer);
renderer.clear();
if (this.clearColor) {
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
}
}
}
exports.ClearPass = ClearPass;
//# sourceMappingURL=ClearPass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ClearPass.cjs","sources":["../../src/postprocessing/ClearPass.ts"],"sourcesContent":["import { Pass } from './Pass'\nimport { Color, WebGLRenderer, WebGLRenderTarget } from 'three'\n\nclass ClearPass extends Pass {\n public clearColor: Color | string | number\n public clearAlpha: number\n\n private _oldClearColor: Color\n\n constructor(clearColor?: Color | string | number, clearAlpha?: number) {\n super()\n this.needsSwap = false\n this.clearColor = clearColor !== undefined ? clearColor : 0x000000\n this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0\n this._oldClearColor = new Color()\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n /*, deltaTime, maskActive */\n ): void {\n let oldClearAlpha\n\n if (this.clearColor) {\n renderer.getClearColor(this._oldClearColor)\n oldClearAlpha = renderer.getClearAlpha()\n renderer.setClearColor(this.clearColor, this.clearAlpha)\n }\n\n renderer.setRenderTarget(this.renderToScreen ? null : readBuffer)\n renderer.clear()\n\n if (this.clearColor) {\n renderer.setClearColor(this._oldClearColor, oldClearAlpha)\n }\n }\n}\n\nexport { ClearPass }\n"],"names":["Pass","Color"],"mappings":";;;;;;;;;;AAGA,MAAM,kBAAkBA,KAAAA,KAAK;AAAA,EAM3B,YAAY,YAAsC,YAAqB;AAC/D;AAND;AACA;AAEC;AAIN,SAAK,YAAY;AACZ,SAAA,aAAa,eAAe,SAAY,aAAa;AACrD,SAAA,aAAa,eAAe,SAAY,aAAa;AACrD,SAAA,iBAAiB,IAAIC,MAAAA;EAC5B;AAAA,EAEO,OACL,UACA,aACA,YAEM;AACF,QAAA;AAEJ,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,cAAc;AAC1C,sBAAgB,SAAS;AACzB,eAAS,cAAc,KAAK,YAAY,KAAK,UAAU;AAAA,IACzD;AAEA,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,UAAU;AAChE,aAAS,MAAM;AAEf,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,gBAAgB,aAAa;AAAA,IAC3D;AAAA,EACF;AACF;;"}
+10
View File
@@ -0,0 +1,10 @@
import { Pass } from './Pass';
import { Color, WebGLRenderer, WebGLRenderTarget } from 'three';
declare class ClearPass extends Pass {
clearColor: Color | string | number;
clearAlpha: number;
private _oldClearColor;
constructor(clearColor?: Color | string | number, clearAlpha?: number);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
}
export { ClearPass };
+37
View File
@@ -0,0 +1,37 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass } from "./Pass.js";
import { Color } from "three";
class ClearPass extends Pass {
constructor(clearColor, clearAlpha) {
super();
__publicField(this, "clearColor");
__publicField(this, "clearAlpha");
__publicField(this, "_oldClearColor");
this.needsSwap = false;
this.clearColor = clearColor !== void 0 ? clearColor : 0;
this.clearAlpha = clearAlpha !== void 0 ? clearAlpha : 0;
this._oldClearColor = new Color();
}
render(renderer, writeBuffer, readBuffer) {
let oldClearAlpha;
if (this.clearColor) {
renderer.getClearColor(this._oldClearColor);
oldClearAlpha = renderer.getClearAlpha();
renderer.setClearColor(this.clearColor, this.clearAlpha);
}
renderer.setRenderTarget(this.renderToScreen ? null : readBuffer);
renderer.clear();
if (this.clearColor) {
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
}
}
}
export {
ClearPass
};
//# sourceMappingURL=ClearPass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ClearPass.js","sources":["../../src/postprocessing/ClearPass.ts"],"sourcesContent":["import { Pass } from './Pass'\nimport { Color, WebGLRenderer, WebGLRenderTarget } from 'three'\n\nclass ClearPass extends Pass {\n public clearColor: Color | string | number\n public clearAlpha: number\n\n private _oldClearColor: Color\n\n constructor(clearColor?: Color | string | number, clearAlpha?: number) {\n super()\n this.needsSwap = false\n this.clearColor = clearColor !== undefined ? clearColor : 0x000000\n this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0\n this._oldClearColor = new Color()\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n /*, deltaTime, maskActive */\n ): void {\n let oldClearAlpha\n\n if (this.clearColor) {\n renderer.getClearColor(this._oldClearColor)\n oldClearAlpha = renderer.getClearAlpha()\n renderer.setClearColor(this.clearColor, this.clearAlpha)\n }\n\n renderer.setRenderTarget(this.renderToScreen ? null : readBuffer)\n renderer.clear()\n\n if (this.clearColor) {\n renderer.setClearColor(this._oldClearColor, oldClearAlpha)\n }\n }\n}\n\nexport { ClearPass }\n"],"names":[],"mappings":";;;;;;;;AAGA,MAAM,kBAAkB,KAAK;AAAA,EAM3B,YAAY,YAAsC,YAAqB;AAC/D;AAND;AACA;AAEC;AAIN,SAAK,YAAY;AACZ,SAAA,aAAa,eAAe,SAAY,aAAa;AACrD,SAAA,aAAa,eAAe,SAAY,aAAa;AACrD,SAAA,iBAAiB,IAAI;EAC5B;AAAA,EAEO,OACL,UACA,aACA,YAEM;AACF,QAAA;AAEJ,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,cAAc;AAC1C,sBAAgB,SAAS;AACzB,eAAS,cAAc,KAAK,YAAY,KAAK,UAAU;AAAA,IACzD;AAEA,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,UAAU;AAChE,aAAS,MAAM;AAEf,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,gBAAgB,aAAa;AAAA,IAC3D;AAAA,EACF;AACF;"}
+54
View File
@@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
class CubeTexturePass extends Pass.Pass {
constructor(camera, tCube, opacity = 1) {
super();
this.camera = camera;
this.needsSwap = false;
this.cubeShader = THREE.ShaderLib["cube"];
this.cubeMesh = new THREE.Mesh(
new THREE.BoxGeometry(10, 10, 10),
new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(this.cubeShader.uniforms),
vertexShader: this.cubeShader.vertexShader,
fragmentShader: this.cubeShader.fragmentShader,
depthTest: false,
depthWrite: false,
side: THREE.BackSide
})
);
Object.defineProperty(this.cubeMesh.material, "envMap", {
get: function() {
return this.uniforms.tCube.value;
}
});
this.tCube = tCube;
this.opacity = opacity;
this.cubeScene = new THREE.Scene();
this.cubeCamera = new THREE.PerspectiveCamera();
this.cubeScene.add(this.cubeMesh);
}
render(renderer, writeBuffer, readBuffer) {
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
this.cubeCamera.projectionMatrix.copy(this.camera.projectionMatrix);
this.cubeCamera.quaternion.setFromRotationMatrix(this.camera.matrixWorld);
this.cubeMesh.material.uniforms.tCube.value = this.tCube;
this.cubeMesh.material.uniforms.tFlip.value = this.tCube.isCubeTexture && this.tCube.isRenderTargetTexture === false ? -1 : 1;
this.cubeMesh.material.uniforms.opacity.value = this.opacity;
this.cubeMesh.material.transparent = this.opacity < 1;
renderer.setRenderTarget(this.renderToScreen ? null : readBuffer);
if (this.clear)
renderer.clear();
renderer.render(this.cubeScene, this.cubeCamera);
renderer.autoClear = oldAutoClear;
}
dispose() {
this.cubeMesh.geometry.dispose();
this.cubeMesh.material.dispose();
}
}
exports.CubeTexturePass = CubeTexturePass;
//# sourceMappingURL=CubeTexturePass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"CubeTexturePass.cjs","sources":["../../src/postprocessing/CubeTexturePass.js"],"sourcesContent":["import { BackSide, BoxGeometry, Mesh, PerspectiveCamera, Scene, ShaderLib, ShaderMaterial, UniformsUtils } from 'three'\nimport { Pass } from './Pass'\n\nclass CubeTexturePass extends Pass {\n constructor(camera, tCube, opacity = 1) {\n super()\n\n this.camera = camera\n\n this.needsSwap = false\n\n this.cubeShader = ShaderLib['cube']\n this.cubeMesh = new Mesh(\n new BoxGeometry(10, 10, 10),\n new ShaderMaterial({\n uniforms: UniformsUtils.clone(this.cubeShader.uniforms),\n vertexShader: this.cubeShader.vertexShader,\n fragmentShader: this.cubeShader.fragmentShader,\n depthTest: false,\n depthWrite: false,\n side: BackSide,\n }),\n )\n\n Object.defineProperty(this.cubeMesh.material, 'envMap', {\n get: function () {\n return this.uniforms.tCube.value\n },\n })\n\n this.tCube = tCube\n this.opacity = opacity\n\n this.cubeScene = new Scene()\n this.cubeCamera = new PerspectiveCamera()\n this.cubeScene.add(this.cubeMesh)\n }\n\n render(renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/) {\n const oldAutoClear = renderer.autoClear\n renderer.autoClear = false\n\n this.cubeCamera.projectionMatrix.copy(this.camera.projectionMatrix)\n this.cubeCamera.quaternion.setFromRotationMatrix(this.camera.matrixWorld)\n\n this.cubeMesh.material.uniforms.tCube.value = this.tCube\n this.cubeMesh.material.uniforms.tFlip.value =\n this.tCube.isCubeTexture && this.tCube.isRenderTargetTexture === false ? -1 : 1\n this.cubeMesh.material.uniforms.opacity.value = this.opacity\n this.cubeMesh.material.transparent = this.opacity < 1.0\n\n renderer.setRenderTarget(this.renderToScreen ? null : readBuffer)\n if (this.clear) renderer.clear()\n renderer.render(this.cubeScene, this.cubeCamera)\n\n renderer.autoClear = oldAutoClear\n }\n\n dispose() {\n this.cubeMesh.geometry.dispose()\n this.cubeMesh.material.dispose()\n }\n}\n\nexport { CubeTexturePass }\n"],"names":["Pass","ShaderLib","Mesh","BoxGeometry","ShaderMaterial","UniformsUtils","BackSide","Scene","PerspectiveCamera"],"mappings":";;;;AAGA,MAAM,wBAAwBA,KAAAA,KAAK;AAAA,EACjC,YAAY,QAAQ,OAAO,UAAU,GAAG;AACtC,UAAO;AAEP,SAAK,SAAS;AAEd,SAAK,YAAY;AAEjB,SAAK,aAAaC,MAAS,UAAC,MAAM;AAClC,SAAK,WAAW,IAAIC,MAAI;AAAA,MACtB,IAAIC,kBAAY,IAAI,IAAI,EAAE;AAAA,MAC1B,IAAIC,qBAAe;AAAA,QACjB,UAAUC,MAAAA,cAAc,MAAM,KAAK,WAAW,QAAQ;AAAA,QACtD,cAAc,KAAK,WAAW;AAAA,QAC9B,gBAAgB,KAAK,WAAW;AAAA,QAChC,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,MAAMC,MAAQ;AAAA,MACtB,CAAO;AAAA,IACF;AAED,WAAO,eAAe,KAAK,SAAS,UAAU,UAAU;AAAA,MACtD,KAAK,WAAY;AACf,eAAO,KAAK,SAAS,MAAM;AAAA,MAC5B;AAAA,IACP,CAAK;AAED,SAAK,QAAQ;AACb,SAAK,UAAU;AAEf,SAAK,YAAY,IAAIC,YAAO;AAC5B,SAAK,aAAa,IAAIC,wBAAmB;AACzC,SAAK,UAAU,IAAI,KAAK,QAAQ;AAAA,EACjC;AAAA,EAED,OAAO,UAAU,aAAa,YAAwC;AACpE,UAAM,eAAe,SAAS;AAC9B,aAAS,YAAY;AAErB,SAAK,WAAW,iBAAiB,KAAK,KAAK,OAAO,gBAAgB;AAClE,SAAK,WAAW,WAAW,sBAAsB,KAAK,OAAO,WAAW;AAExE,SAAK,SAAS,SAAS,SAAS,MAAM,QAAQ,KAAK;AACnD,SAAK,SAAS,SAAS,SAAS,MAAM,QACpC,KAAK,MAAM,iBAAiB,KAAK,MAAM,0BAA0B,QAAQ,KAAK;AAChF,SAAK,SAAS,SAAS,SAAS,QAAQ,QAAQ,KAAK;AACrD,SAAK,SAAS,SAAS,cAAc,KAAK,UAAU;AAEpD,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,UAAU;AAChE,QAAI,KAAK;AAAO,eAAS,MAAO;AAChC,aAAS,OAAO,KAAK,WAAW,KAAK,UAAU;AAE/C,aAAS,YAAY;AAAA,EACtB;AAAA,EAED,UAAU;AACR,SAAK,SAAS,SAAS,QAAS;AAChC,SAAK,SAAS,SAAS,QAAS;AAAA,EACjC;AACH;;"}
+14
View File
@@ -0,0 +1,14 @@
import { PerspectiveCamera, CubeTexture, Mesh, Scene } from 'three'
import { Pass } from './Pass'
export class CubeTexturePass extends Pass {
constructor(camera: PerspectiveCamera, envMap?: CubeTexture, opacity?: number)
camera: PerspectiveCamera
cubeShader: object
cubeMesh: Mesh
envMap: CubeTexture
opacity: number
cubeScene: Scene
cubeCamera: PerspectiveCamera
}
+54
View File
@@ -0,0 +1,54 @@
import { ShaderLib, Mesh, BoxGeometry, ShaderMaterial, UniformsUtils, BackSide, Scene, PerspectiveCamera } from "three";
import { Pass } from "./Pass.js";
class CubeTexturePass extends Pass {
constructor(camera, tCube, opacity = 1) {
super();
this.camera = camera;
this.needsSwap = false;
this.cubeShader = ShaderLib["cube"];
this.cubeMesh = new Mesh(
new BoxGeometry(10, 10, 10),
new ShaderMaterial({
uniforms: UniformsUtils.clone(this.cubeShader.uniforms),
vertexShader: this.cubeShader.vertexShader,
fragmentShader: this.cubeShader.fragmentShader,
depthTest: false,
depthWrite: false,
side: BackSide
})
);
Object.defineProperty(this.cubeMesh.material, "envMap", {
get: function() {
return this.uniforms.tCube.value;
}
});
this.tCube = tCube;
this.opacity = opacity;
this.cubeScene = new Scene();
this.cubeCamera = new PerspectiveCamera();
this.cubeScene.add(this.cubeMesh);
}
render(renderer, writeBuffer, readBuffer) {
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
this.cubeCamera.projectionMatrix.copy(this.camera.projectionMatrix);
this.cubeCamera.quaternion.setFromRotationMatrix(this.camera.matrixWorld);
this.cubeMesh.material.uniforms.tCube.value = this.tCube;
this.cubeMesh.material.uniforms.tFlip.value = this.tCube.isCubeTexture && this.tCube.isRenderTargetTexture === false ? -1 : 1;
this.cubeMesh.material.uniforms.opacity.value = this.opacity;
this.cubeMesh.material.transparent = this.opacity < 1;
renderer.setRenderTarget(this.renderToScreen ? null : readBuffer);
if (this.clear)
renderer.clear();
renderer.render(this.cubeScene, this.cubeCamera);
renderer.autoClear = oldAutoClear;
}
dispose() {
this.cubeMesh.geometry.dispose();
this.cubeMesh.material.dispose();
}
}
export {
CubeTexturePass
};
//# sourceMappingURL=CubeTexturePass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"CubeTexturePass.js","sources":["../../src/postprocessing/CubeTexturePass.js"],"sourcesContent":["import { BackSide, BoxGeometry, Mesh, PerspectiveCamera, Scene, ShaderLib, ShaderMaterial, UniformsUtils } from 'three'\nimport { Pass } from './Pass'\n\nclass CubeTexturePass extends Pass {\n constructor(camera, tCube, opacity = 1) {\n super()\n\n this.camera = camera\n\n this.needsSwap = false\n\n this.cubeShader = ShaderLib['cube']\n this.cubeMesh = new Mesh(\n new BoxGeometry(10, 10, 10),\n new ShaderMaterial({\n uniforms: UniformsUtils.clone(this.cubeShader.uniforms),\n vertexShader: this.cubeShader.vertexShader,\n fragmentShader: this.cubeShader.fragmentShader,\n depthTest: false,\n depthWrite: false,\n side: BackSide,\n }),\n )\n\n Object.defineProperty(this.cubeMesh.material, 'envMap', {\n get: function () {\n return this.uniforms.tCube.value\n },\n })\n\n this.tCube = tCube\n this.opacity = opacity\n\n this.cubeScene = new Scene()\n this.cubeCamera = new PerspectiveCamera()\n this.cubeScene.add(this.cubeMesh)\n }\n\n render(renderer, writeBuffer, readBuffer /*, deltaTime, maskActive*/) {\n const oldAutoClear = renderer.autoClear\n renderer.autoClear = false\n\n this.cubeCamera.projectionMatrix.copy(this.camera.projectionMatrix)\n this.cubeCamera.quaternion.setFromRotationMatrix(this.camera.matrixWorld)\n\n this.cubeMesh.material.uniforms.tCube.value = this.tCube\n this.cubeMesh.material.uniforms.tFlip.value =\n this.tCube.isCubeTexture && this.tCube.isRenderTargetTexture === false ? -1 : 1\n this.cubeMesh.material.uniforms.opacity.value = this.opacity\n this.cubeMesh.material.transparent = this.opacity < 1.0\n\n renderer.setRenderTarget(this.renderToScreen ? null : readBuffer)\n if (this.clear) renderer.clear()\n renderer.render(this.cubeScene, this.cubeCamera)\n\n renderer.autoClear = oldAutoClear\n }\n\n dispose() {\n this.cubeMesh.geometry.dispose()\n this.cubeMesh.material.dispose()\n }\n}\n\nexport { CubeTexturePass }\n"],"names":[],"mappings":";;AAGA,MAAM,wBAAwB,KAAK;AAAA,EACjC,YAAY,QAAQ,OAAO,UAAU,GAAG;AACtC,UAAO;AAEP,SAAK,SAAS;AAEd,SAAK,YAAY;AAEjB,SAAK,aAAa,UAAU,MAAM;AAClC,SAAK,WAAW,IAAI;AAAA,MAClB,IAAI,YAAY,IAAI,IAAI,EAAE;AAAA,MAC1B,IAAI,eAAe;AAAA,QACjB,UAAU,cAAc,MAAM,KAAK,WAAW,QAAQ;AAAA,QACtD,cAAc,KAAK,WAAW;AAAA,QAC9B,gBAAgB,KAAK,WAAW;AAAA,QAChC,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,MAAM;AAAA,MACd,CAAO;AAAA,IACF;AAED,WAAO,eAAe,KAAK,SAAS,UAAU,UAAU;AAAA,MACtD,KAAK,WAAY;AACf,eAAO,KAAK,SAAS,MAAM;AAAA,MAC5B;AAAA,IACP,CAAK;AAED,SAAK,QAAQ;AACb,SAAK,UAAU;AAEf,SAAK,YAAY,IAAI,MAAO;AAC5B,SAAK,aAAa,IAAI,kBAAmB;AACzC,SAAK,UAAU,IAAI,KAAK,QAAQ;AAAA,EACjC;AAAA,EAED,OAAO,UAAU,aAAa,YAAwC;AACpE,UAAM,eAAe,SAAS;AAC9B,aAAS,YAAY;AAErB,SAAK,WAAW,iBAAiB,KAAK,KAAK,OAAO,gBAAgB;AAClE,SAAK,WAAW,WAAW,sBAAsB,KAAK,OAAO,WAAW;AAExE,SAAK,SAAS,SAAS,SAAS,MAAM,QAAQ,KAAK;AACnD,SAAK,SAAS,SAAS,SAAS,MAAM,QACpC,KAAK,MAAM,iBAAiB,KAAK,MAAM,0BAA0B,QAAQ,KAAK;AAChF,SAAK,SAAS,SAAS,SAAS,QAAQ,QAAQ,KAAK;AACrD,SAAK,SAAS,SAAS,cAAc,KAAK,UAAU;AAEpD,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,UAAU;AAChE,QAAI,KAAK;AAAO,eAAS,MAAO;AAChC,aAAS,OAAO,KAAK,WAAW,KAAK,UAAU;AAE/C,aAAS,YAAY;AAAA,EACtB;AAAA,EAED,UAAU;AACR,SAAK,SAAS,SAAS,QAAS;AAChC,SAAK,SAAS,SAAS,QAAS;AAAA,EACjC;AACH;"}
+50
View File
@@ -0,0 +1,50 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const DotScreenShader = require("../shaders/DotScreenShader.cjs");
class DotScreenPass extends Pass.Pass {
constructor(center, angle, scale) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "uniforms");
if (DotScreenShader.DotScreenShader === void 0)
console.error("THREE.DotScreenPass relies on THREE.DotScreenShader");
const shader = DotScreenShader.DotScreenShader;
this.uniforms = THREE.UniformsUtils.clone(shader.uniforms);
if (center !== void 0)
this.uniforms["center"].value.copy(center);
if (angle !== void 0)
this.uniforms["angle"].value = angle;
if (scale !== void 0)
this.uniforms["scale"].value = scale;
this.material = new THREE.ShaderMaterial({
uniforms: this.uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
this.fsQuad = new Pass.FullScreenQuad(this.material);
}
render(renderer, writeBuffer, readBuffer) {
this.uniforms["tDiffuse"].value = readBuffer.texture;
this.uniforms["tSize"].value.set(readBuffer.width, readBuffer.height);
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
}
exports.DotScreenPass = DotScreenPass;
//# sourceMappingURL=DotScreenPass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"DotScreenPass.cjs","sources":["../../src/postprocessing/DotScreenPass.ts"],"sourcesContent":["import { Pass, FullScreenQuad } from './Pass'\nimport { IUniform, ShaderMaterial, UniformsUtils, Vector2, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { DotScreenShader } from '../shaders/DotScreenShader'\n\nclass DotScreenPass extends Pass {\n public material: ShaderMaterial\n public fsQuad: FullScreenQuad\n\n public uniforms: Record<keyof typeof DotScreenShader['uniforms'], IUniform<any>>\n\n constructor(center?: Vector2, angle?: number, scale?: number) {\n super()\n if (DotScreenShader === undefined) console.error('THREE.DotScreenPass relies on THREE.DotScreenShader')\n const shader = DotScreenShader\n this.uniforms = UniformsUtils.clone(shader.uniforms)\n if (center !== undefined) this.uniforms['center'].value.copy(center)\n if (angle !== undefined) this.uniforms['angle'].value = angle\n if (scale !== undefined) this.uniforms['scale'].value = scale\n this.material = new ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n })\n this.fsQuad = new FullScreenQuad(this.material)\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n /*, deltaTime, maskActive */\n ): void {\n this.uniforms['tDiffuse'].value = readBuffer.texture\n this.uniforms['tSize'].value.set(readBuffer.width, readBuffer.height)\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n this.fsQuad.render(renderer)\n }\n }\n}\n\nexport { DotScreenPass }\n"],"names":["Pass","DotScreenShader","UniformsUtils","ShaderMaterial","FullScreenQuad"],"mappings":";;;;;;;;;;;AAIA,MAAM,sBAAsBA,KAAAA,KAAK;AAAA,EAM/B,YAAY,QAAkB,OAAgB,OAAgB;AACtD;AAND;AACA;AAEA;AAIL,QAAIC,gBAAAA,oBAAoB;AAAW,cAAQ,MAAM,qDAAqD;AACtG,UAAM,SAASA,gBAAAA;AACf,SAAK,WAAWC,MAAA,cAAc,MAAM,OAAO,QAAQ;AACnD,QAAI,WAAW;AAAW,WAAK,SAAS,QAAQ,EAAE,MAAM,KAAK,MAAM;AACnE,QAAI,UAAU;AAAgB,WAAA,SAAS,OAAO,EAAE,QAAQ;AACxD,QAAI,UAAU;AAAgB,WAAA,SAAS,OAAO,EAAE,QAAQ;AACnD,SAAA,WAAW,IAAIC,qBAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,cAAc,OAAO;AAAA,MACrB,gBAAgB,OAAO;AAAA,IAAA,CACxB;AACD,SAAK,SAAS,IAAIC,KAAe,eAAA,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,OACL,UACA,aACA,YAEM;AACN,SAAK,SAAS,UAAU,EAAE,QAAQ,WAAW;AACxC,SAAA,SAAS,OAAO,EAAE,MAAM,IAAI,WAAW,OAAO,WAAW,MAAM;AAEpE,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,OAAO,OAAO,QAAQ;AAAA,IAAA,OACtB;AACL,eAAS,gBAAgB,WAAW;AACpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAC1B,WAAA,OAAO,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF;AACF;;"}
+11
View File
@@ -0,0 +1,11 @@
import { Pass, FullScreenQuad } from './Pass';
import { IUniform, ShaderMaterial, Vector2, WebGLRenderer, WebGLRenderTarget } from 'three';
import { DotScreenShader } from '../shaders/DotScreenShader';
declare class DotScreenPass extends Pass {
material: ShaderMaterial;
fsQuad: FullScreenQuad;
uniforms: Record<keyof typeof DotScreenShader['uniforms'], IUniform<any>>;
constructor(center?: Vector2, angle?: number, scale?: number);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
}
export { DotScreenPass };
+50
View File
@@ -0,0 +1,50 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { UniformsUtils, ShaderMaterial } from "three";
import { DotScreenShader } from "../shaders/DotScreenShader.js";
class DotScreenPass extends Pass {
constructor(center, angle, scale) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "uniforms");
if (DotScreenShader === void 0)
console.error("THREE.DotScreenPass relies on THREE.DotScreenShader");
const shader = DotScreenShader;
this.uniforms = UniformsUtils.clone(shader.uniforms);
if (center !== void 0)
this.uniforms["center"].value.copy(center);
if (angle !== void 0)
this.uniforms["angle"].value = angle;
if (scale !== void 0)
this.uniforms["scale"].value = scale;
this.material = new ShaderMaterial({
uniforms: this.uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
this.fsQuad = new FullScreenQuad(this.material);
}
render(renderer, writeBuffer, readBuffer) {
this.uniforms["tDiffuse"].value = readBuffer.texture;
this.uniforms["tSize"].value.set(readBuffer.width, readBuffer.height);
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
}
export {
DotScreenPass
};
//# sourceMappingURL=DotScreenPass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"DotScreenPass.js","sources":["../../src/postprocessing/DotScreenPass.ts"],"sourcesContent":["import { Pass, FullScreenQuad } from './Pass'\nimport { IUniform, ShaderMaterial, UniformsUtils, Vector2, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { DotScreenShader } from '../shaders/DotScreenShader'\n\nclass DotScreenPass extends Pass {\n public material: ShaderMaterial\n public fsQuad: FullScreenQuad\n\n public uniforms: Record<keyof typeof DotScreenShader['uniforms'], IUniform<any>>\n\n constructor(center?: Vector2, angle?: number, scale?: number) {\n super()\n if (DotScreenShader === undefined) console.error('THREE.DotScreenPass relies on THREE.DotScreenShader')\n const shader = DotScreenShader\n this.uniforms = UniformsUtils.clone(shader.uniforms)\n if (center !== undefined) this.uniforms['center'].value.copy(center)\n if (angle !== undefined) this.uniforms['angle'].value = angle\n if (scale !== undefined) this.uniforms['scale'].value = scale\n this.material = new ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n })\n this.fsQuad = new FullScreenQuad(this.material)\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n /*, deltaTime, maskActive */\n ): void {\n this.uniforms['tDiffuse'].value = readBuffer.texture\n this.uniforms['tSize'].value.set(readBuffer.width, readBuffer.height)\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n this.fsQuad.render(renderer)\n }\n }\n}\n\nexport { DotScreenPass }\n"],"names":[],"mappings":";;;;;;;;;AAIA,MAAM,sBAAsB,KAAK;AAAA,EAM/B,YAAY,QAAkB,OAAgB,OAAgB;AACtD;AAND;AACA;AAEA;AAIL,QAAI,oBAAoB;AAAW,cAAQ,MAAM,qDAAqD;AACtG,UAAM,SAAS;AACf,SAAK,WAAW,cAAc,MAAM,OAAO,QAAQ;AACnD,QAAI,WAAW;AAAW,WAAK,SAAS,QAAQ,EAAE,MAAM,KAAK,MAAM;AACnE,QAAI,UAAU;AAAgB,WAAA,SAAS,OAAO,EAAE,QAAQ;AACxD,QAAI,UAAU;AAAgB,WAAA,SAAS,OAAO,EAAE,QAAQ;AACnD,SAAA,WAAW,IAAI,eAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,cAAc,OAAO;AAAA,MACrB,gBAAgB,OAAO;AAAA,IAAA,CACxB;AACD,SAAK,SAAS,IAAI,eAAe,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,OACL,UACA,aACA,YAEM;AACN,SAAK,SAAS,UAAU,EAAE,QAAQ,WAAW;AACxC,SAAA,SAAS,OAAO,EAAE,MAAM,IAAI,WAAW,OAAO,WAAW,MAAM;AAEpE,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,OAAO,OAAO,QAAQ;AAAA,IAAA,OACtB;AACL,eAAS,gBAAgB,WAAW;AACpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAC1B,WAAA,OAAO,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF;AACF;"}
+163
View File
@@ -0,0 +1,163 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const CopyShader = require("../shaders/CopyShader.cjs");
const ShaderPass = require("./ShaderPass.cjs");
const MaskPass = require("./MaskPass.cjs");
class EffectComposer {
constructor(renderer, renderTarget) {
__publicField(this, "renderer");
__publicField(this, "_pixelRatio");
__publicField(this, "_width");
__publicField(this, "_height");
__publicField(this, "renderTarget1");
__publicField(this, "renderTarget2");
__publicField(this, "writeBuffer");
__publicField(this, "readBuffer");
__publicField(this, "renderToScreen");
__publicField(this, "passes", []);
__publicField(this, "copyPass");
__publicField(this, "clock");
this.renderer = renderer;
if (renderTarget === void 0) {
const parameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBAFormat
};
const size = renderer.getSize(new THREE.Vector2());
this._pixelRatio = renderer.getPixelRatio();
this._width = size.width;
this._height = size.height;
renderTarget = new THREE.WebGLRenderTarget(
this._width * this._pixelRatio,
this._height * this._pixelRatio,
parameters
);
renderTarget.texture.name = "EffectComposer.rt1";
} else {
this._pixelRatio = 1;
this._width = renderTarget.width;
this._height = renderTarget.height;
}
this.renderTarget1 = renderTarget;
this.renderTarget2 = renderTarget.clone();
this.renderTarget2.texture.name = "EffectComposer.rt2";
this.writeBuffer = this.renderTarget1;
this.readBuffer = this.renderTarget2;
this.renderToScreen = true;
if (CopyShader.CopyShader === void 0) {
console.error("THREE.EffectComposer relies on CopyShader");
}
if (ShaderPass.ShaderPass === void 0) {
console.error("THREE.EffectComposer relies on ShaderPass");
}
this.copyPass = new ShaderPass.ShaderPass(CopyShader.CopyShader);
this.copyPass.material.blending = THREE.NoBlending;
this.clock = new THREE.Clock();
}
swapBuffers() {
const tmp = this.readBuffer;
this.readBuffer = this.writeBuffer;
this.writeBuffer = tmp;
}
addPass(pass) {
this.passes.push(pass);
pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
}
insertPass(pass, index) {
this.passes.splice(index, 0, pass);
pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
}
removePass(pass) {
const index = this.passes.indexOf(pass);
if (index !== -1) {
this.passes.splice(index, 1);
}
}
isLastEnabledPass(passIndex) {
for (let i = passIndex + 1; i < this.passes.length; i++) {
if (this.passes[i].enabled) {
return false;
}
}
return true;
}
render(deltaTime) {
if (deltaTime === void 0) {
deltaTime = this.clock.getDelta();
}
const currentRenderTarget = this.renderer.getRenderTarget();
let maskActive = false;
const il = this.passes.length;
for (let i = 0; i < il; i++) {
const pass = this.passes[i];
if (pass.enabled === false)
continue;
pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass(i);
pass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive);
if (pass.needsSwap) {
if (maskActive) {
const context = this.renderer.getContext();
const stencil = this.renderer.state.buffers.stencil;
stencil.setFunc(context.NOTEQUAL, 1, 4294967295);
this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime);
stencil.setFunc(context.EQUAL, 1, 4294967295);
}
this.swapBuffers();
}
if (MaskPass.MaskPass !== void 0) {
if (pass instanceof MaskPass.MaskPass) {
maskActive = true;
} else if (pass instanceof MaskPass.ClearMaskPass) {
maskActive = false;
}
}
}
this.renderer.setRenderTarget(currentRenderTarget);
}
reset(renderTarget) {
if (renderTarget === void 0) {
const size = this.renderer.getSize(new THREE.Vector2());
this._pixelRatio = this.renderer.getPixelRatio();
this._width = size.width;
this._height = size.height;
renderTarget = this.renderTarget1.clone();
renderTarget.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
}
this.renderTarget1.dispose();
this.renderTarget2.dispose();
this.renderTarget1 = renderTarget;
this.renderTarget2 = renderTarget.clone();
this.writeBuffer = this.renderTarget1;
this.readBuffer = this.renderTarget2;
}
setSize(width, height) {
this._width = width;
this._height = height;
const effectiveWidth = this._width * this._pixelRatio;
const effectiveHeight = this._height * this._pixelRatio;
this.renderTarget1.setSize(effectiveWidth, effectiveHeight);
this.renderTarget2.setSize(effectiveWidth, effectiveHeight);
for (let i = 0; i < this.passes.length; i++) {
this.passes[i].setSize(effectiveWidth, effectiveHeight);
}
}
setPixelRatio(pixelRatio) {
this._pixelRatio = pixelRatio;
this.setSize(this._width, this._height);
}
dispose() {
this.renderTarget1.dispose();
this.renderTarget2.dispose();
this.copyPass.dispose();
}
}
exports.EffectComposer = EffectComposer;
//# sourceMappingURL=EffectComposer.cjs.map
File diff suppressed because one or more lines are too long
+28
View File
@@ -0,0 +1,28 @@
import { Clock, WebGLRenderer, WebGLRenderTarget } from 'three';
import { Pass } from './Pass';
declare class EffectComposer<TRenderTarget extends WebGLRenderTarget = WebGLRenderTarget> {
renderer: WebGLRenderer;
private _pixelRatio;
private _width;
private _height;
renderTarget1: WebGLRenderTarget;
renderTarget2: WebGLRenderTarget;
writeBuffer: WebGLRenderTarget;
readBuffer: WebGLRenderTarget;
renderToScreen: boolean;
passes: Pass[];
copyPass: Pass;
clock: Clock;
constructor(renderer: WebGLRenderer, renderTarget?: TRenderTarget);
swapBuffers(): void;
addPass(pass: Pass): void;
insertPass(pass: Pass, index: number): void;
removePass(pass: Pass): void;
isLastEnabledPass(passIndex: number): boolean;
render(deltaTime?: number): void;
reset(renderTarget: WebGLRenderTarget): void;
setSize(width: number, height: number): void;
setPixelRatio(pixelRatio: number): void;
dispose(): void;
}
export { EffectComposer };
+163
View File
@@ -0,0 +1,163 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Vector2, WebGLRenderTarget, NoBlending, Clock, LinearFilter, RGBAFormat } from "three";
import { CopyShader } from "../shaders/CopyShader.js";
import { ShaderPass } from "./ShaderPass.js";
import { MaskPass, ClearMaskPass } from "./MaskPass.js";
class EffectComposer {
constructor(renderer, renderTarget) {
__publicField(this, "renderer");
__publicField(this, "_pixelRatio");
__publicField(this, "_width");
__publicField(this, "_height");
__publicField(this, "renderTarget1");
__publicField(this, "renderTarget2");
__publicField(this, "writeBuffer");
__publicField(this, "readBuffer");
__publicField(this, "renderToScreen");
__publicField(this, "passes", []);
__publicField(this, "copyPass");
__publicField(this, "clock");
this.renderer = renderer;
if (renderTarget === void 0) {
const parameters = {
minFilter: LinearFilter,
magFilter: LinearFilter,
format: RGBAFormat
};
const size = renderer.getSize(new Vector2());
this._pixelRatio = renderer.getPixelRatio();
this._width = size.width;
this._height = size.height;
renderTarget = new WebGLRenderTarget(
this._width * this._pixelRatio,
this._height * this._pixelRatio,
parameters
);
renderTarget.texture.name = "EffectComposer.rt1";
} else {
this._pixelRatio = 1;
this._width = renderTarget.width;
this._height = renderTarget.height;
}
this.renderTarget1 = renderTarget;
this.renderTarget2 = renderTarget.clone();
this.renderTarget2.texture.name = "EffectComposer.rt2";
this.writeBuffer = this.renderTarget1;
this.readBuffer = this.renderTarget2;
this.renderToScreen = true;
if (CopyShader === void 0) {
console.error("THREE.EffectComposer relies on CopyShader");
}
if (ShaderPass === void 0) {
console.error("THREE.EffectComposer relies on ShaderPass");
}
this.copyPass = new ShaderPass(CopyShader);
this.copyPass.material.blending = NoBlending;
this.clock = new Clock();
}
swapBuffers() {
const tmp = this.readBuffer;
this.readBuffer = this.writeBuffer;
this.writeBuffer = tmp;
}
addPass(pass) {
this.passes.push(pass);
pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
}
insertPass(pass, index) {
this.passes.splice(index, 0, pass);
pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
}
removePass(pass) {
const index = this.passes.indexOf(pass);
if (index !== -1) {
this.passes.splice(index, 1);
}
}
isLastEnabledPass(passIndex) {
for (let i = passIndex + 1; i < this.passes.length; i++) {
if (this.passes[i].enabled) {
return false;
}
}
return true;
}
render(deltaTime) {
if (deltaTime === void 0) {
deltaTime = this.clock.getDelta();
}
const currentRenderTarget = this.renderer.getRenderTarget();
let maskActive = false;
const il = this.passes.length;
for (let i = 0; i < il; i++) {
const pass = this.passes[i];
if (pass.enabled === false)
continue;
pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass(i);
pass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive);
if (pass.needsSwap) {
if (maskActive) {
const context = this.renderer.getContext();
const stencil = this.renderer.state.buffers.stencil;
stencil.setFunc(context.NOTEQUAL, 1, 4294967295);
this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime);
stencil.setFunc(context.EQUAL, 1, 4294967295);
}
this.swapBuffers();
}
if (MaskPass !== void 0) {
if (pass instanceof MaskPass) {
maskActive = true;
} else if (pass instanceof ClearMaskPass) {
maskActive = false;
}
}
}
this.renderer.setRenderTarget(currentRenderTarget);
}
reset(renderTarget) {
if (renderTarget === void 0) {
const size = this.renderer.getSize(new Vector2());
this._pixelRatio = this.renderer.getPixelRatio();
this._width = size.width;
this._height = size.height;
renderTarget = this.renderTarget1.clone();
renderTarget.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio);
}
this.renderTarget1.dispose();
this.renderTarget2.dispose();
this.renderTarget1 = renderTarget;
this.renderTarget2 = renderTarget.clone();
this.writeBuffer = this.renderTarget1;
this.readBuffer = this.renderTarget2;
}
setSize(width, height) {
this._width = width;
this._height = height;
const effectiveWidth = this._width * this._pixelRatio;
const effectiveHeight = this._height * this._pixelRatio;
this.renderTarget1.setSize(effectiveWidth, effectiveHeight);
this.renderTarget2.setSize(effectiveWidth, effectiveHeight);
for (let i = 0; i < this.passes.length; i++) {
this.passes[i].setSize(effectiveWidth, effectiveHeight);
}
}
setPixelRatio(pixelRatio) {
this._pixelRatio = pixelRatio;
this.setSize(this._width, this._height);
}
dispose() {
this.renderTarget1.dispose();
this.renderTarget2.dispose();
this.copyPass.dispose();
}
}
export {
EffectComposer
};
//# sourceMappingURL=EffectComposer.js.map
File diff suppressed because one or more lines are too long
+52
View File
@@ -0,0 +1,52 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const FilmShader = require("../shaders/FilmShader.cjs");
class FilmPass extends Pass.Pass {
constructor(noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "uniforms");
if (FilmShader.FilmShader === void 0)
console.error("THREE.FilmPass relies on FilmShader");
const shader = FilmShader.FilmShader;
this.uniforms = THREE.UniformsUtils.clone(shader.uniforms);
this.material = new THREE.ShaderMaterial({
uniforms: this.uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
if (grayscale !== void 0)
this.uniforms.grayscale.value = grayscale;
if (noiseIntensity !== void 0)
this.uniforms.nIntensity.value = noiseIntensity;
if (scanlinesIntensity !== void 0)
this.uniforms.sIntensity.value = scanlinesIntensity;
if (scanlinesCount !== void 0)
this.uniforms.sCount.value = scanlinesCount;
this.fsQuad = new Pass.FullScreenQuad(this.material);
}
render(renderer, writeBuffer, readBuffer, deltaTime) {
this.uniforms["tDiffuse"].value = readBuffer.texture;
this.uniforms["time"].value += deltaTime;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
}
exports.FilmPass = FilmPass;
//# sourceMappingURL=FilmPass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"FilmPass.cjs","sources":["../../src/postprocessing/FilmPass.ts"],"sourcesContent":["import { Pass, FullScreenQuad } from './Pass'\nimport { IUniform, ShaderMaterial, UniformsUtils, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { FilmShader } from '../shaders/FilmShader'\n\nclass FilmPass extends Pass {\n public material: ShaderMaterial\n public fsQuad: FullScreenQuad\n\n public uniforms: Record<keyof typeof FilmShader['uniforms'], IUniform<any>>\n\n constructor(noiseIntensity?: number, scanlinesIntensity?: number, scanlinesCount?: number, grayscale?: boolean) {\n super()\n\n if (FilmShader === undefined) console.error('THREE.FilmPass relies on FilmShader')\n\n const shader = FilmShader\n\n this.uniforms = UniformsUtils.clone(shader.uniforms)\n\n this.material = new ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n })\n\n if (grayscale !== undefined) this.uniforms.grayscale.value = grayscale\n if (noiseIntensity !== undefined) this.uniforms.nIntensity.value = noiseIntensity\n if (scanlinesIntensity !== undefined) this.uniforms.sIntensity.value = scanlinesIntensity\n if (scanlinesCount !== undefined) this.uniforms.sCount.value = scanlinesCount\n\n this.fsQuad = new FullScreenQuad(this.material)\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n deltaTime: number,\n ): void {\n this.uniforms['tDiffuse'].value = readBuffer.texture\n this.uniforms['time'].value += deltaTime\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n this.fsQuad.render(renderer)\n }\n }\n}\n\nexport { FilmPass }\n"],"names":["Pass","FilmShader","UniformsUtils","ShaderMaterial","FullScreenQuad"],"mappings":";;;;;;;;;;;AAIA,MAAM,iBAAiBA,KAAAA,KAAK;AAAA,EAM1B,YAAY,gBAAyB,oBAA6B,gBAAyB,WAAqB;AACxG;AAND;AACA;AAEA;AAKL,QAAIC,WAAAA,eAAe;AAAW,cAAQ,MAAM,qCAAqC;AAEjF,UAAM,SAASA,WAAAA;AAEf,SAAK,WAAWC,MAAA,cAAc,MAAM,OAAO,QAAQ;AAE9C,SAAA,WAAW,IAAIC,qBAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,cAAc,OAAO;AAAA,MACrB,gBAAgB,OAAO;AAAA,IAAA,CACxB;AAED,QAAI,cAAc;AAAgB,WAAA,SAAS,UAAU,QAAQ;AAC7D,QAAI,mBAAmB;AAAgB,WAAA,SAAS,WAAW,QAAQ;AACnE,QAAI,uBAAuB;AAAgB,WAAA,SAAS,WAAW,QAAQ;AACvE,QAAI,mBAAmB;AAAgB,WAAA,SAAS,OAAO,QAAQ;AAE/D,SAAK,SAAS,IAAIC,KAAe,eAAA,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,OACL,UACA,aACA,YACA,WACM;AACN,SAAK,SAAS,UAAU,EAAE,QAAQ,WAAW;AACxC,SAAA,SAAS,MAAM,EAAE,SAAS;AAE/B,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,OAAO,OAAO,QAAQ;AAAA,IAAA,OACtB;AACL,eAAS,gBAAgB,WAAW;AACpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAC1B,WAAA,OAAO,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF;AACF;;"}
+11
View File
@@ -0,0 +1,11 @@
import { Pass, FullScreenQuad } from './Pass';
import { IUniform, ShaderMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
import { FilmShader } from '../shaders/FilmShader';
declare class FilmPass extends Pass {
material: ShaderMaterial;
fsQuad: FullScreenQuad;
uniforms: Record<keyof typeof FilmShader['uniforms'], IUniform<any>>;
constructor(noiseIntensity?: number, scanlinesIntensity?: number, scanlinesCount?: number, grayscale?: boolean);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number): void;
}
export { FilmPass };
+52
View File
@@ -0,0 +1,52 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { UniformsUtils, ShaderMaterial } from "three";
import { FilmShader } from "../shaders/FilmShader.js";
class FilmPass extends Pass {
constructor(noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "uniforms");
if (FilmShader === void 0)
console.error("THREE.FilmPass relies on FilmShader");
const shader = FilmShader;
this.uniforms = UniformsUtils.clone(shader.uniforms);
this.material = new ShaderMaterial({
uniforms: this.uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
if (grayscale !== void 0)
this.uniforms.grayscale.value = grayscale;
if (noiseIntensity !== void 0)
this.uniforms.nIntensity.value = noiseIntensity;
if (scanlinesIntensity !== void 0)
this.uniforms.sIntensity.value = scanlinesIntensity;
if (scanlinesCount !== void 0)
this.uniforms.sCount.value = scanlinesCount;
this.fsQuad = new FullScreenQuad(this.material);
}
render(renderer, writeBuffer, readBuffer, deltaTime) {
this.uniforms["tDiffuse"].value = readBuffer.texture;
this.uniforms["time"].value += deltaTime;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
}
export {
FilmPass
};
//# sourceMappingURL=FilmPass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"FilmPass.js","sources":["../../src/postprocessing/FilmPass.ts"],"sourcesContent":["import { Pass, FullScreenQuad } from './Pass'\nimport { IUniform, ShaderMaterial, UniformsUtils, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { FilmShader } from '../shaders/FilmShader'\n\nclass FilmPass extends Pass {\n public material: ShaderMaterial\n public fsQuad: FullScreenQuad\n\n public uniforms: Record<keyof typeof FilmShader['uniforms'], IUniform<any>>\n\n constructor(noiseIntensity?: number, scanlinesIntensity?: number, scanlinesCount?: number, grayscale?: boolean) {\n super()\n\n if (FilmShader === undefined) console.error('THREE.FilmPass relies on FilmShader')\n\n const shader = FilmShader\n\n this.uniforms = UniformsUtils.clone(shader.uniforms)\n\n this.material = new ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: shader.vertexShader,\n fragmentShader: shader.fragmentShader,\n })\n\n if (grayscale !== undefined) this.uniforms.grayscale.value = grayscale\n if (noiseIntensity !== undefined) this.uniforms.nIntensity.value = noiseIntensity\n if (scanlinesIntensity !== undefined) this.uniforms.sIntensity.value = scanlinesIntensity\n if (scanlinesCount !== undefined) this.uniforms.sCount.value = scanlinesCount\n\n this.fsQuad = new FullScreenQuad(this.material)\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n deltaTime: number,\n ): void {\n this.uniforms['tDiffuse'].value = readBuffer.texture\n this.uniforms['time'].value += deltaTime\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n this.fsQuad.render(renderer)\n }\n }\n}\n\nexport { FilmPass }\n"],"names":[],"mappings":";;;;;;;;;AAIA,MAAM,iBAAiB,KAAK;AAAA,EAM1B,YAAY,gBAAyB,oBAA6B,gBAAyB,WAAqB;AACxG;AAND;AACA;AAEA;AAKL,QAAI,eAAe;AAAW,cAAQ,MAAM,qCAAqC;AAEjF,UAAM,SAAS;AAEf,SAAK,WAAW,cAAc,MAAM,OAAO,QAAQ;AAE9C,SAAA,WAAW,IAAI,eAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,cAAc,OAAO;AAAA,MACrB,gBAAgB,OAAO;AAAA,IAAA,CACxB;AAED,QAAI,cAAc;AAAgB,WAAA,SAAS,UAAU,QAAQ;AAC7D,QAAI,mBAAmB;AAAgB,WAAA,SAAS,WAAW,QAAQ;AACnE,QAAI,uBAAuB;AAAgB,WAAA,SAAS,WAAW,QAAQ;AACvE,QAAI,mBAAmB;AAAgB,WAAA,SAAS,OAAO,QAAQ;AAE/D,SAAK,SAAS,IAAI,eAAe,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,OACL,UACA,aACA,YACA,WACM;AACN,SAAK,SAAS,UAAU,EAAE,QAAQ,WAAW;AACxC,SAAA,SAAS,MAAM,EAAE,SAAS;AAE/B,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,OAAO,OAAO,QAAQ;AAAA,IAAA,OACtB;AACL,eAAS,gBAAgB,WAAW;AACpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAC1B,WAAA,OAAO,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF;AACF;"}
+83
View File
@@ -0,0 +1,83 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const DigitalGlitch = require("../shaders/DigitalGlitch.cjs");
class GlitchPass extends Pass.Pass {
constructor(dt_size = 64) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "goWild");
__publicField(this, "curF");
__publicField(this, "randX");
__publicField(this, "uniforms");
this.uniforms = THREE.UniformsUtils.clone(DigitalGlitch.DigitalGlitch.uniforms);
this.uniforms["tDisp"].value = this.generateHeightmap(dt_size);
this.material = new THREE.ShaderMaterial({
uniforms: this.uniforms,
vertexShader: DigitalGlitch.DigitalGlitch.vertexShader,
fragmentShader: DigitalGlitch.DigitalGlitch.fragmentShader
});
this.fsQuad = new Pass.FullScreenQuad(this.material);
this.goWild = false;
this.curF = 0;
this.generateTrigger();
}
render(renderer, writeBuffer, readBuffer) {
this.uniforms["tDiffuse"].value = readBuffer.texture;
this.uniforms["seed"].value = Math.random();
this.uniforms["byp"].value = 0;
if (this.curF % this.randX == 0 || this.goWild == true) {
this.uniforms["amount"].value = Math.random() / 30;
this.uniforms["angle"].value = THREE.MathUtils.randFloat(-Math.PI, Math.PI);
this.uniforms["seed_x"].value = THREE.MathUtils.randFloat(-1, 1);
this.uniforms["seed_y"].value = THREE.MathUtils.randFloat(-1, 1);
this.uniforms["distortion_x"].value = THREE.MathUtils.randFloat(0, 1);
this.uniforms["distortion_y"].value = THREE.MathUtils.randFloat(0, 1);
this.curF = 0;
this.generateTrigger();
} else if (this.curF % this.randX < this.randX / 5) {
this.uniforms["amount"].value = Math.random() / 90;
this.uniforms["angle"].value = THREE.MathUtils.randFloat(-Math.PI, Math.PI);
this.uniforms["distortion_x"].value = THREE.MathUtils.randFloat(0, 1);
this.uniforms["distortion_y"].value = THREE.MathUtils.randFloat(0, 1);
this.uniforms["seed_x"].value = THREE.MathUtils.randFloat(-0.3, 0.3);
this.uniforms["seed_y"].value = THREE.MathUtils.randFloat(-0.3, 0.3);
} else if (this.goWild == false) {
this.uniforms["byp"].value = 1;
}
this.curF++;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
generateTrigger() {
this.randX = THREE.MathUtils.randInt(120, 240);
}
generateHeightmap(dt_size) {
const data_arr = new Float32Array(dt_size * dt_size);
const length = dt_size * dt_size;
for (let i = 0; i < length; i++) {
const val = THREE.MathUtils.randFloat(0, 1);
data_arr[i] = val;
}
const texture = new THREE.DataTexture(data_arr, dt_size, dt_size, THREE.RedFormat, THREE.FloatType);
texture.needsUpdate = true;
return texture;
}
}
exports.GlitchPass = GlitchPass;
//# sourceMappingURL=GlitchPass.cjs.map
File diff suppressed because one or more lines are too long
+16
View File
@@ -0,0 +1,16 @@
import { Pass, FullScreenQuad } from './Pass';
import { DataTexture, ShaderMaterial, WebGLRenderTarget, WebGLRenderer, IUniform } from 'three';
import { DigitalGlitch } from '../shaders/DigitalGlitch';
declare class GlitchPass extends Pass {
material: ShaderMaterial;
fsQuad: FullScreenQuad;
goWild: boolean;
curF: number;
randX: number;
uniforms: Record<keyof typeof DigitalGlitch['uniforms'], IUniform<any>>;
constructor(dt_size?: number);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
generateTrigger(): void;
generateHeightmap(dt_size: number): DataTexture;
}
export { GlitchPass };
+83
View File
@@ -0,0 +1,83 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { UniformsUtils, ShaderMaterial, MathUtils, DataTexture, RedFormat, FloatType } from "three";
import { DigitalGlitch } from "../shaders/DigitalGlitch.js";
class GlitchPass extends Pass {
constructor(dt_size = 64) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "goWild");
__publicField(this, "curF");
__publicField(this, "randX");
__publicField(this, "uniforms");
this.uniforms = UniformsUtils.clone(DigitalGlitch.uniforms);
this.uniforms["tDisp"].value = this.generateHeightmap(dt_size);
this.material = new ShaderMaterial({
uniforms: this.uniforms,
vertexShader: DigitalGlitch.vertexShader,
fragmentShader: DigitalGlitch.fragmentShader
});
this.fsQuad = new FullScreenQuad(this.material);
this.goWild = false;
this.curF = 0;
this.generateTrigger();
}
render(renderer, writeBuffer, readBuffer) {
this.uniforms["tDiffuse"].value = readBuffer.texture;
this.uniforms["seed"].value = Math.random();
this.uniforms["byp"].value = 0;
if (this.curF % this.randX == 0 || this.goWild == true) {
this.uniforms["amount"].value = Math.random() / 30;
this.uniforms["angle"].value = MathUtils.randFloat(-Math.PI, Math.PI);
this.uniforms["seed_x"].value = MathUtils.randFloat(-1, 1);
this.uniforms["seed_y"].value = MathUtils.randFloat(-1, 1);
this.uniforms["distortion_x"].value = MathUtils.randFloat(0, 1);
this.uniforms["distortion_y"].value = MathUtils.randFloat(0, 1);
this.curF = 0;
this.generateTrigger();
} else if (this.curF % this.randX < this.randX / 5) {
this.uniforms["amount"].value = Math.random() / 90;
this.uniforms["angle"].value = MathUtils.randFloat(-Math.PI, Math.PI);
this.uniforms["distortion_x"].value = MathUtils.randFloat(0, 1);
this.uniforms["distortion_y"].value = MathUtils.randFloat(0, 1);
this.uniforms["seed_x"].value = MathUtils.randFloat(-0.3, 0.3);
this.uniforms["seed_y"].value = MathUtils.randFloat(-0.3, 0.3);
} else if (this.goWild == false) {
this.uniforms["byp"].value = 1;
}
this.curF++;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
generateTrigger() {
this.randX = MathUtils.randInt(120, 240);
}
generateHeightmap(dt_size) {
const data_arr = new Float32Array(dt_size * dt_size);
const length = dt_size * dt_size;
for (let i = 0; i < length; i++) {
const val = MathUtils.randFloat(0, 1);
data_arr[i] = val;
}
const texture = new DataTexture(data_arr, dt_size, dt_size, RedFormat, FloatType);
texture.needsUpdate = true;
return texture;
}
}
export {
GlitchPass
};
//# sourceMappingURL=GlitchPass.js.map
File diff suppressed because one or more lines are too long
+54
View File
@@ -0,0 +1,54 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const HalftoneShader = require("../shaders/HalftoneShader.cjs");
class HalftonePass extends Pass.Pass {
constructor(width, height, params) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "uniforms");
if (HalftoneShader.HalftoneShader === void 0) {
console.error("THREE.HalftonePass requires HalftoneShader");
}
this.uniforms = THREE.UniformsUtils.clone(HalftoneShader.HalftoneShader.uniforms);
this.material = new THREE.ShaderMaterial({
uniforms: this.uniforms,
fragmentShader: HalftoneShader.HalftoneShader.fragmentShader,
vertexShader: HalftoneShader.HalftoneShader.vertexShader
});
this.uniforms.width.value = width;
this.uniforms.height.value = height;
for (const key in params) {
if (params.hasOwnProperty(key) && this.uniforms.hasOwnProperty(key)) {
this.uniforms[key].value = params[key];
}
}
this.fsQuad = new Pass.FullScreenQuad(this.material);
}
render(renderer, writeBuffer, readBuffer) {
this.material.uniforms["tDiffuse"].value = readBuffer.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
setSize(width, height) {
this.uniforms.width.value = width;
this.uniforms.height.value = height;
}
}
exports.HalftonePass = HalftonePass;
//# sourceMappingURL=HalftonePass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"HalftonePass.cjs","sources":["../../src/postprocessing/HalftonePass.ts"],"sourcesContent":["import { Pass, FullScreenQuad } from './Pass'\nimport { ShaderMaterial, UniformsUtils, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { HalftoneShader } from '../shaders/HalftoneShader'\n\ntype HalftonePassParams = {\n shape?: number\n radius?: number\n rotateR?: number\n rotateB?: number\n rotateG?: number\n scatter?: number\n blending?: number\n blendingMode?: number\n greyscale?: number\n disable?: number\n}\n\n/**\n * RGB Halftone pass for three.js effects composer. Requires HalftoneShader.\n */\n\nclass HalftonePass extends Pass {\n public material: ShaderMaterial\n public fsQuad: FullScreenQuad\n\n public uniforms: any\n\n constructor(width: number, height: number, params: HalftonePassParams) {\n super()\n\n if (HalftoneShader === undefined) {\n console.error('THREE.HalftonePass requires HalftoneShader')\n }\n\n this.uniforms = UniformsUtils.clone(HalftoneShader.uniforms)\n this.material = new ShaderMaterial({\n uniforms: this.uniforms,\n fragmentShader: HalftoneShader.fragmentShader,\n vertexShader: HalftoneShader.vertexShader,\n })\n\n // set params\n this.uniforms.width.value = width\n this.uniforms.height.value = height\n\n for (const key in params) {\n if (params.hasOwnProperty(key) && this.uniforms.hasOwnProperty(key)) {\n this.uniforms[key].value = params[key as keyof HalftonePassParams]\n }\n }\n\n this.fsQuad = new FullScreenQuad(this.material)\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n /*, deltaTime, maskActive */\n ): void {\n this.material.uniforms['tDiffuse'].value = readBuffer.texture\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n this.fsQuad.render(renderer)\n }\n }\n\n public setSize(width: number, height: number): void {\n this.uniforms.width.value = width\n this.uniforms.height.value = height\n }\n}\n\nexport { HalftonePass }\n"],"names":["Pass","HalftoneShader","UniformsUtils","ShaderMaterial","FullScreenQuad"],"mappings":";;;;;;;;;;;AAqBA,MAAM,qBAAqBA,KAAAA,KAAK;AAAA,EAM9B,YAAY,OAAe,QAAgB,QAA4B;AAC/D;AAND;AACA;AAEA;AAKL,QAAIC,eAAAA,mBAAmB,QAAW;AAChC,cAAQ,MAAM,4CAA4C;AAAA,IAC5D;AAEA,SAAK,WAAWC,MAAA,cAAc,MAAMD,eAAA,eAAe,QAAQ;AACtD,SAAA,WAAW,IAAIE,qBAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,gBAAgBF,eAAe,eAAA;AAAA,MAC/B,cAAcA,eAAe,eAAA;AAAA,IAAA,CAC9B;AAGI,SAAA,SAAS,MAAM,QAAQ;AACvB,SAAA,SAAS,OAAO,QAAQ;AAE7B,eAAW,OAAO,QAAQ;AACpB,UAAA,OAAO,eAAe,GAAG,KAAK,KAAK,SAAS,eAAe,GAAG,GAAG;AACnE,aAAK,SAAS,GAAG,EAAE,QAAQ,OAAO,GAA+B;AAAA,MACnE;AAAA,IACF;AAEA,SAAK,SAAS,IAAIG,KAAe,eAAA,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,OACL,UACA,aACA,YAEM;AACN,SAAK,SAAS,SAAS,UAAU,EAAE,QAAQ,WAAW;AAEtD,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,OAAO,OAAO,QAAQ;AAAA,IAAA,OACtB;AACL,eAAS,gBAAgB,WAAW;AACpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAC1B,WAAA,OAAO,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA,EAEO,QAAQ,OAAe,QAAsB;AAC7C,SAAA,SAAS,MAAM,QAAQ;AACvB,SAAA,SAAS,OAAO,QAAQ;AAAA,EAC/B;AACF;;"}
+26
View File
@@ -0,0 +1,26 @@
import { Pass, FullScreenQuad } from './Pass';
import { ShaderMaterial, WebGLRenderer, WebGLRenderTarget } from 'three';
type HalftonePassParams = {
shape?: number;
radius?: number;
rotateR?: number;
rotateB?: number;
rotateG?: number;
scatter?: number;
blending?: number;
blendingMode?: number;
greyscale?: number;
disable?: number;
};
/**
* RGB Halftone pass for three.js effects composer. Requires HalftoneShader.
*/
declare class HalftonePass extends Pass {
material: ShaderMaterial;
fsQuad: FullScreenQuad;
uniforms: any;
constructor(width: number, height: number, params: HalftonePassParams);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
setSize(width: number, height: number): void;
}
export { HalftonePass };
+54
View File
@@ -0,0 +1,54 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { UniformsUtils, ShaderMaterial } from "three";
import { HalftoneShader } from "../shaders/HalftoneShader.js";
class HalftonePass extends Pass {
constructor(width, height, params) {
super();
__publicField(this, "material");
__publicField(this, "fsQuad");
__publicField(this, "uniforms");
if (HalftoneShader === void 0) {
console.error("THREE.HalftonePass requires HalftoneShader");
}
this.uniforms = UniformsUtils.clone(HalftoneShader.uniforms);
this.material = new ShaderMaterial({
uniforms: this.uniforms,
fragmentShader: HalftoneShader.fragmentShader,
vertexShader: HalftoneShader.vertexShader
});
this.uniforms.width.value = width;
this.uniforms.height.value = height;
for (const key in params) {
if (params.hasOwnProperty(key) && this.uniforms.hasOwnProperty(key)) {
this.uniforms[key].value = params[key];
}
}
this.fsQuad = new FullScreenQuad(this.material);
}
render(renderer, writeBuffer, readBuffer) {
this.material.uniforms["tDiffuse"].value = readBuffer.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
this.fsQuad.render(renderer);
}
}
setSize(width, height) {
this.uniforms.width.value = width;
this.uniforms.height.value = height;
}
}
export {
HalftonePass
};
//# sourceMappingURL=HalftonePass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"HalftonePass.js","sources":["../../src/postprocessing/HalftonePass.ts"],"sourcesContent":["import { Pass, FullScreenQuad } from './Pass'\nimport { ShaderMaterial, UniformsUtils, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { HalftoneShader } from '../shaders/HalftoneShader'\n\ntype HalftonePassParams = {\n shape?: number\n radius?: number\n rotateR?: number\n rotateB?: number\n rotateG?: number\n scatter?: number\n blending?: number\n blendingMode?: number\n greyscale?: number\n disable?: number\n}\n\n/**\n * RGB Halftone pass for three.js effects composer. Requires HalftoneShader.\n */\n\nclass HalftonePass extends Pass {\n public material: ShaderMaterial\n public fsQuad: FullScreenQuad\n\n public uniforms: any\n\n constructor(width: number, height: number, params: HalftonePassParams) {\n super()\n\n if (HalftoneShader === undefined) {\n console.error('THREE.HalftonePass requires HalftoneShader')\n }\n\n this.uniforms = UniformsUtils.clone(HalftoneShader.uniforms)\n this.material = new ShaderMaterial({\n uniforms: this.uniforms,\n fragmentShader: HalftoneShader.fragmentShader,\n vertexShader: HalftoneShader.vertexShader,\n })\n\n // set params\n this.uniforms.width.value = width\n this.uniforms.height.value = height\n\n for (const key in params) {\n if (params.hasOwnProperty(key) && this.uniforms.hasOwnProperty(key)) {\n this.uniforms[key].value = params[key as keyof HalftonePassParams]\n }\n }\n\n this.fsQuad = new FullScreenQuad(this.material)\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n /*, deltaTime, maskActive */\n ): void {\n this.material.uniforms['tDiffuse'].value = readBuffer.texture\n\n if (this.renderToScreen) {\n renderer.setRenderTarget(null)\n this.fsQuad.render(renderer)\n } else {\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n this.fsQuad.render(renderer)\n }\n }\n\n public setSize(width: number, height: number): void {\n this.uniforms.width.value = width\n this.uniforms.height.value = height\n }\n}\n\nexport { HalftonePass }\n"],"names":[],"mappings":";;;;;;;;;AAqBA,MAAM,qBAAqB,KAAK;AAAA,EAM9B,YAAY,OAAe,QAAgB,QAA4B;AAC/D;AAND;AACA;AAEA;AAKL,QAAI,mBAAmB,QAAW;AAChC,cAAQ,MAAM,4CAA4C;AAAA,IAC5D;AAEA,SAAK,WAAW,cAAc,MAAM,eAAe,QAAQ;AACtD,SAAA,WAAW,IAAI,eAAe;AAAA,MACjC,UAAU,KAAK;AAAA,MACf,gBAAgB,eAAe;AAAA,MAC/B,cAAc,eAAe;AAAA,IAAA,CAC9B;AAGI,SAAA,SAAS,MAAM,QAAQ;AACvB,SAAA,SAAS,OAAO,QAAQ;AAE7B,eAAW,OAAO,QAAQ;AACpB,UAAA,OAAO,eAAe,GAAG,KAAK,KAAK,SAAS,eAAe,GAAG,GAAG;AACnE,aAAK,SAAS,GAAG,EAAE,QAAQ,OAAO,GAA+B;AAAA,MACnE;AAAA,IACF;AAEA,SAAK,SAAS,IAAI,eAAe,KAAK,QAAQ;AAAA,EAChD;AAAA,EAEO,OACL,UACA,aACA,YAEM;AACN,SAAK,SAAS,SAAS,UAAU,EAAE,QAAQ,WAAW;AAEtD,QAAI,KAAK,gBAAgB;AACvB,eAAS,gBAAgB,IAAI;AACxB,WAAA,OAAO,OAAO,QAAQ;AAAA,IAAA,OACtB;AACL,eAAS,gBAAgB,WAAW;AACpC,UAAI,KAAK;AAAO,iBAAS,MAAM;AAC1B,WAAA,OAAO,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA,EAEO,QAAQ,OAAe,QAAsB;AAC7C,SAAA,SAAS,MAAM,QAAQ;AACvB,SAAA,SAAS,OAAO,QAAQ;AAAA,EAC/B;AACF;"}
+143
View File
@@ -0,0 +1,143 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const ShaderPass = require("./ShaderPass.cjs");
const LUTShader = {
defines: {
USE_3DTEXTURE: 1
},
uniforms: {
lut3d: { value: null },
lut: { value: null },
lutSize: { value: 0 },
tDiffuse: { value: null },
intensity: { value: 1 }
},
vertexShader: (
/* glsl */
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
),
fragmentShader: (
/* glsl */
`
uniform float lutSize;
#if USE_3DTEXTURE
precision highp sampler3D;
uniform sampler3D lut3d;
#else
uniform sampler2D lut;
vec3 lutLookup( sampler2D tex, float size, vec3 rgb ) {
float sliceHeight = 1.0 / size;
float yPixelHeight = 1.0 / ( size * size );
// Get the slices on either side of the sample
float slice = rgb.b * size;
float interp = fract( slice );
float slice0 = slice - interp;
float centeredInterp = interp - 0.5;
float slice1 = slice0 + sign( centeredInterp );
// Pull y sample in by half a pixel in each direction to avoid color
// bleeding from adjacent slices.
float greenOffset = clamp( rgb.g * sliceHeight, yPixelHeight * 0.5, sliceHeight - yPixelHeight * 0.5 );
vec2 uv0 = vec2(
rgb.r,
slice0 * sliceHeight + greenOffset
);
vec2 uv1 = vec2(
rgb.r,
slice1 * sliceHeight + greenOffset
);
vec3 sample0 = texture2D( tex, uv0 ).rgb;
vec3 sample1 = texture2D( tex, uv1 ).rgb;
return mix( sample0, sample1, abs( centeredInterp ) );
}
#endif
varying vec2 vUv;
uniform float intensity;
uniform sampler2D tDiffuse;
void main() {
vec4 val = texture2D( tDiffuse, vUv );
vec4 lutVal;
// pull the sample in by half a pixel so the sample begins
// at the center of the edge pixels.
float pixelWidth = 1.0 / lutSize;
float halfPixelWidth = 0.5 / lutSize;
vec3 uvw = vec3( halfPixelWidth ) + val.rgb * ( 1.0 - pixelWidth );
#if USE_3DTEXTURE
lutVal = vec4( texture( lut3d, uvw ).rgb, val.a );
#else
lutVal = vec4( lutLookup( lut, lutSize, uvw ), val.a );
#endif
gl_FragColor = vec4( mix( val, lutVal, intensity ) );
}
`
)
};
class LUTPass extends ShaderPass.ShaderPass {
set lut(v) {
const material = this.material;
if (v !== this.lut) {
material.uniforms.lut3d.value = null;
material.uniforms.lut.value = null;
if (v) {
const is3dTextureDefine = v.isData3DTexture ? 1 : 0;
if (is3dTextureDefine !== material.defines.USE_3DTEXTURE) {
material.defines.USE_3DTEXTURE = is3dTextureDefine;
material.needsUpdate = true;
}
material.uniforms.lutSize.value = v.image.width;
if (v.isData3DTexture) {
material.uniforms.lut3d.value = v;
} else {
material.uniforms.lut.value = v;
}
}
}
}
get lut() {
return this.material.uniforms.lut.value || this.material.uniforms.lut3d.value;
}
set intensity(v) {
this.material.uniforms.intensity.value = v;
}
get intensity() {
return this.material.uniforms.intensity.value;
}
constructor(options = {}) {
super(LUTShader);
this.lut = options.lut || null;
this.intensity = "intensity" in options ? options.intensity : 1;
}
}
exports.LUTPass = LUTPass;
//# sourceMappingURL=LUTPass.cjs.map
File diff suppressed because one or more lines are too long
+13
View File
@@ -0,0 +1,13 @@
import { DataTexture, Texture } from 'three'
import { ShaderPass } from './ShaderPass'
export interface LUTPassParameters {
lut?: DataTexture | Texture // Data3DTexture
intensity?: number
}
export class LUTPass extends ShaderPass {
lut?: DataTexture | Texture // Data3DTexture
intensity?: number
constructor(params: LUTPassParameters)
}
+143
View File
@@ -0,0 +1,143 @@
import { ShaderPass } from "./ShaderPass.js";
const LUTShader = {
defines: {
USE_3DTEXTURE: 1
},
uniforms: {
lut3d: { value: null },
lut: { value: null },
lutSize: { value: 0 },
tDiffuse: { value: null },
intensity: { value: 1 }
},
vertexShader: (
/* glsl */
`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`
),
fragmentShader: (
/* glsl */
`
uniform float lutSize;
#if USE_3DTEXTURE
precision highp sampler3D;
uniform sampler3D lut3d;
#else
uniform sampler2D lut;
vec3 lutLookup( sampler2D tex, float size, vec3 rgb ) {
float sliceHeight = 1.0 / size;
float yPixelHeight = 1.0 / ( size * size );
// Get the slices on either side of the sample
float slice = rgb.b * size;
float interp = fract( slice );
float slice0 = slice - interp;
float centeredInterp = interp - 0.5;
float slice1 = slice0 + sign( centeredInterp );
// Pull y sample in by half a pixel in each direction to avoid color
// bleeding from adjacent slices.
float greenOffset = clamp( rgb.g * sliceHeight, yPixelHeight * 0.5, sliceHeight - yPixelHeight * 0.5 );
vec2 uv0 = vec2(
rgb.r,
slice0 * sliceHeight + greenOffset
);
vec2 uv1 = vec2(
rgb.r,
slice1 * sliceHeight + greenOffset
);
vec3 sample0 = texture2D( tex, uv0 ).rgb;
vec3 sample1 = texture2D( tex, uv1 ).rgb;
return mix( sample0, sample1, abs( centeredInterp ) );
}
#endif
varying vec2 vUv;
uniform float intensity;
uniform sampler2D tDiffuse;
void main() {
vec4 val = texture2D( tDiffuse, vUv );
vec4 lutVal;
// pull the sample in by half a pixel so the sample begins
// at the center of the edge pixels.
float pixelWidth = 1.0 / lutSize;
float halfPixelWidth = 0.5 / lutSize;
vec3 uvw = vec3( halfPixelWidth ) + val.rgb * ( 1.0 - pixelWidth );
#if USE_3DTEXTURE
lutVal = vec4( texture( lut3d, uvw ).rgb, val.a );
#else
lutVal = vec4( lutLookup( lut, lutSize, uvw ), val.a );
#endif
gl_FragColor = vec4( mix( val, lutVal, intensity ) );
}
`
)
};
class LUTPass extends ShaderPass {
set lut(v) {
const material = this.material;
if (v !== this.lut) {
material.uniforms.lut3d.value = null;
material.uniforms.lut.value = null;
if (v) {
const is3dTextureDefine = v.isData3DTexture ? 1 : 0;
if (is3dTextureDefine !== material.defines.USE_3DTEXTURE) {
material.defines.USE_3DTEXTURE = is3dTextureDefine;
material.needsUpdate = true;
}
material.uniforms.lutSize.value = v.image.width;
if (v.isData3DTexture) {
material.uniforms.lut3d.value = v;
} else {
material.uniforms.lut.value = v;
}
}
}
}
get lut() {
return this.material.uniforms.lut.value || this.material.uniforms.lut3d.value;
}
set intensity(v) {
this.material.uniforms.intensity.value = v;
}
get intensity() {
return this.material.uniforms.intensity.value;
}
constructor(options = {}) {
super(LUTShader);
this.lut = options.lut || null;
this.intensity = "intensity" in options ? options.intensity : 1;
}
}
export {
LUTPass
};
//# sourceMappingURL=LUTPass.js.map
File diff suppressed because one or more lines are too long
+70
View File
@@ -0,0 +1,70 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
class MaskPass extends Pass.Pass {
constructor(scene, camera) {
super();
__publicField(this, "scene");
__publicField(this, "camera");
__publicField(this, "inverse");
this.scene = scene;
this.camera = camera;
this.clear = true;
this.needsSwap = false;
this.inverse = false;
}
render(renderer, writeBuffer, readBuffer) {
const context = renderer.getContext();
const state = renderer.state;
state.buffers.color.setMask(false);
state.buffers.depth.setMask(false);
state.buffers.color.setLocked(true);
state.buffers.depth.setLocked(true);
let writeValue, clearValue;
if (this.inverse) {
writeValue = 0;
clearValue = 1;
} else {
writeValue = 1;
clearValue = 0;
}
state.buffers.stencil.setTest(true);
state.buffers.stencil.setOp(context.REPLACE, context.REPLACE, context.REPLACE);
state.buffers.stencil.setFunc(context.ALWAYS, writeValue, 4294967295);
state.buffers.stencil.setClear(clearValue);
state.buffers.stencil.setLocked(true);
renderer.setRenderTarget(readBuffer);
if (this.clear)
renderer.clear();
renderer.render(this.scene, this.camera);
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
renderer.render(this.scene, this.camera);
state.buffers.color.setLocked(false);
state.buffers.depth.setLocked(false);
state.buffers.stencil.setLocked(false);
state.buffers.stencil.setFunc(context.EQUAL, 1, 4294967295);
state.buffers.stencil.setOp(context.KEEP, context.KEEP, context.KEEP);
state.buffers.stencil.setLocked(true);
}
}
class ClearMaskPass extends Pass.Pass {
constructor() {
super();
this.needsSwap = false;
}
render(renderer) {
renderer.state.buffers.stencil.setLocked(false);
renderer.state.buffers.stencil.setTest(false);
}
}
exports.ClearMaskPass = ClearMaskPass;
exports.MaskPass = MaskPass;
//# sourceMappingURL=MaskPass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"MaskPass.cjs","sources":["../../src/postprocessing/MaskPass.ts"],"sourcesContent":["import { Camera, Scene, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { Pass } from './Pass'\n\nclass MaskPass extends Pass {\n public scene: Scene\n public camera: Camera\n public inverse: boolean\n\n constructor(scene: Scene, camera: Camera) {\n super()\n\n this.scene = scene\n this.camera = camera\n\n this.clear = true\n this.needsSwap = false\n\n this.inverse = false\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget /*, deltaTime, maskActive */,\n ): void {\n const context = renderer.getContext()\n const state = renderer.state\n\n // don't update color or depth\n\n state.buffers.color.setMask(false)\n state.buffers.depth.setMask(false)\n\n // lock buffers\n\n state.buffers.color.setLocked(true)\n state.buffers.depth.setLocked(true)\n\n // set up stencil\n\n let writeValue, clearValue\n\n if (this.inverse) {\n writeValue = 0\n clearValue = 1\n } else {\n writeValue = 1\n clearValue = 0\n }\n\n state.buffers.stencil.setTest(true)\n state.buffers.stencil.setOp(context.REPLACE, context.REPLACE, context.REPLACE)\n state.buffers.stencil.setFunc(context.ALWAYS, writeValue, 0xffffffff)\n state.buffers.stencil.setClear(clearValue)\n state.buffers.stencil.setLocked(true)\n\n // draw into the stencil buffer\n\n renderer.setRenderTarget(readBuffer)\n if (this.clear) renderer.clear()\n renderer.render(this.scene, this.camera)\n\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n renderer.render(this.scene, this.camera)\n\n // unlock color and depth buffer for subsequent rendering\n\n state.buffers.color.setLocked(false)\n state.buffers.depth.setLocked(false)\n\n // only render where stencil is set to 1\n\n state.buffers.stencil.setLocked(false)\n state.buffers.stencil.setFunc(context.EQUAL, 1, 0xffffffff) // draw if == 1\n state.buffers.stencil.setOp(context.KEEP, context.KEEP, context.KEEP)\n state.buffers.stencil.setLocked(true)\n }\n}\n\nclass ClearMaskPass extends Pass {\n constructor() {\n super()\n this.needsSwap = false\n }\n\n public render(renderer: WebGLRenderer /*, writeBuffer, readBuffer, deltaTime, maskActive */): void {\n renderer.state.buffers.stencil.setLocked(false)\n renderer.state.buffers.stencil.setTest(false)\n }\n}\n\nexport { MaskPass, ClearMaskPass }\n"],"names":["Pass"],"mappings":";;;;;;;;;AAGA,MAAM,iBAAiBA,KAAAA,KAAK;AAAA,EAK1B,YAAY,OAAc,QAAgB;AAClC;AALD;AACA;AACA;AAKL,SAAK,QAAQ;AACb,SAAK,SAAS;AAEd,SAAK,QAAQ;AACb,SAAK,YAAY;AAEjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,OACL,UACA,aACA,YACM;AACA,UAAA,UAAU,SAAS;AACzB,UAAM,QAAQ,SAAS;AAIjB,UAAA,QAAQ,MAAM,QAAQ,KAAK;AAC3B,UAAA,QAAQ,MAAM,QAAQ,KAAK;AAI3B,UAAA,QAAQ,MAAM,UAAU,IAAI;AAC5B,UAAA,QAAQ,MAAM,UAAU,IAAI;AAIlC,QAAI,YAAY;AAEhB,QAAI,KAAK,SAAS;AACH,mBAAA;AACA,mBAAA;AAAA,IAAA,OACR;AACQ,mBAAA;AACA,mBAAA;AAAA,IACf;AAEM,UAAA,QAAQ,QAAQ,QAAQ,IAAI;AAC5B,UAAA,QAAQ,QAAQ,MAAM,QAAQ,SAAS,QAAQ,SAAS,QAAQ,OAAO;AAC7E,UAAM,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,UAAU;AAC9D,UAAA,QAAQ,QAAQ,SAAS,UAAU;AACnC,UAAA,QAAQ,QAAQ,UAAU,IAAI;AAIpC,aAAS,gBAAgB,UAAU;AACnC,QAAI,KAAK;AAAO,eAAS,MAAM;AAC/B,aAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAEvC,aAAS,gBAAgB,WAAW;AACpC,QAAI,KAAK;AAAO,eAAS,MAAM;AAC/B,aAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAIjC,UAAA,QAAQ,MAAM,UAAU,KAAK;AAC7B,UAAA,QAAQ,MAAM,UAAU,KAAK;AAI7B,UAAA,QAAQ,QAAQ,UAAU,KAAK;AACrC,UAAM,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,GAAG,UAAU;AACpD,UAAA,QAAQ,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,IAAI;AAC9D,UAAA,QAAQ,QAAQ,UAAU,IAAI;AAAA,EACtC;AACF;AAEA,MAAM,sBAAsBA,KAAAA,KAAK;AAAA,EAC/B,cAAc;AACN;AACN,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,OAAO,UAAqF;AACjG,aAAS,MAAM,QAAQ,QAAQ,UAAU,KAAK;AAC9C,aAAS,MAAM,QAAQ,QAAQ,QAAQ,KAAK;AAAA,EAC9C;AACF;;;"}
+14
View File
@@ -0,0 +1,14 @@
import { Camera, Scene, WebGLRenderer, WebGLRenderTarget } from 'three';
import { Pass } from './Pass';
declare class MaskPass extends Pass {
scene: Scene;
camera: Camera;
inverse: boolean;
constructor(scene: Scene, camera: Camera);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
}
declare class ClearMaskPass extends Pass {
constructor();
render(renderer: WebGLRenderer): void;
}
export { MaskPass, ClearMaskPass };
+70
View File
@@ -0,0 +1,70 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass } from "./Pass.js";
class MaskPass extends Pass {
constructor(scene, camera) {
super();
__publicField(this, "scene");
__publicField(this, "camera");
__publicField(this, "inverse");
this.scene = scene;
this.camera = camera;
this.clear = true;
this.needsSwap = false;
this.inverse = false;
}
render(renderer, writeBuffer, readBuffer) {
const context = renderer.getContext();
const state = renderer.state;
state.buffers.color.setMask(false);
state.buffers.depth.setMask(false);
state.buffers.color.setLocked(true);
state.buffers.depth.setLocked(true);
let writeValue, clearValue;
if (this.inverse) {
writeValue = 0;
clearValue = 1;
} else {
writeValue = 1;
clearValue = 0;
}
state.buffers.stencil.setTest(true);
state.buffers.stencil.setOp(context.REPLACE, context.REPLACE, context.REPLACE);
state.buffers.stencil.setFunc(context.ALWAYS, writeValue, 4294967295);
state.buffers.stencil.setClear(clearValue);
state.buffers.stencil.setLocked(true);
renderer.setRenderTarget(readBuffer);
if (this.clear)
renderer.clear();
renderer.render(this.scene, this.camera);
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
renderer.render(this.scene, this.camera);
state.buffers.color.setLocked(false);
state.buffers.depth.setLocked(false);
state.buffers.stencil.setLocked(false);
state.buffers.stencil.setFunc(context.EQUAL, 1, 4294967295);
state.buffers.stencil.setOp(context.KEEP, context.KEEP, context.KEEP);
state.buffers.stencil.setLocked(true);
}
}
class ClearMaskPass extends Pass {
constructor() {
super();
this.needsSwap = false;
}
render(renderer) {
renderer.state.buffers.stencil.setLocked(false);
renderer.state.buffers.stencil.setTest(false);
}
}
export {
ClearMaskPass,
MaskPass
};
//# sourceMappingURL=MaskPass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"MaskPass.js","sources":["../../src/postprocessing/MaskPass.ts"],"sourcesContent":["import { Camera, Scene, WebGLRenderer, WebGLRenderTarget } from 'three'\nimport { Pass } from './Pass'\n\nclass MaskPass extends Pass {\n public scene: Scene\n public camera: Camera\n public inverse: boolean\n\n constructor(scene: Scene, camera: Camera) {\n super()\n\n this.scene = scene\n this.camera = camera\n\n this.clear = true\n this.needsSwap = false\n\n this.inverse = false\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget /*, deltaTime, maskActive */,\n ): void {\n const context = renderer.getContext()\n const state = renderer.state\n\n // don't update color or depth\n\n state.buffers.color.setMask(false)\n state.buffers.depth.setMask(false)\n\n // lock buffers\n\n state.buffers.color.setLocked(true)\n state.buffers.depth.setLocked(true)\n\n // set up stencil\n\n let writeValue, clearValue\n\n if (this.inverse) {\n writeValue = 0\n clearValue = 1\n } else {\n writeValue = 1\n clearValue = 0\n }\n\n state.buffers.stencil.setTest(true)\n state.buffers.stencil.setOp(context.REPLACE, context.REPLACE, context.REPLACE)\n state.buffers.stencil.setFunc(context.ALWAYS, writeValue, 0xffffffff)\n state.buffers.stencil.setClear(clearValue)\n state.buffers.stencil.setLocked(true)\n\n // draw into the stencil buffer\n\n renderer.setRenderTarget(readBuffer)\n if (this.clear) renderer.clear()\n renderer.render(this.scene, this.camera)\n\n renderer.setRenderTarget(writeBuffer)\n if (this.clear) renderer.clear()\n renderer.render(this.scene, this.camera)\n\n // unlock color and depth buffer for subsequent rendering\n\n state.buffers.color.setLocked(false)\n state.buffers.depth.setLocked(false)\n\n // only render where stencil is set to 1\n\n state.buffers.stencil.setLocked(false)\n state.buffers.stencil.setFunc(context.EQUAL, 1, 0xffffffff) // draw if == 1\n state.buffers.stencil.setOp(context.KEEP, context.KEEP, context.KEEP)\n state.buffers.stencil.setLocked(true)\n }\n}\n\nclass ClearMaskPass extends Pass {\n constructor() {\n super()\n this.needsSwap = false\n }\n\n public render(renderer: WebGLRenderer /*, writeBuffer, readBuffer, deltaTime, maskActive */): void {\n renderer.state.buffers.stencil.setLocked(false)\n renderer.state.buffers.stencil.setTest(false)\n }\n}\n\nexport { MaskPass, ClearMaskPass }\n"],"names":[],"mappings":";;;;;;;AAGA,MAAM,iBAAiB,KAAK;AAAA,EAK1B,YAAY,OAAc,QAAgB;AAClC;AALD;AACA;AACA;AAKL,SAAK,QAAQ;AACb,SAAK,SAAS;AAEd,SAAK,QAAQ;AACb,SAAK,YAAY;AAEjB,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,OACL,UACA,aACA,YACM;AACA,UAAA,UAAU,SAAS;AACzB,UAAM,QAAQ,SAAS;AAIjB,UAAA,QAAQ,MAAM,QAAQ,KAAK;AAC3B,UAAA,QAAQ,MAAM,QAAQ,KAAK;AAI3B,UAAA,QAAQ,MAAM,UAAU,IAAI;AAC5B,UAAA,QAAQ,MAAM,UAAU,IAAI;AAIlC,QAAI,YAAY;AAEhB,QAAI,KAAK,SAAS;AACH,mBAAA;AACA,mBAAA;AAAA,IAAA,OACR;AACQ,mBAAA;AACA,mBAAA;AAAA,IACf;AAEM,UAAA,QAAQ,QAAQ,QAAQ,IAAI;AAC5B,UAAA,QAAQ,QAAQ,MAAM,QAAQ,SAAS,QAAQ,SAAS,QAAQ,OAAO;AAC7E,UAAM,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,YAAY,UAAU;AAC9D,UAAA,QAAQ,QAAQ,SAAS,UAAU;AACnC,UAAA,QAAQ,QAAQ,UAAU,IAAI;AAIpC,aAAS,gBAAgB,UAAU;AACnC,QAAI,KAAK;AAAO,eAAS,MAAM;AAC/B,aAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAEvC,aAAS,gBAAgB,WAAW;AACpC,QAAI,KAAK;AAAO,eAAS,MAAM;AAC/B,aAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAIjC,UAAA,QAAQ,MAAM,UAAU,KAAK;AAC7B,UAAA,QAAQ,MAAM,UAAU,KAAK;AAI7B,UAAA,QAAQ,QAAQ,UAAU,KAAK;AACrC,UAAM,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,GAAG,UAAU;AACpD,UAAA,QAAQ,QAAQ,MAAM,QAAQ,MAAM,QAAQ,MAAM,QAAQ,IAAI;AAC9D,UAAA,QAAQ,QAAQ,UAAU,IAAI;AAAA,EACtC;AACF;AAEA,MAAM,sBAAsB,KAAK;AAAA,EAC/B,cAAc;AACN;AACN,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,OAAO,UAAqF;AACjG,aAAS,MAAM,QAAQ,QAAQ,UAAU,KAAK;AAC9C,aAAS,MAAM,QAAQ,QAAQ,QAAQ,KAAK;AAAA,EAC9C;AACF;"}
+480
View File
@@ -0,0 +1,480 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const Pass = require("./Pass.cjs");
const THREE = require("three");
const CopyShader = require("../shaders/CopyShader.cjs");
class OutlinePass extends Pass.Pass {
constructor(resolution, scene, camera, selectedObjects) {
super();
__publicField(this, "renderScene");
__publicField(this, "renderCamera");
__publicField(this, "selectedObjects");
__publicField(this, "visibleEdgeColor");
__publicField(this, "hiddenEdgeColor");
__publicField(this, "edgeGlow");
__publicField(this, "usePatternTexture");
__publicField(this, "edgeThickness");
__publicField(this, "edgeStrength");
__publicField(this, "downSampleRatio");
__publicField(this, "pulsePeriod");
__publicField(this, "resolution");
__publicField(this, "renderTargetMaskBuffer");
__publicField(this, "depthMaterial");
__publicField(this, "prepareMaskMaterial");
__publicField(this, "renderTargetDepthBuffer");
__publicField(this, "renderTargetMaskDownSampleBuffer");
__publicField(this, "renderTargetBlurBuffer1");
__publicField(this, "renderTargetBlurBuffer2");
__publicField(this, "edgeDetectionMaterial");
__publicField(this, "renderTargetEdgeBuffer1");
__publicField(this, "renderTargetEdgeBuffer2");
__publicField(this, "separableBlurMaterial1");
__publicField(this, "separableBlurMaterial2");
__publicField(this, "overlayMaterial");
__publicField(this, "materialCopy");
__publicField(this, "oldClearAlpha");
__publicField(this, "fsQuad");
__publicField(this, "tempPulseColor1");
__publicField(this, "tempPulseColor2");
__publicField(this, "textureMatrix");
__publicField(this, "patternTexture");
__publicField(this, "_visibilityCache");
__publicField(this, "_oldClearColor");
__publicField(this, "copyUniforms");
__publicField(this, "BlurDirectionX", new THREE.Vector2(1, 0));
__publicField(this, "BlurDirectionY", new THREE.Vector2(0, 1));
this.renderScene = scene;
this.renderCamera = camera;
this.selectedObjects = selectedObjects !== void 0 ? selectedObjects : [];
this.visibleEdgeColor = new THREE.Color(1, 1, 1);
this.hiddenEdgeColor = new THREE.Color(0.1, 0.04, 0.02);
this.edgeGlow = 0;
this.usePatternTexture = false;
this.edgeThickness = 1;
this.edgeStrength = 3;
this.downSampleRatio = 2;
this.pulsePeriod = 0;
this._visibilityCache = /* @__PURE__ */ new Map();
this.resolution = resolution !== void 0 ? new THREE.Vector2(resolution.x, resolution.y) : new THREE.Vector2(256, 256);
const resx = Math.round(this.resolution.x / this.downSampleRatio);
const resy = Math.round(this.resolution.y / this.downSampleRatio);
this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget(this.resolution.x, this.resolution.y);
this.renderTargetMaskBuffer.texture.name = "OutlinePass.mask";
this.renderTargetMaskBuffer.texture.generateMipmaps = false;
this.depthMaterial = new THREE.MeshDepthMaterial();
this.depthMaterial.side = THREE.DoubleSide;
this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
this.depthMaterial.blending = THREE.NoBlending;
this.prepareMaskMaterial = this.getPrepareMaskMaterial();
this.prepareMaskMaterial.side = THREE.DoubleSide;
this.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ(
this.prepareMaskMaterial.fragmentShader,
this.renderCamera
);
this.renderTargetDepthBuffer = new THREE.WebGLRenderTarget(this.resolution.x, this.resolution.y);
this.renderTargetDepthBuffer.texture.name = "OutlinePass.depth";
this.renderTargetDepthBuffer.texture.generateMipmaps = false;
this.renderTargetMaskDownSampleBuffer = new THREE.WebGLRenderTarget(resx, resy);
this.renderTargetMaskDownSampleBuffer.texture.name = "OutlinePass.depthDownSample";
this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;
this.renderTargetBlurBuffer1 = new THREE.WebGLRenderTarget(resx, resy);
this.renderTargetBlurBuffer1.texture.name = "OutlinePass.blur1";
this.renderTargetBlurBuffer1.texture.generateMipmaps = false;
this.renderTargetBlurBuffer2 = new THREE.WebGLRenderTarget(Math.round(resx / 2), Math.round(resy / 2));
this.renderTargetBlurBuffer2.texture.name = "OutlinePass.blur2";
this.renderTargetBlurBuffer2.texture.generateMipmaps = false;
this.edgeDetectionMaterial = this.getEdgeDetectionMaterial();
this.renderTargetEdgeBuffer1 = new THREE.WebGLRenderTarget(resx, resy);
this.renderTargetEdgeBuffer1.texture.name = "OutlinePass.edge1";
this.renderTargetEdgeBuffer1.texture.generateMipmaps = false;
this.renderTargetEdgeBuffer2 = new THREE.WebGLRenderTarget(Math.round(resx / 2), Math.round(resy / 2));
this.renderTargetEdgeBuffer2.texture.name = "OutlinePass.edge2";
this.renderTargetEdgeBuffer2.texture.generateMipmaps = false;
const MAX_EDGE_THICKNESS = 4;
const MAX_EDGE_GLOW = 4;
this.separableBlurMaterial1 = this.getSeperableBlurMaterial(MAX_EDGE_THICKNESS);
this.separableBlurMaterial1.uniforms["texSize"].value.set(resx, resy);
this.separableBlurMaterial1.uniforms["kernelRadius"].value = 1;
this.separableBlurMaterial2 = this.getSeperableBlurMaterial(MAX_EDGE_GLOW);
this.separableBlurMaterial2.uniforms["texSize"].value.set(Math.round(resx / 2), Math.round(resy / 2));
this.separableBlurMaterial2.uniforms["kernelRadius"].value = MAX_EDGE_GLOW;
this.overlayMaterial = this.getOverlayMaterial();
if (CopyShader.CopyShader === void 0)
console.error("THREE.OutlinePass relies on CopyShader");
const copyShader = CopyShader.CopyShader;
this.copyUniforms = THREE.UniformsUtils.clone(copyShader.uniforms);
this.copyUniforms["opacity"].value = 1;
this.materialCopy = new THREE.ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
blending: THREE.NoBlending,
depthTest: false,
depthWrite: false,
transparent: true
});
this.enabled = true;
this.needsSwap = false;
this._oldClearColor = new THREE.Color();
this.oldClearAlpha = 1;
this.fsQuad = new Pass.FullScreenQuad(this.materialCopy);
this.tempPulseColor1 = new THREE.Color();
this.tempPulseColor2 = new THREE.Color();
this.textureMatrix = new THREE.Matrix4();
function replaceDepthToViewZ(string, camera2) {
const type = camera2.isPerspectiveCamera ? "perspective" : "orthographic";
return string.replace(/DEPTH_TO_VIEW_Z/g, type + "DepthToViewZ");
}
}
dispose() {
this.renderTargetMaskBuffer.dispose();
this.renderTargetDepthBuffer.dispose();
this.renderTargetMaskDownSampleBuffer.dispose();
this.renderTargetBlurBuffer1.dispose();
this.renderTargetBlurBuffer2.dispose();
this.renderTargetEdgeBuffer1.dispose();
this.renderTargetEdgeBuffer2.dispose();
}
setSize(width, height) {
this.renderTargetMaskBuffer.setSize(width, height);
this.renderTargetDepthBuffer.setSize(width, height);
let resx = Math.round(width / this.downSampleRatio);
let resy = Math.round(height / this.downSampleRatio);
this.renderTargetMaskDownSampleBuffer.setSize(resx, resy);
this.renderTargetBlurBuffer1.setSize(resx, resy);
this.renderTargetEdgeBuffer1.setSize(resx, resy);
this.separableBlurMaterial1.uniforms["texSize"].value.set(resx, resy);
resx = Math.round(resx / 2);
resy = Math.round(resy / 2);
this.renderTargetBlurBuffer2.setSize(resx, resy);
this.renderTargetEdgeBuffer2.setSize(resx, resy);
this.separableBlurMaterial2.uniforms["texSize"].value.set(resx, resy);
}
changeVisibilityOfSelectedObjects(bVisible) {
const cache = this._visibilityCache;
function gatherSelectedMeshesCallBack(object) {
if (object.isMesh) {
if (bVisible === true) {
object.visible = cache.get(object);
} else {
cache.set(object, object.visible);
object.visible = bVisible;
}
}
}
for (let i = 0; i < this.selectedObjects.length; i++) {
const selectedObject = this.selectedObjects[i];
selectedObject.traverse(gatherSelectedMeshesCallBack);
}
}
changeVisibilityOfNonSelectedObjects(bVisible) {
const cache = this._visibilityCache;
const selectedMeshes = [];
function gatherSelectedMeshesCallBack(object) {
if (object.isMesh)
selectedMeshes.push(object);
}
for (let i = 0; i < this.selectedObjects.length; i++) {
const selectedObject = this.selectedObjects[i];
selectedObject.traverse(gatherSelectedMeshesCallBack);
}
function VisibilityChangeCallBack(object) {
if (object.isMesh || object.isSprite) {
let bFound = false;
for (let i = 0; i < selectedMeshes.length; i++) {
const selectedObjectId = selectedMeshes[i].id;
if (selectedObjectId === object.id) {
bFound = true;
break;
}
}
if (bFound === false) {
const visibility = object.visible;
if (bVisible === false || cache.get(object) === true) {
object.visible = bVisible;
}
cache.set(object, visibility);
}
} else if (object.isPoints || object.isLine) {
if (bVisible === true) {
object.visible = cache.get(object);
} else {
cache.set(object, object.visible);
object.visible = bVisible;
}
}
}
this.renderScene.traverse(VisibilityChangeCallBack);
}
updateTextureMatrix() {
this.textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
this.textureMatrix.multiply(this.renderCamera.projectionMatrix);
this.textureMatrix.multiply(this.renderCamera.matrixWorldInverse);
}
render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) {
if (this.selectedObjects.length > 0) {
renderer.getClearColor(this._oldClearColor);
this.oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
if (maskActive)
renderer.state.buffers.stencil.setTest(false);
renderer.setClearColor(16777215, 1);
this.changeVisibilityOfSelectedObjects(false);
const currentBackground = this.renderScene.background;
this.renderScene.background = null;
this.renderScene.overrideMaterial = this.depthMaterial;
renderer.setRenderTarget(this.renderTargetDepthBuffer);
renderer.clear();
renderer.render(this.renderScene, this.renderCamera);
this.changeVisibilityOfSelectedObjects(true);
this._visibilityCache.clear();
this.updateTextureMatrix();
this.changeVisibilityOfNonSelectedObjects(false);
this.renderScene.overrideMaterial = this.prepareMaskMaterial;
this.prepareMaskMaterial.uniforms["cameraNearFar"].value.set(
this.renderCamera.near,
this.renderCamera.far
);
this.prepareMaskMaterial.uniforms["depthTexture"].value = this.renderTargetDepthBuffer.texture;
this.prepareMaskMaterial.uniforms["textureMatrix"].value = this.textureMatrix;
renderer.setRenderTarget(this.renderTargetMaskBuffer);
renderer.clear();
renderer.render(this.renderScene, this.renderCamera);
this.renderScene.overrideMaterial = null;
this.changeVisibilityOfNonSelectedObjects(true);
this._visibilityCache.clear();
this.renderScene.background = currentBackground;
this.fsQuad.material = this.materialCopy;
this.copyUniforms["tDiffuse"].value = this.renderTargetMaskBuffer.texture;
renderer.setRenderTarget(this.renderTargetMaskDownSampleBuffer);
renderer.clear();
this.fsQuad.render(renderer);
this.tempPulseColor1.copy(this.visibleEdgeColor);
this.tempPulseColor2.copy(this.hiddenEdgeColor);
if (this.pulsePeriod > 0) {
const scalar = (1 + 0.25) / 2 + Math.cos(performance.now() * 0.01 / this.pulsePeriod) * (1 - 0.25) / 2;
this.tempPulseColor1.multiplyScalar(scalar);
this.tempPulseColor2.multiplyScalar(scalar);
}
this.fsQuad.material = this.edgeDetectionMaterial;
this.edgeDetectionMaterial.uniforms["maskTexture"].value = this.renderTargetMaskDownSampleBuffer.texture;
this.edgeDetectionMaterial.uniforms["texSize"].value.set(
this.renderTargetMaskDownSampleBuffer.width,
this.renderTargetMaskDownSampleBuffer.height
);
this.edgeDetectionMaterial.uniforms["visibleEdgeColor"].value = this.tempPulseColor1;
this.edgeDetectionMaterial.uniforms["hiddenEdgeColor"].value = this.tempPulseColor2;
renderer.setRenderTarget(this.renderTargetEdgeBuffer1);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.separableBlurMaterial1;
this.separableBlurMaterial1.uniforms["colorTexture"].value = this.renderTargetEdgeBuffer1.texture;
this.separableBlurMaterial1.uniforms["direction"].value = this.BlurDirectionX;
this.separableBlurMaterial1.uniforms["kernelRadius"].value = this.edgeThickness;
renderer.setRenderTarget(this.renderTargetBlurBuffer1);
renderer.clear();
this.fsQuad.render(renderer);
this.separableBlurMaterial1.uniforms["colorTexture"].value = this.renderTargetBlurBuffer1.texture;
this.separableBlurMaterial1.uniforms["direction"].value = this.BlurDirectionY;
renderer.setRenderTarget(this.renderTargetEdgeBuffer1);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.separableBlurMaterial2;
this.separableBlurMaterial2.uniforms["colorTexture"].value = this.renderTargetEdgeBuffer1.texture;
this.separableBlurMaterial2.uniforms["direction"].value = this.BlurDirectionX;
renderer.setRenderTarget(this.renderTargetBlurBuffer2);
renderer.clear();
this.fsQuad.render(renderer);
this.separableBlurMaterial2.uniforms["colorTexture"].value = this.renderTargetBlurBuffer2.texture;
this.separableBlurMaterial2.uniforms["direction"].value = this.BlurDirectionY;
renderer.setRenderTarget(this.renderTargetEdgeBuffer2);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.overlayMaterial;
this.overlayMaterial.uniforms["maskTexture"].value = this.renderTargetMaskBuffer.texture;
this.overlayMaterial.uniforms["edgeTexture1"].value = this.renderTargetEdgeBuffer1.texture;
this.overlayMaterial.uniforms["edgeTexture2"].value = this.renderTargetEdgeBuffer2.texture;
this.overlayMaterial.uniforms["patternTexture"].value = this.patternTexture;
this.overlayMaterial.uniforms["edgeStrength"].value = this.edgeStrength;
this.overlayMaterial.uniforms["edgeGlow"].value = this.edgeGlow;
this.overlayMaterial.uniforms["usePatternTexture"].value = this.usePatternTexture;
if (maskActive)
renderer.state.buffers.stencil.setTest(true);
renderer.setRenderTarget(readBuffer);
this.fsQuad.render(renderer);
renderer.setClearColor(this._oldClearColor, this.oldClearAlpha);
renderer.autoClear = oldAutoClear;
}
if (this.renderToScreen) {
this.fsQuad.material = this.materialCopy;
this.copyUniforms["tDiffuse"].value = readBuffer.texture;
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
}
}
getPrepareMaskMaterial() {
return new THREE.ShaderMaterial({
uniforms: {
depthTexture: { value: null },
cameraNearFar: { value: new THREE.Vector2(0.5, 0.5) },
textureMatrix: { value: null }
},
vertexShader: `#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
varying vec4 projTexCoord;
varying vec4 vPosition;
uniform mat4 textureMatrix;
void main() {
#include <skinbase_vertex>
#include <begin_vertex>
#include <morphtarget_vertex>
#include <skinning_vertex>
#include <project_vertex>
vPosition = mvPosition;
vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
projTexCoord = textureMatrix * worldPosition;
}`,
fragmentShader: `#include <packing>
varying vec4 vPosition;
varying vec4 projTexCoord;
uniform sampler2D depthTexture;
uniform vec2 cameraNearFar;
void main() {
float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));
float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );
float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;
gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);
}`
});
}
getEdgeDetectionMaterial() {
return new THREE.ShaderMaterial({
uniforms: {
maskTexture: { value: null },
texSize: { value: new THREE.Vector2(0.5, 0.5) },
visibleEdgeColor: { value: new THREE.Vector3(1, 1, 1) },
hiddenEdgeColor: { value: new THREE.Vector3(1, 1, 1) }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec2 vUv;
uniform sampler2D maskTexture;
uniform vec2 texSize;
uniform vec3 visibleEdgeColor;
uniform vec3 hiddenEdgeColor;
void main() {
vec2 invSize = 1.0 / texSize;
vec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);
vec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);
vec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);
vec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);
vec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);
float diff1 = (c1.r - c2.r)*0.5;
float diff2 = (c3.r - c4.r)*0.5;
float d = length( vec2(diff1, diff2) );
float a1 = min(c1.g, c2.g);
float a2 = min(c3.g, c4.g);
float visibilityFactor = min(a1, a2);
vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;
gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);
}`
});
}
getSeperableBlurMaterial(maxRadius) {
return new THREE.ShaderMaterial({
defines: {
MAX_RADIUS: maxRadius
},
uniforms: {
colorTexture: { value: null },
texSize: { value: new THREE.Vector2(0.5, 0.5) },
direction: { value: new THREE.Vector2(0.5, 0.5) },
kernelRadius: { value: 1 }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `#include <common>
varying vec2 vUv;
uniform sampler2D colorTexture;
uniform vec2 texSize;
uniform vec2 direction;
uniform float kernelRadius;
float gaussianPdf(in float x, in float sigma) {
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
}
void main() {
vec2 invSize = 1.0 / texSize;
float weightSum = gaussianPdf(0.0, kernelRadius);
vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;
vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);
vec2 uvOffset = delta;
for( int i = 1; i <= MAX_RADIUS; i ++ ) {
float w = gaussianPdf(uvOffset.x, kernelRadius);
vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);
vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);
diffuseSum += ((sample1 + sample2) * w);
weightSum += (2.0 * w);
uvOffset += delta;
}
gl_FragColor = diffuseSum/weightSum;
}`
});
}
getOverlayMaterial() {
return new THREE.ShaderMaterial({
uniforms: {
maskTexture: { value: null },
edgeTexture1: { value: null },
edgeTexture2: { value: null },
patternTexture: { value: null },
edgeStrength: { value: 1 },
edgeGlow: { value: 1 },
usePatternTexture: { value: 0 }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec2 vUv;
uniform sampler2D maskTexture;
uniform sampler2D edgeTexture1;
uniform sampler2D edgeTexture2;
uniform sampler2D patternTexture;
uniform float edgeStrength;
uniform float edgeGlow;
uniform bool usePatternTexture;
void main() {
vec4 edgeValue1 = texture2D(edgeTexture1, vUv);
vec4 edgeValue2 = texture2D(edgeTexture2, vUv);
vec4 maskColor = texture2D(maskTexture, vUv);
vec4 patternColor = texture2D(patternTexture, 6.0 * vUv);
float visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;
vec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;
vec4 finalColor = edgeStrength * maskColor.r * edgeValue;
if(usePatternTexture)
finalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);
gl_FragColor = finalColor;
}`,
blending: THREE.AdditiveBlending,
depthTest: false,
depthWrite: false,
transparent: true
});
}
}
exports.OutlinePass = OutlinePass;
//# sourceMappingURL=OutlinePass.cjs.map
File diff suppressed because one or more lines are too long
+53
View File
@@ -0,0 +1,53 @@
import { Pass, FullScreenQuad } from './Pass';
import { Camera, Color, Matrix4, MeshDepthMaterial, Object3D, Scene, ShaderMaterial, Texture, Vector2, WebGLRenderer, WebGLRenderTarget } from 'three';
declare class OutlinePass extends Pass {
renderScene: Scene;
renderCamera: Camera;
selectedObjects: Object3D[];
visibleEdgeColor: Color;
hiddenEdgeColor: Color;
edgeGlow: number;
usePatternTexture: boolean;
edgeThickness: number;
edgeStrength: number;
downSampleRatio: number;
pulsePeriod: number;
resolution: Vector2;
renderTargetMaskBuffer: WebGLRenderTarget;
depthMaterial: MeshDepthMaterial;
prepareMaskMaterial: ShaderMaterial;
renderTargetDepthBuffer: WebGLRenderTarget;
renderTargetMaskDownSampleBuffer: WebGLRenderTarget;
renderTargetBlurBuffer1: WebGLRenderTarget;
renderTargetBlurBuffer2: WebGLRenderTarget;
edgeDetectionMaterial: ShaderMaterial;
renderTargetEdgeBuffer1: WebGLRenderTarget;
renderTargetEdgeBuffer2: WebGLRenderTarget;
separableBlurMaterial1: ShaderMaterial;
separableBlurMaterial2: ShaderMaterial;
overlayMaterial: ShaderMaterial;
materialCopy: ShaderMaterial;
oldClearAlpha: number;
fsQuad: FullScreenQuad;
tempPulseColor1: Color;
tempPulseColor2: Color;
textureMatrix: Matrix4;
patternTexture?: Texture;
private _visibilityCache;
private _oldClearColor;
copyUniforms: any;
BlurDirectionX: Vector2;
BlurDirectionY: Vector2;
constructor(resolution: Vector2, scene: Scene, camera: Camera, selectedObjects?: Object3D[]);
dispose(): void;
setSize(width: number, height: number): void;
changeVisibilityOfSelectedObjects(bVisible: boolean): void;
changeVisibilityOfNonSelectedObjects(bVisible: boolean): void;
updateTextureMatrix(): void;
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive: boolean): void;
getPrepareMaskMaterial(): ShaderMaterial;
getEdgeDetectionMaterial(): ShaderMaterial;
getSeperableBlurMaterial(maxRadius: number): ShaderMaterial;
getOverlayMaterial(): ShaderMaterial;
}
export { OutlinePass };
+480
View File
@@ -0,0 +1,480 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Pass, FullScreenQuad } from "./Pass.js";
import { Vector2, Color, WebGLRenderTarget, MeshDepthMaterial, DoubleSide, RGBADepthPacking, NoBlending, UniformsUtils, ShaderMaterial, Matrix4, Vector3, AdditiveBlending } from "three";
import { CopyShader } from "../shaders/CopyShader.js";
class OutlinePass extends Pass {
constructor(resolution, scene, camera, selectedObjects) {
super();
__publicField(this, "renderScene");
__publicField(this, "renderCamera");
__publicField(this, "selectedObjects");
__publicField(this, "visibleEdgeColor");
__publicField(this, "hiddenEdgeColor");
__publicField(this, "edgeGlow");
__publicField(this, "usePatternTexture");
__publicField(this, "edgeThickness");
__publicField(this, "edgeStrength");
__publicField(this, "downSampleRatio");
__publicField(this, "pulsePeriod");
__publicField(this, "resolution");
__publicField(this, "renderTargetMaskBuffer");
__publicField(this, "depthMaterial");
__publicField(this, "prepareMaskMaterial");
__publicField(this, "renderTargetDepthBuffer");
__publicField(this, "renderTargetMaskDownSampleBuffer");
__publicField(this, "renderTargetBlurBuffer1");
__publicField(this, "renderTargetBlurBuffer2");
__publicField(this, "edgeDetectionMaterial");
__publicField(this, "renderTargetEdgeBuffer1");
__publicField(this, "renderTargetEdgeBuffer2");
__publicField(this, "separableBlurMaterial1");
__publicField(this, "separableBlurMaterial2");
__publicField(this, "overlayMaterial");
__publicField(this, "materialCopy");
__publicField(this, "oldClearAlpha");
__publicField(this, "fsQuad");
__publicField(this, "tempPulseColor1");
__publicField(this, "tempPulseColor2");
__publicField(this, "textureMatrix");
__publicField(this, "patternTexture");
__publicField(this, "_visibilityCache");
__publicField(this, "_oldClearColor");
__publicField(this, "copyUniforms");
__publicField(this, "BlurDirectionX", new Vector2(1, 0));
__publicField(this, "BlurDirectionY", new Vector2(0, 1));
this.renderScene = scene;
this.renderCamera = camera;
this.selectedObjects = selectedObjects !== void 0 ? selectedObjects : [];
this.visibleEdgeColor = new Color(1, 1, 1);
this.hiddenEdgeColor = new Color(0.1, 0.04, 0.02);
this.edgeGlow = 0;
this.usePatternTexture = false;
this.edgeThickness = 1;
this.edgeStrength = 3;
this.downSampleRatio = 2;
this.pulsePeriod = 0;
this._visibilityCache = /* @__PURE__ */ new Map();
this.resolution = resolution !== void 0 ? new Vector2(resolution.x, resolution.y) : new Vector2(256, 256);
const resx = Math.round(this.resolution.x / this.downSampleRatio);
const resy = Math.round(this.resolution.y / this.downSampleRatio);
this.renderTargetMaskBuffer = new WebGLRenderTarget(this.resolution.x, this.resolution.y);
this.renderTargetMaskBuffer.texture.name = "OutlinePass.mask";
this.renderTargetMaskBuffer.texture.generateMipmaps = false;
this.depthMaterial = new MeshDepthMaterial();
this.depthMaterial.side = DoubleSide;
this.depthMaterial.depthPacking = RGBADepthPacking;
this.depthMaterial.blending = NoBlending;
this.prepareMaskMaterial = this.getPrepareMaskMaterial();
this.prepareMaskMaterial.side = DoubleSide;
this.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ(
this.prepareMaskMaterial.fragmentShader,
this.renderCamera
);
this.renderTargetDepthBuffer = new WebGLRenderTarget(this.resolution.x, this.resolution.y);
this.renderTargetDepthBuffer.texture.name = "OutlinePass.depth";
this.renderTargetDepthBuffer.texture.generateMipmaps = false;
this.renderTargetMaskDownSampleBuffer = new WebGLRenderTarget(resx, resy);
this.renderTargetMaskDownSampleBuffer.texture.name = "OutlinePass.depthDownSample";
this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;
this.renderTargetBlurBuffer1 = new WebGLRenderTarget(resx, resy);
this.renderTargetBlurBuffer1.texture.name = "OutlinePass.blur1";
this.renderTargetBlurBuffer1.texture.generateMipmaps = false;
this.renderTargetBlurBuffer2 = new WebGLRenderTarget(Math.round(resx / 2), Math.round(resy / 2));
this.renderTargetBlurBuffer2.texture.name = "OutlinePass.blur2";
this.renderTargetBlurBuffer2.texture.generateMipmaps = false;
this.edgeDetectionMaterial = this.getEdgeDetectionMaterial();
this.renderTargetEdgeBuffer1 = new WebGLRenderTarget(resx, resy);
this.renderTargetEdgeBuffer1.texture.name = "OutlinePass.edge1";
this.renderTargetEdgeBuffer1.texture.generateMipmaps = false;
this.renderTargetEdgeBuffer2 = new WebGLRenderTarget(Math.round(resx / 2), Math.round(resy / 2));
this.renderTargetEdgeBuffer2.texture.name = "OutlinePass.edge2";
this.renderTargetEdgeBuffer2.texture.generateMipmaps = false;
const MAX_EDGE_THICKNESS = 4;
const MAX_EDGE_GLOW = 4;
this.separableBlurMaterial1 = this.getSeperableBlurMaterial(MAX_EDGE_THICKNESS);
this.separableBlurMaterial1.uniforms["texSize"].value.set(resx, resy);
this.separableBlurMaterial1.uniforms["kernelRadius"].value = 1;
this.separableBlurMaterial2 = this.getSeperableBlurMaterial(MAX_EDGE_GLOW);
this.separableBlurMaterial2.uniforms["texSize"].value.set(Math.round(resx / 2), Math.round(resy / 2));
this.separableBlurMaterial2.uniforms["kernelRadius"].value = MAX_EDGE_GLOW;
this.overlayMaterial = this.getOverlayMaterial();
if (CopyShader === void 0)
console.error("THREE.OutlinePass relies on CopyShader");
const copyShader = CopyShader;
this.copyUniforms = UniformsUtils.clone(copyShader.uniforms);
this.copyUniforms["opacity"].value = 1;
this.materialCopy = new ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
blending: NoBlending,
depthTest: false,
depthWrite: false,
transparent: true
});
this.enabled = true;
this.needsSwap = false;
this._oldClearColor = new Color();
this.oldClearAlpha = 1;
this.fsQuad = new FullScreenQuad(this.materialCopy);
this.tempPulseColor1 = new Color();
this.tempPulseColor2 = new Color();
this.textureMatrix = new Matrix4();
function replaceDepthToViewZ(string, camera2) {
const type = camera2.isPerspectiveCamera ? "perspective" : "orthographic";
return string.replace(/DEPTH_TO_VIEW_Z/g, type + "DepthToViewZ");
}
}
dispose() {
this.renderTargetMaskBuffer.dispose();
this.renderTargetDepthBuffer.dispose();
this.renderTargetMaskDownSampleBuffer.dispose();
this.renderTargetBlurBuffer1.dispose();
this.renderTargetBlurBuffer2.dispose();
this.renderTargetEdgeBuffer1.dispose();
this.renderTargetEdgeBuffer2.dispose();
}
setSize(width, height) {
this.renderTargetMaskBuffer.setSize(width, height);
this.renderTargetDepthBuffer.setSize(width, height);
let resx = Math.round(width / this.downSampleRatio);
let resy = Math.round(height / this.downSampleRatio);
this.renderTargetMaskDownSampleBuffer.setSize(resx, resy);
this.renderTargetBlurBuffer1.setSize(resx, resy);
this.renderTargetEdgeBuffer1.setSize(resx, resy);
this.separableBlurMaterial1.uniforms["texSize"].value.set(resx, resy);
resx = Math.round(resx / 2);
resy = Math.round(resy / 2);
this.renderTargetBlurBuffer2.setSize(resx, resy);
this.renderTargetEdgeBuffer2.setSize(resx, resy);
this.separableBlurMaterial2.uniforms["texSize"].value.set(resx, resy);
}
changeVisibilityOfSelectedObjects(bVisible) {
const cache = this._visibilityCache;
function gatherSelectedMeshesCallBack(object) {
if (object.isMesh) {
if (bVisible === true) {
object.visible = cache.get(object);
} else {
cache.set(object, object.visible);
object.visible = bVisible;
}
}
}
for (let i = 0; i < this.selectedObjects.length; i++) {
const selectedObject = this.selectedObjects[i];
selectedObject.traverse(gatherSelectedMeshesCallBack);
}
}
changeVisibilityOfNonSelectedObjects(bVisible) {
const cache = this._visibilityCache;
const selectedMeshes = [];
function gatherSelectedMeshesCallBack(object) {
if (object.isMesh)
selectedMeshes.push(object);
}
for (let i = 0; i < this.selectedObjects.length; i++) {
const selectedObject = this.selectedObjects[i];
selectedObject.traverse(gatherSelectedMeshesCallBack);
}
function VisibilityChangeCallBack(object) {
if (object.isMesh || object.isSprite) {
let bFound = false;
for (let i = 0; i < selectedMeshes.length; i++) {
const selectedObjectId = selectedMeshes[i].id;
if (selectedObjectId === object.id) {
bFound = true;
break;
}
}
if (bFound === false) {
const visibility = object.visible;
if (bVisible === false || cache.get(object) === true) {
object.visible = bVisible;
}
cache.set(object, visibility);
}
} else if (object.isPoints || object.isLine) {
if (bVisible === true) {
object.visible = cache.get(object);
} else {
cache.set(object, object.visible);
object.visible = bVisible;
}
}
}
this.renderScene.traverse(VisibilityChangeCallBack);
}
updateTextureMatrix() {
this.textureMatrix.set(0.5, 0, 0, 0.5, 0, 0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1);
this.textureMatrix.multiply(this.renderCamera.projectionMatrix);
this.textureMatrix.multiply(this.renderCamera.matrixWorldInverse);
}
render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) {
if (this.selectedObjects.length > 0) {
renderer.getClearColor(this._oldClearColor);
this.oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
if (maskActive)
renderer.state.buffers.stencil.setTest(false);
renderer.setClearColor(16777215, 1);
this.changeVisibilityOfSelectedObjects(false);
const currentBackground = this.renderScene.background;
this.renderScene.background = null;
this.renderScene.overrideMaterial = this.depthMaterial;
renderer.setRenderTarget(this.renderTargetDepthBuffer);
renderer.clear();
renderer.render(this.renderScene, this.renderCamera);
this.changeVisibilityOfSelectedObjects(true);
this._visibilityCache.clear();
this.updateTextureMatrix();
this.changeVisibilityOfNonSelectedObjects(false);
this.renderScene.overrideMaterial = this.prepareMaskMaterial;
this.prepareMaskMaterial.uniforms["cameraNearFar"].value.set(
this.renderCamera.near,
this.renderCamera.far
);
this.prepareMaskMaterial.uniforms["depthTexture"].value = this.renderTargetDepthBuffer.texture;
this.prepareMaskMaterial.uniforms["textureMatrix"].value = this.textureMatrix;
renderer.setRenderTarget(this.renderTargetMaskBuffer);
renderer.clear();
renderer.render(this.renderScene, this.renderCamera);
this.renderScene.overrideMaterial = null;
this.changeVisibilityOfNonSelectedObjects(true);
this._visibilityCache.clear();
this.renderScene.background = currentBackground;
this.fsQuad.material = this.materialCopy;
this.copyUniforms["tDiffuse"].value = this.renderTargetMaskBuffer.texture;
renderer.setRenderTarget(this.renderTargetMaskDownSampleBuffer);
renderer.clear();
this.fsQuad.render(renderer);
this.tempPulseColor1.copy(this.visibleEdgeColor);
this.tempPulseColor2.copy(this.hiddenEdgeColor);
if (this.pulsePeriod > 0) {
const scalar = (1 + 0.25) / 2 + Math.cos(performance.now() * 0.01 / this.pulsePeriod) * (1 - 0.25) / 2;
this.tempPulseColor1.multiplyScalar(scalar);
this.tempPulseColor2.multiplyScalar(scalar);
}
this.fsQuad.material = this.edgeDetectionMaterial;
this.edgeDetectionMaterial.uniforms["maskTexture"].value = this.renderTargetMaskDownSampleBuffer.texture;
this.edgeDetectionMaterial.uniforms["texSize"].value.set(
this.renderTargetMaskDownSampleBuffer.width,
this.renderTargetMaskDownSampleBuffer.height
);
this.edgeDetectionMaterial.uniforms["visibleEdgeColor"].value = this.tempPulseColor1;
this.edgeDetectionMaterial.uniforms["hiddenEdgeColor"].value = this.tempPulseColor2;
renderer.setRenderTarget(this.renderTargetEdgeBuffer1);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.separableBlurMaterial1;
this.separableBlurMaterial1.uniforms["colorTexture"].value = this.renderTargetEdgeBuffer1.texture;
this.separableBlurMaterial1.uniforms["direction"].value = this.BlurDirectionX;
this.separableBlurMaterial1.uniforms["kernelRadius"].value = this.edgeThickness;
renderer.setRenderTarget(this.renderTargetBlurBuffer1);
renderer.clear();
this.fsQuad.render(renderer);
this.separableBlurMaterial1.uniforms["colorTexture"].value = this.renderTargetBlurBuffer1.texture;
this.separableBlurMaterial1.uniforms["direction"].value = this.BlurDirectionY;
renderer.setRenderTarget(this.renderTargetEdgeBuffer1);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.separableBlurMaterial2;
this.separableBlurMaterial2.uniforms["colorTexture"].value = this.renderTargetEdgeBuffer1.texture;
this.separableBlurMaterial2.uniforms["direction"].value = this.BlurDirectionX;
renderer.setRenderTarget(this.renderTargetBlurBuffer2);
renderer.clear();
this.fsQuad.render(renderer);
this.separableBlurMaterial2.uniforms["colorTexture"].value = this.renderTargetBlurBuffer2.texture;
this.separableBlurMaterial2.uniforms["direction"].value = this.BlurDirectionY;
renderer.setRenderTarget(this.renderTargetEdgeBuffer2);
renderer.clear();
this.fsQuad.render(renderer);
this.fsQuad.material = this.overlayMaterial;
this.overlayMaterial.uniforms["maskTexture"].value = this.renderTargetMaskBuffer.texture;
this.overlayMaterial.uniforms["edgeTexture1"].value = this.renderTargetEdgeBuffer1.texture;
this.overlayMaterial.uniforms["edgeTexture2"].value = this.renderTargetEdgeBuffer2.texture;
this.overlayMaterial.uniforms["patternTexture"].value = this.patternTexture;
this.overlayMaterial.uniforms["edgeStrength"].value = this.edgeStrength;
this.overlayMaterial.uniforms["edgeGlow"].value = this.edgeGlow;
this.overlayMaterial.uniforms["usePatternTexture"].value = this.usePatternTexture;
if (maskActive)
renderer.state.buffers.stencil.setTest(true);
renderer.setRenderTarget(readBuffer);
this.fsQuad.render(renderer);
renderer.setClearColor(this._oldClearColor, this.oldClearAlpha);
renderer.autoClear = oldAutoClear;
}
if (this.renderToScreen) {
this.fsQuad.material = this.materialCopy;
this.copyUniforms["tDiffuse"].value = readBuffer.texture;
renderer.setRenderTarget(null);
this.fsQuad.render(renderer);
}
}
getPrepareMaskMaterial() {
return new ShaderMaterial({
uniforms: {
depthTexture: { value: null },
cameraNearFar: { value: new Vector2(0.5, 0.5) },
textureMatrix: { value: null }
},
vertexShader: `#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
varying vec4 projTexCoord;
varying vec4 vPosition;
uniform mat4 textureMatrix;
void main() {
#include <skinbase_vertex>
#include <begin_vertex>
#include <morphtarget_vertex>
#include <skinning_vertex>
#include <project_vertex>
vPosition = mvPosition;
vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
projTexCoord = textureMatrix * worldPosition;
}`,
fragmentShader: `#include <packing>
varying vec4 vPosition;
varying vec4 projTexCoord;
uniform sampler2D depthTexture;
uniform vec2 cameraNearFar;
void main() {
float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));
float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );
float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;
gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);
}`
});
}
getEdgeDetectionMaterial() {
return new ShaderMaterial({
uniforms: {
maskTexture: { value: null },
texSize: { value: new Vector2(0.5, 0.5) },
visibleEdgeColor: { value: new Vector3(1, 1, 1) },
hiddenEdgeColor: { value: new Vector3(1, 1, 1) }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec2 vUv;
uniform sampler2D maskTexture;
uniform vec2 texSize;
uniform vec3 visibleEdgeColor;
uniform vec3 hiddenEdgeColor;
void main() {
vec2 invSize = 1.0 / texSize;
vec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);
vec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);
vec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);
vec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);
vec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);
float diff1 = (c1.r - c2.r)*0.5;
float diff2 = (c3.r - c4.r)*0.5;
float d = length( vec2(diff1, diff2) );
float a1 = min(c1.g, c2.g);
float a2 = min(c3.g, c4.g);
float visibilityFactor = min(a1, a2);
vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;
gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);
}`
});
}
getSeperableBlurMaterial(maxRadius) {
return new ShaderMaterial({
defines: {
MAX_RADIUS: maxRadius
},
uniforms: {
colorTexture: { value: null },
texSize: { value: new Vector2(0.5, 0.5) },
direction: { value: new Vector2(0.5, 0.5) },
kernelRadius: { value: 1 }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `#include <common>
varying vec2 vUv;
uniform sampler2D colorTexture;
uniform vec2 texSize;
uniform vec2 direction;
uniform float kernelRadius;
float gaussianPdf(in float x, in float sigma) {
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
}
void main() {
vec2 invSize = 1.0 / texSize;
float weightSum = gaussianPdf(0.0, kernelRadius);
vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;
vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);
vec2 uvOffset = delta;
for( int i = 1; i <= MAX_RADIUS; i ++ ) {
float w = gaussianPdf(uvOffset.x, kernelRadius);
vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);
vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);
diffuseSum += ((sample1 + sample2) * w);
weightSum += (2.0 * w);
uvOffset += delta;
}
gl_FragColor = diffuseSum/weightSum;
}`
});
}
getOverlayMaterial() {
return new ShaderMaterial({
uniforms: {
maskTexture: { value: null },
edgeTexture1: { value: null },
edgeTexture2: { value: null },
patternTexture: { value: null },
edgeStrength: { value: 1 },
edgeGlow: { value: 1 },
usePatternTexture: { value: 0 }
},
vertexShader: `varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec2 vUv;
uniform sampler2D maskTexture;
uniform sampler2D edgeTexture1;
uniform sampler2D edgeTexture2;
uniform sampler2D patternTexture;
uniform float edgeStrength;
uniform float edgeGlow;
uniform bool usePatternTexture;
void main() {
vec4 edgeValue1 = texture2D(edgeTexture1, vUv);
vec4 edgeValue2 = texture2D(edgeTexture2, vUv);
vec4 maskColor = texture2D(maskTexture, vUv);
vec4 patternColor = texture2D(patternTexture, 6.0 * vUv);
float visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;
vec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;
vec4 finalColor = edgeStrength * maskColor.r * edgeValue;
if(usePatternTexture)
finalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);
gl_FragColor = finalColor;
}`,
blending: AdditiveBlending,
depthTest: false,
depthWrite: false,
transparent: true
});
}
}
export {
OutlinePass
};
//# sourceMappingURL=OutlinePass.js.map
File diff suppressed because one or more lines are too long
+51
View File
@@ -0,0 +1,51 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
class Pass {
constructor() {
// if set to true, the pass is processed by the composer
__publicField(this, "enabled", true);
// if set to true, the pass indicates to swap read and write buffer after rendering
__publicField(this, "needsSwap", true);
// if set to true, the pass clears its buffer before rendering
__publicField(this, "clear", false);
// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
__publicField(this, "renderToScreen", false);
}
setSize(width, height) {
}
render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) {
console.error("THREE.Pass: .render() must be implemented in derived pass.");
}
dispose() {
}
}
class FullScreenQuad {
constructor(material) {
__publicField(this, "camera", new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1));
__publicField(this, "geometry", new THREE.PlaneGeometry(2, 2));
__publicField(this, "mesh");
this.mesh = new THREE.Mesh(this.geometry, material);
}
get material() {
return this.mesh.material;
}
set material(value) {
this.mesh.material = value;
}
dispose() {
this.mesh.geometry.dispose();
}
render(renderer) {
renderer.render(this.mesh, this.camera);
}
}
exports.FullScreenQuad = FullScreenQuad;
exports.Pass = Pass;
//# sourceMappingURL=Pass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Pass.cjs","sources":["../../src/postprocessing/Pass.ts"],"sourcesContent":["import { OrthographicCamera, PlaneGeometry, Mesh, Material, WebGLRenderer, WebGLRenderTarget } from 'three'\n\nclass Pass {\n // if set to true, the pass is processed by the composer\n public enabled = true\n\n // if set to true, the pass indicates to swap read and write buffer after rendering\n public needsSwap = true\n\n // if set to true, the pass clears its buffer before rendering\n public clear = false\n\n // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n public renderToScreen = false\n\n public setSize(width: number, height: number): void {}\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n deltaTime: number,\n maskActive?: unknown,\n ): void {\n console.error('THREE.Pass: .render() must be implemented in derived pass.')\n }\n\n public dispose() {}\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\nclass FullScreenQuad<TMaterial extends Material = Material> {\n public camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1)\n public geometry = new PlaneGeometry(2, 2)\n private mesh: Mesh<PlaneGeometry, TMaterial>\n\n constructor(material: TMaterial) {\n this.mesh = new Mesh(this.geometry, material)\n }\n\n public get material(): TMaterial {\n return this.mesh.material\n }\n\n public set material(value: TMaterial) {\n this.mesh.material = value\n }\n\n public dispose(): void {\n this.mesh.geometry.dispose()\n }\n\n public render(renderer: WebGLRenderer): void {\n renderer.render(this.mesh, this.camera)\n }\n}\n\nexport { Pass, FullScreenQuad }\n"],"names":["OrthographicCamera","PlaneGeometry","Mesh"],"mappings":";;;;;;;;;AAEA,MAAM,KAAK;AAAA,EAAX;AAES;AAAA,mCAAU;AAGV;AAAA,qCAAY;AAGZ;AAAA,iCAAQ;AAGR;AAAA,0CAAiB;AAAA;AAAA,EAEjB,QAAQ,OAAe,QAAsB;AAAA,EAAC;AAAA,EAE9C,OACL,UACA,aACA,YACA,WACA,YACM;AACN,YAAQ,MAAM,4DAA4D;AAAA,EAC5E;AAAA,EAEO,UAAU;AAAA,EAAC;AACpB;AAGA,MAAM,eAAsD;AAAA,EAK1D,YAAY,UAAqB;AAJ1B,kCAAS,IAAIA,yBAAmB,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC;AAClD,oCAAW,IAAIC,MAAAA,cAAc,GAAG,CAAC;AAChC;AAGN,SAAK,OAAO,IAAIC,MAAAA,KAAK,KAAK,UAAU,QAAQ;AAAA,EAC9C;AAAA,EAEA,IAAW,WAAsB;AAC/B,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAW,SAAS,OAAkB;AACpC,SAAK,KAAK,WAAW;AAAA,EACvB;AAAA,EAEO,UAAgB;AAChB,SAAA,KAAK,SAAS;EACrB;AAAA,EAEO,OAAO,UAA+B;AAC3C,aAAS,OAAO,KAAK,MAAM,KAAK,MAAM;AAAA,EACxC;AACF;;;"}
+21
View File
@@ -0,0 +1,21 @@
import { OrthographicCamera, PlaneGeometry, Material, WebGLRenderer, WebGLRenderTarget } from 'three';
declare class Pass {
enabled: boolean;
needsSwap: boolean;
clear: boolean;
renderToScreen: boolean;
setSize(width: number, height: number): void;
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, deltaTime: number, maskActive?: unknown): void;
dispose(): void;
}
declare class FullScreenQuad<TMaterial extends Material = Material> {
camera: OrthographicCamera;
geometry: PlaneGeometry;
private mesh;
constructor(material: TMaterial);
get material(): TMaterial;
set material(value: TMaterial);
dispose(): void;
render(renderer: WebGLRenderer): void;
}
export { Pass, FullScreenQuad };
+51
View File
@@ -0,0 +1,51 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { OrthographicCamera, PlaneGeometry, Mesh } from "three";
class Pass {
constructor() {
// if set to true, the pass is processed by the composer
__publicField(this, "enabled", true);
// if set to true, the pass indicates to swap read and write buffer after rendering
__publicField(this, "needsSwap", true);
// if set to true, the pass clears its buffer before rendering
__publicField(this, "clear", false);
// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
__publicField(this, "renderToScreen", false);
}
setSize(width, height) {
}
render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) {
console.error("THREE.Pass: .render() must be implemented in derived pass.");
}
dispose() {
}
}
class FullScreenQuad {
constructor(material) {
__publicField(this, "camera", new OrthographicCamera(-1, 1, 1, -1, 0, 1));
__publicField(this, "geometry", new PlaneGeometry(2, 2));
__publicField(this, "mesh");
this.mesh = new Mesh(this.geometry, material);
}
get material() {
return this.mesh.material;
}
set material(value) {
this.mesh.material = value;
}
dispose() {
this.mesh.geometry.dispose();
}
render(renderer) {
renderer.render(this.mesh, this.camera);
}
}
export {
FullScreenQuad,
Pass
};
//# sourceMappingURL=Pass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"Pass.js","sources":["../../src/postprocessing/Pass.ts"],"sourcesContent":["import { OrthographicCamera, PlaneGeometry, Mesh, Material, WebGLRenderer, WebGLRenderTarget } from 'three'\n\nclass Pass {\n // if set to true, the pass is processed by the composer\n public enabled = true\n\n // if set to true, the pass indicates to swap read and write buffer after rendering\n public needsSwap = true\n\n // if set to true, the pass clears its buffer before rendering\n public clear = false\n\n // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n public renderToScreen = false\n\n public setSize(width: number, height: number): void {}\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget,\n deltaTime: number,\n maskActive?: unknown,\n ): void {\n console.error('THREE.Pass: .render() must be implemented in derived pass.')\n }\n\n public dispose() {}\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\nclass FullScreenQuad<TMaterial extends Material = Material> {\n public camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1)\n public geometry = new PlaneGeometry(2, 2)\n private mesh: Mesh<PlaneGeometry, TMaterial>\n\n constructor(material: TMaterial) {\n this.mesh = new Mesh(this.geometry, material)\n }\n\n public get material(): TMaterial {\n return this.mesh.material\n }\n\n public set material(value: TMaterial) {\n this.mesh.material = value\n }\n\n public dispose(): void {\n this.mesh.geometry.dispose()\n }\n\n public render(renderer: WebGLRenderer): void {\n renderer.render(this.mesh, this.camera)\n }\n}\n\nexport { Pass, FullScreenQuad }\n"],"names":[],"mappings":";;;;;;;AAEA,MAAM,KAAK;AAAA,EAAX;AAES;AAAA,mCAAU;AAGV;AAAA,qCAAY;AAGZ;AAAA,iCAAQ;AAGR;AAAA,0CAAiB;AAAA;AAAA,EAEjB,QAAQ,OAAe,QAAsB;AAAA,EAAC;AAAA,EAE9C,OACL,UACA,aACA,YACA,WACA,YACM;AACN,YAAQ,MAAM,4DAA4D;AAAA,EAC5E;AAAA,EAEO,UAAU;AAAA,EAAC;AACpB;AAGA,MAAM,eAAsD;AAAA,EAK1D,YAAY,UAAqB;AAJ1B,kCAAS,IAAI,mBAAmB,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC;AAClD,oCAAW,IAAI,cAAc,GAAG,CAAC;AAChC;AAGN,SAAK,OAAO,IAAI,KAAK,KAAK,UAAU,QAAQ;AAAA,EAC9C;AAAA,EAEA,IAAW,WAAsB;AAC/B,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAW,SAAS,OAAkB;AACpC,SAAK,KAAK,WAAW;AAAA,EACvB;AAAA,EAEO,UAAgB;AAChB,SAAA,KAAK,SAAS;EACrB;AAAA,EAEO,OAAO,UAA+B;AAC3C,aAAS,OAAO,KAAK,MAAM,KAAK,MAAM;AAAA,EACxC;AACF;"}
+60
View File
@@ -0,0 +1,60 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
class RenderPass extends Pass.Pass {
constructor(scene, camera, overrideMaterial, clearColor, clearAlpha = 0) {
super();
__publicField(this, "scene");
__publicField(this, "camera");
__publicField(this, "overrideMaterial");
__publicField(this, "clearColor");
__publicField(this, "clearAlpha");
__publicField(this, "clearDepth", false);
__publicField(this, "_oldClearColor", new THREE.Color());
this.scene = scene;
this.camera = camera;
this.overrideMaterial = overrideMaterial;
this.clearColor = clearColor;
this.clearAlpha = clearAlpha;
this.clear = true;
this.needsSwap = false;
}
render(renderer, writeBuffer, readBuffer) {
let oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
let oldClearAlpha;
let oldOverrideMaterial = null;
if (this.overrideMaterial !== void 0) {
oldOverrideMaterial = this.scene.overrideMaterial;
this.scene.overrideMaterial = this.overrideMaterial;
}
if (this.clearColor) {
renderer.getClearColor(this._oldClearColor);
oldClearAlpha = renderer.getClearAlpha();
renderer.setClearColor(this.clearColor, this.clearAlpha);
}
if (this.clearDepth) {
renderer.clearDepth();
}
renderer.setRenderTarget(this.renderToScreen ? null : readBuffer);
if (this.clear)
renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil);
renderer.render(this.scene, this.camera);
if (this.clearColor) {
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
}
if (this.overrideMaterial !== void 0) {
this.scene.overrideMaterial = oldOverrideMaterial;
}
renderer.autoClear = oldAutoClear;
}
}
exports.RenderPass = RenderPass;
//# sourceMappingURL=RenderPass.cjs.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"RenderPass.cjs","sources":["../../src/postprocessing/RenderPass.ts"],"sourcesContent":["import { Camera, Color, Material, Scene, WebGLRenderTarget, WebGLRenderer } from 'three'\nimport { Pass } from './Pass'\n\nclass RenderPass extends Pass {\n public scene: Scene\n public camera: Camera\n public overrideMaterial: Material | undefined\n public clearColor: Color | undefined\n public clearAlpha: number\n public clearDepth = false\n private _oldClearColor = new Color()\n\n constructor(scene: Scene, camera: Camera, overrideMaterial?: Material, clearColor?: Color, clearAlpha = 0) {\n super()\n\n this.scene = scene\n this.camera = camera\n\n this.overrideMaterial = overrideMaterial\n\n this.clearColor = clearColor\n this.clearAlpha = clearAlpha\n\n this.clear = true\n this.needsSwap = false\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget /*, deltaTime, maskActive */,\n ): void {\n let oldAutoClear = renderer.autoClear\n renderer.autoClear = false\n\n let oldClearAlpha\n let oldOverrideMaterial: Material | null = null\n\n if (this.overrideMaterial !== undefined) {\n oldOverrideMaterial = this.scene.overrideMaterial\n\n this.scene.overrideMaterial = this.overrideMaterial\n }\n\n if (this.clearColor) {\n renderer.getClearColor(this._oldClearColor)\n oldClearAlpha = renderer.getClearAlpha()\n\n renderer.setClearColor(this.clearColor, this.clearAlpha)\n }\n\n if (this.clearDepth) {\n renderer.clearDepth()\n }\n\n renderer.setRenderTarget(this.renderToScreen ? null : readBuffer)\n\n // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600\n if (this.clear) renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil)\n renderer.render(this.scene, this.camera)\n\n if (this.clearColor) {\n renderer.setClearColor(this._oldClearColor, oldClearAlpha)\n }\n\n if (this.overrideMaterial !== undefined) {\n this.scene.overrideMaterial = oldOverrideMaterial\n }\n\n renderer.autoClear = oldAutoClear\n }\n}\n\nexport { RenderPass }\n"],"names":["Pass","Color"],"mappings":";;;;;;;;;;AAGA,MAAM,mBAAmBA,KAAAA,KAAK;AAAA,EAS5B,YAAY,OAAc,QAAgB,kBAA6B,YAAoB,aAAa,GAAG;AACnG;AATD;AACA;AACA;AACA;AACA;AACA,sCAAa;AACZ,0CAAiB,IAAIC,MAAAA;AAK3B,SAAK,QAAQ;AACb,SAAK,SAAS;AAEd,SAAK,mBAAmB;AAExB,SAAK,aAAa;AAClB,SAAK,aAAa;AAElB,SAAK,QAAQ;AACb,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,OACL,UACA,aACA,YACM;AACN,QAAI,eAAe,SAAS;AAC5B,aAAS,YAAY;AAEjB,QAAA;AACJ,QAAI,sBAAuC;AAEvC,QAAA,KAAK,qBAAqB,QAAW;AACvC,4BAAsB,KAAK,MAAM;AAE5B,WAAA,MAAM,mBAAmB,KAAK;AAAA,IACrC;AAEA,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,cAAc;AAC1C,sBAAgB,SAAS;AAEzB,eAAS,cAAc,KAAK,YAAY,KAAK,UAAU;AAAA,IACzD;AAEA,QAAI,KAAK,YAAY;AACnB,eAAS,WAAW;AAAA,IACtB;AAEA,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,UAAU;AAGhE,QAAI,KAAK;AAAO,eAAS,MAAM,SAAS,gBAAgB,SAAS,gBAAgB,SAAS,gBAAgB;AAC1G,aAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAEvC,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,gBAAgB,aAAa;AAAA,IAC3D;AAEI,QAAA,KAAK,qBAAqB,QAAW;AACvC,WAAK,MAAM,mBAAmB;AAAA,IAChC;AAEA,aAAS,YAAY;AAAA,EACvB;AACF;;"}
+14
View File
@@ -0,0 +1,14 @@
import { Camera, Color, Material, Scene, WebGLRenderTarget, WebGLRenderer } from 'three';
import { Pass } from './Pass';
declare class RenderPass extends Pass {
scene: Scene;
camera: Camera;
overrideMaterial: Material | undefined;
clearColor: Color | undefined;
clearAlpha: number;
clearDepth: boolean;
private _oldClearColor;
constructor(scene: Scene, camera: Camera, overrideMaterial?: Material, clearColor?: Color, clearAlpha?: number);
render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget): void;
}
export { RenderPass };
+60
View File
@@ -0,0 +1,60 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Color } from "three";
import { Pass } from "./Pass.js";
class RenderPass extends Pass {
constructor(scene, camera, overrideMaterial, clearColor, clearAlpha = 0) {
super();
__publicField(this, "scene");
__publicField(this, "camera");
__publicField(this, "overrideMaterial");
__publicField(this, "clearColor");
__publicField(this, "clearAlpha");
__publicField(this, "clearDepth", false);
__publicField(this, "_oldClearColor", new Color());
this.scene = scene;
this.camera = camera;
this.overrideMaterial = overrideMaterial;
this.clearColor = clearColor;
this.clearAlpha = clearAlpha;
this.clear = true;
this.needsSwap = false;
}
render(renderer, writeBuffer, readBuffer) {
let oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
let oldClearAlpha;
let oldOverrideMaterial = null;
if (this.overrideMaterial !== void 0) {
oldOverrideMaterial = this.scene.overrideMaterial;
this.scene.overrideMaterial = this.overrideMaterial;
}
if (this.clearColor) {
renderer.getClearColor(this._oldClearColor);
oldClearAlpha = renderer.getClearAlpha();
renderer.setClearColor(this.clearColor, this.clearAlpha);
}
if (this.clearDepth) {
renderer.clearDepth();
}
renderer.setRenderTarget(this.renderToScreen ? null : readBuffer);
if (this.clear)
renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil);
renderer.render(this.scene, this.camera);
if (this.clearColor) {
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
}
if (this.overrideMaterial !== void 0) {
this.scene.overrideMaterial = oldOverrideMaterial;
}
renderer.autoClear = oldAutoClear;
}
}
export {
RenderPass
};
//# sourceMappingURL=RenderPass.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"RenderPass.js","sources":["../../src/postprocessing/RenderPass.ts"],"sourcesContent":["import { Camera, Color, Material, Scene, WebGLRenderTarget, WebGLRenderer } from 'three'\nimport { Pass } from './Pass'\n\nclass RenderPass extends Pass {\n public scene: Scene\n public camera: Camera\n public overrideMaterial: Material | undefined\n public clearColor: Color | undefined\n public clearAlpha: number\n public clearDepth = false\n private _oldClearColor = new Color()\n\n constructor(scene: Scene, camera: Camera, overrideMaterial?: Material, clearColor?: Color, clearAlpha = 0) {\n super()\n\n this.scene = scene\n this.camera = camera\n\n this.overrideMaterial = overrideMaterial\n\n this.clearColor = clearColor\n this.clearAlpha = clearAlpha\n\n this.clear = true\n this.needsSwap = false\n }\n\n public render(\n renderer: WebGLRenderer,\n writeBuffer: WebGLRenderTarget,\n readBuffer: WebGLRenderTarget /*, deltaTime, maskActive */,\n ): void {\n let oldAutoClear = renderer.autoClear\n renderer.autoClear = false\n\n let oldClearAlpha\n let oldOverrideMaterial: Material | null = null\n\n if (this.overrideMaterial !== undefined) {\n oldOverrideMaterial = this.scene.overrideMaterial\n\n this.scene.overrideMaterial = this.overrideMaterial\n }\n\n if (this.clearColor) {\n renderer.getClearColor(this._oldClearColor)\n oldClearAlpha = renderer.getClearAlpha()\n\n renderer.setClearColor(this.clearColor, this.clearAlpha)\n }\n\n if (this.clearDepth) {\n renderer.clearDepth()\n }\n\n renderer.setRenderTarget(this.renderToScreen ? null : readBuffer)\n\n // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600\n if (this.clear) renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil)\n renderer.render(this.scene, this.camera)\n\n if (this.clearColor) {\n renderer.setClearColor(this._oldClearColor, oldClearAlpha)\n }\n\n if (this.overrideMaterial !== undefined) {\n this.scene.overrideMaterial = oldOverrideMaterial\n }\n\n renderer.autoClear = oldAutoClear\n }\n}\n\nexport { RenderPass }\n"],"names":[],"mappings":";;;;;;;;AAGA,MAAM,mBAAmB,KAAK;AAAA,EAS5B,YAAY,OAAc,QAAgB,kBAA6B,YAAoB,aAAa,GAAG;AACnG;AATD;AACA;AACA;AACA;AACA;AACA,sCAAa;AACZ,0CAAiB,IAAI;AAK3B,SAAK,QAAQ;AACb,SAAK,SAAS;AAEd,SAAK,mBAAmB;AAExB,SAAK,aAAa;AAClB,SAAK,aAAa;AAElB,SAAK,QAAQ;AACb,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,OACL,UACA,aACA,YACM;AACN,QAAI,eAAe,SAAS;AAC5B,aAAS,YAAY;AAEjB,QAAA;AACJ,QAAI,sBAAuC;AAEvC,QAAA,KAAK,qBAAqB,QAAW;AACvC,4BAAsB,KAAK,MAAM;AAE5B,WAAA,MAAM,mBAAmB,KAAK;AAAA,IACrC;AAEA,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,cAAc;AAC1C,sBAAgB,SAAS;AAEzB,eAAS,cAAc,KAAK,YAAY,KAAK,UAAU;AAAA,IACzD;AAEA,QAAI,KAAK,YAAY;AACnB,eAAS,WAAW;AAAA,IACtB;AAEA,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,UAAU;AAGhE,QAAI,KAAK;AAAO,eAAS,MAAM,SAAS,gBAAgB,SAAS,gBAAgB,SAAS,gBAAgB;AAC1G,aAAS,OAAO,KAAK,OAAO,KAAK,MAAM;AAEvC,QAAI,KAAK,YAAY;AACV,eAAA,cAAc,KAAK,gBAAgB,aAAa;AAAA,IAC3D;AAEI,QAAA,KAAK,qBAAqB,QAAW;AACvC,WAAK,MAAM,mBAAmB;AAAA,IAChC;AAEA,aAAS,YAAY;AAAA,EACvB;AACF;"}
+200
View File
@@ -0,0 +1,200 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
class RenderPixelatedPass extends Pass.Pass {
constructor(resolution, pixelSize, scene, camera, options = {}) {
var _a, _b;
super();
this.pixelSize = pixelSize;
this.resolution = new THREE.Vector2();
this.renderResolution = new THREE.Vector2();
this.setSize(resolution.x, resolution.y);
this.fsQuad = new Pass.FullScreenQuad(this.material());
this.scene = scene;
this.camera = camera;
this.normalEdgeStrength = (_a = options.normalEdgeStrength) != null ? _a : 0.3;
this.depthEdgeStrength = (_b = options.depthEdgeStrength) != null ? _b : 0.4;
this.rgbRenderTarget = pixelRenderTarget(this.renderResolution, THREE.RGBAFormat, true);
this.normalRenderTarget = pixelRenderTarget(this.renderResolution, THREE.RGBAFormat, false);
this.normalMaterial = new THREE.MeshNormalMaterial();
}
dispose() {
this.rgbRenderTarget.dispose();
this.normalRenderTarget.dispose();
this.fsQuad.dispose();
}
setSize(width, height) {
var _a, _b, _c;
this.resolution.set(width, height);
this.renderResolution.set(width / this.pixelSize | 0, height / this.pixelSize | 0);
const { x, y } = this.renderResolution;
(_a = this.rgbRenderTarget) == null ? void 0 : _a.setSize(x, y);
(_b = this.normalRenderTarget) == null ? void 0 : _b.setSize(x, y);
(_c = this.fsQuad) == null ? void 0 : _c.material.uniforms.resolution.value.set(x, y, 1 / x, 1 / y);
}
setPixelSize(pixelSize) {
this.pixelSize = pixelSize;
this.setSize(this.resolution.x, this.resolution.y);
}
render(renderer, writeBuffer) {
const uniforms = this.fsQuad.material.uniforms;
uniforms.normalEdgeStrength.value = this.normalEdgeStrength;
uniforms.depthEdgeStrength.value = this.depthEdgeStrength;
renderer.setRenderTarget(this.rgbRenderTarget);
renderer.render(this.scene, this.camera);
const overrideMaterial_old = this.scene.overrideMaterial;
renderer.setRenderTarget(this.normalRenderTarget);
this.scene.overrideMaterial = this.normalMaterial;
renderer.render(this.scene, this.camera);
this.scene.overrideMaterial = overrideMaterial_old;
uniforms.tDiffuse.value = this.rgbRenderTarget.texture;
uniforms.tDepth.value = this.rgbRenderTarget.depthTexture;
uniforms.tNormal.value = this.normalRenderTarget.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
}
this.fsQuad.render(renderer);
}
material() {
return new THREE.ShaderMaterial({
uniforms: {
tDiffuse: { value: null },
tDepth: { value: null },
tNormal: { value: null },
resolution: {
value: new THREE.Vector4(
this.renderResolution.x,
this.renderResolution.y,
1 / this.renderResolution.x,
1 / this.renderResolution.y
)
},
normalEdgeStrength: { value: 0 },
depthEdgeStrength: { value: 0 }
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`,
fragmentShader: `
uniform sampler2D tDiffuse;
uniform sampler2D tDepth;
uniform sampler2D tNormal;
uniform vec4 resolution;
uniform float normalEdgeStrength;
uniform float depthEdgeStrength;
varying vec2 vUv;
float getDepth(int x, int y) {
return texture2D( tDepth, vUv + vec2(x, y) * resolution.zw ).r;
}
vec3 getNormal(int x, int y) {
return texture2D( tNormal, vUv + vec2(x, y) * resolution.zw ).rgb * 2.0 - 1.0;
}
float depthEdgeIndicator(float depth, vec3 normal) {
float diff = 0.0;
diff += clamp(getDepth(1, 0) - depth, 0.0, 1.0);
diff += clamp(getDepth(-1, 0) - depth, 0.0, 1.0);
diff += clamp(getDepth(0, 1) - depth, 0.0, 1.0);
diff += clamp(getDepth(0, -1) - depth, 0.0, 1.0);
return floor(smoothstep(0.01, 0.02, diff) * 2.) / 2.;
}
float neighborNormalEdgeIndicator(int x, int y, float depth, vec3 normal) {
float depthDiff = getDepth(x, y) - depth;
vec3 neighborNormal = getNormal(x, y);
// Edge pixels should yield to faces who's normals are closer to the bias normal.
vec3 normalEdgeBias = vec3(1., 1., 1.); // This should probably be a parameter.
float normalDiff = dot(normal - neighborNormal, normalEdgeBias);
float normalIndicator = clamp(smoothstep(-.01, .01, normalDiff), 0.0, 1.0);
// Only the shallower pixel should detect the normal edge.
float depthIndicator = clamp(sign(depthDiff * .25 + .0025), 0.0, 1.0);
return (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator;
}
float normalEdgeIndicator(float depth, vec3 normal) {
float indicator = 0.0;
indicator += neighborNormalEdgeIndicator(0, -1, depth, normal);
indicator += neighborNormalEdgeIndicator(0, 1, depth, normal);
indicator += neighborNormalEdgeIndicator(-1, 0, depth, normal);
indicator += neighborNormalEdgeIndicator(1, 0, depth, normal);
return step(0.1, indicator);
}
void main() {
vec4 texel = texture2D( tDiffuse, vUv );
float depth = 0.0;
vec3 normal = vec3(0.0);
if (depthEdgeStrength > 0.0 || normalEdgeStrength > 0.0) {
depth = getDepth(0, 0);
normal = getNormal(0, 0);
}
float dei = 0.0;
if (depthEdgeStrength > 0.0)
dei = depthEdgeIndicator(depth, normal);
float nei = 0.0;
if (normalEdgeStrength > 0.0)
nei = normalEdgeIndicator(depth, normal);
float Strength = dei > 0.0 ? (1.0 - depthEdgeStrength * dei) : (1.0 + normalEdgeStrength * nei);
gl_FragColor = texel * Strength;
}
`
});
}
}
function pixelRenderTarget(resolution, pixelFormat, useDepthTexture) {
const renderTarget = new THREE.WebGLRenderTarget(
resolution.x,
resolution.y,
!useDepthTexture ? void 0 : {
depthTexture: new THREE.DepthTexture(resolution.x, resolution.y),
depthBuffer: true
}
);
renderTarget.texture.format = pixelFormat;
renderTarget.texture.minFilter = THREE.NearestFilter;
renderTarget.texture.magFilter = THREE.NearestFilter;
renderTarget.texture.generateMipmaps = false;
renderTarget.stencilBuffer = false;
return renderTarget;
}
exports.RenderPixelatedPass = RenderPixelatedPass;
//# sourceMappingURL=RenderPixelatedPass.cjs.map
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
import { Scene, Camera, ShaderMaterial, Vector2, MeshNormalMaterial, WebGLRenderTarget } from 'three'
import { Pass, FullScreenQuad } from './Pass'
export interface RenderPixelatedPassParameters {
normalEdgeStrength?: number
depthEdgeStrength?: number
}
export class RenderPixelatedPass extends Pass {
constructor(
resolution: Vector2,
pixelSize: number,
scene: Scene,
camera: Camera,
options?: RenderPixelatedPassParameters,
)
pixelSize: number
resolution: Vector2
renderResolution: Vector2
pixelatedMaterial: ShaderMaterial
normalMaterial: MeshNormalMaterial
fsQuad: FullScreenQuad
scene: Scene
camera: Camera
normalEdgeStrength: RenderPixelatedPassParameters['normalEdgeStrength']
depthEdgeStrength: RenderPixelatedPassParameters['depthEdgeStrength']
rgbRenderTarget: WebGLRenderTarget
normalRenderTarget: WebGLRenderTarget
}
+200
View File
@@ -0,0 +1,200 @@
import { Vector2, MeshNormalMaterial, ShaderMaterial, Vector4, WebGLRenderTarget, DepthTexture, NearestFilter, RGBAFormat } from "three";
import { Pass, FullScreenQuad } from "./Pass.js";
class RenderPixelatedPass extends Pass {
constructor(resolution, pixelSize, scene, camera, options = {}) {
var _a, _b;
super();
this.pixelSize = pixelSize;
this.resolution = new Vector2();
this.renderResolution = new Vector2();
this.setSize(resolution.x, resolution.y);
this.fsQuad = new FullScreenQuad(this.material());
this.scene = scene;
this.camera = camera;
this.normalEdgeStrength = (_a = options.normalEdgeStrength) != null ? _a : 0.3;
this.depthEdgeStrength = (_b = options.depthEdgeStrength) != null ? _b : 0.4;
this.rgbRenderTarget = pixelRenderTarget(this.renderResolution, RGBAFormat, true);
this.normalRenderTarget = pixelRenderTarget(this.renderResolution, RGBAFormat, false);
this.normalMaterial = new MeshNormalMaterial();
}
dispose() {
this.rgbRenderTarget.dispose();
this.normalRenderTarget.dispose();
this.fsQuad.dispose();
}
setSize(width, height) {
var _a, _b, _c;
this.resolution.set(width, height);
this.renderResolution.set(width / this.pixelSize | 0, height / this.pixelSize | 0);
const { x, y } = this.renderResolution;
(_a = this.rgbRenderTarget) == null ? void 0 : _a.setSize(x, y);
(_b = this.normalRenderTarget) == null ? void 0 : _b.setSize(x, y);
(_c = this.fsQuad) == null ? void 0 : _c.material.uniforms.resolution.value.set(x, y, 1 / x, 1 / y);
}
setPixelSize(pixelSize) {
this.pixelSize = pixelSize;
this.setSize(this.resolution.x, this.resolution.y);
}
render(renderer, writeBuffer) {
const uniforms = this.fsQuad.material.uniforms;
uniforms.normalEdgeStrength.value = this.normalEdgeStrength;
uniforms.depthEdgeStrength.value = this.depthEdgeStrength;
renderer.setRenderTarget(this.rgbRenderTarget);
renderer.render(this.scene, this.camera);
const overrideMaterial_old = this.scene.overrideMaterial;
renderer.setRenderTarget(this.normalRenderTarget);
this.scene.overrideMaterial = this.normalMaterial;
renderer.render(this.scene, this.camera);
this.scene.overrideMaterial = overrideMaterial_old;
uniforms.tDiffuse.value = this.rgbRenderTarget.texture;
uniforms.tDepth.value = this.rgbRenderTarget.depthTexture;
uniforms.tNormal.value = this.normalRenderTarget.texture;
if (this.renderToScreen) {
renderer.setRenderTarget(null);
} else {
renderer.setRenderTarget(writeBuffer);
if (this.clear)
renderer.clear();
}
this.fsQuad.render(renderer);
}
material() {
return new ShaderMaterial({
uniforms: {
tDiffuse: { value: null },
tDepth: { value: null },
tNormal: { value: null },
resolution: {
value: new Vector4(
this.renderResolution.x,
this.renderResolution.y,
1 / this.renderResolution.x,
1 / this.renderResolution.y
)
},
normalEdgeStrength: { value: 0 },
depthEdgeStrength: { value: 0 }
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`,
fragmentShader: `
uniform sampler2D tDiffuse;
uniform sampler2D tDepth;
uniform sampler2D tNormal;
uniform vec4 resolution;
uniform float normalEdgeStrength;
uniform float depthEdgeStrength;
varying vec2 vUv;
float getDepth(int x, int y) {
return texture2D( tDepth, vUv + vec2(x, y) * resolution.zw ).r;
}
vec3 getNormal(int x, int y) {
return texture2D( tNormal, vUv + vec2(x, y) * resolution.zw ).rgb * 2.0 - 1.0;
}
float depthEdgeIndicator(float depth, vec3 normal) {
float diff = 0.0;
diff += clamp(getDepth(1, 0) - depth, 0.0, 1.0);
diff += clamp(getDepth(-1, 0) - depth, 0.0, 1.0);
diff += clamp(getDepth(0, 1) - depth, 0.0, 1.0);
diff += clamp(getDepth(0, -1) - depth, 0.0, 1.0);
return floor(smoothstep(0.01, 0.02, diff) * 2.) / 2.;
}
float neighborNormalEdgeIndicator(int x, int y, float depth, vec3 normal) {
float depthDiff = getDepth(x, y) - depth;
vec3 neighborNormal = getNormal(x, y);
// Edge pixels should yield to faces who's normals are closer to the bias normal.
vec3 normalEdgeBias = vec3(1., 1., 1.); // This should probably be a parameter.
float normalDiff = dot(normal - neighborNormal, normalEdgeBias);
float normalIndicator = clamp(smoothstep(-.01, .01, normalDiff), 0.0, 1.0);
// Only the shallower pixel should detect the normal edge.
float depthIndicator = clamp(sign(depthDiff * .25 + .0025), 0.0, 1.0);
return (1.0 - dot(normal, neighborNormal)) * depthIndicator * normalIndicator;
}
float normalEdgeIndicator(float depth, vec3 normal) {
float indicator = 0.0;
indicator += neighborNormalEdgeIndicator(0, -1, depth, normal);
indicator += neighborNormalEdgeIndicator(0, 1, depth, normal);
indicator += neighborNormalEdgeIndicator(-1, 0, depth, normal);
indicator += neighborNormalEdgeIndicator(1, 0, depth, normal);
return step(0.1, indicator);
}
void main() {
vec4 texel = texture2D( tDiffuse, vUv );
float depth = 0.0;
vec3 normal = vec3(0.0);
if (depthEdgeStrength > 0.0 || normalEdgeStrength > 0.0) {
depth = getDepth(0, 0);
normal = getNormal(0, 0);
}
float dei = 0.0;
if (depthEdgeStrength > 0.0)
dei = depthEdgeIndicator(depth, normal);
float nei = 0.0;
if (normalEdgeStrength > 0.0)
nei = normalEdgeIndicator(depth, normal);
float Strength = dei > 0.0 ? (1.0 - depthEdgeStrength * dei) : (1.0 + normalEdgeStrength * nei);
gl_FragColor = texel * Strength;
}
`
});
}
}
function pixelRenderTarget(resolution, pixelFormat, useDepthTexture) {
const renderTarget = new WebGLRenderTarget(
resolution.x,
resolution.y,
!useDepthTexture ? void 0 : {
depthTexture: new DepthTexture(resolution.x, resolution.y),
depthBuffer: true
}
);
renderTarget.texture.format = pixelFormat;
renderTarget.texture.minFilter = NearestFilter;
renderTarget.texture.magFilter = NearestFilter;
renderTarget.texture.generateMipmaps = false;
renderTarget.stencilBuffer = false;
return renderTarget;
}
export {
RenderPixelatedPass
};
//# sourceMappingURL=RenderPixelatedPass.js.map
File diff suppressed because one or more lines are too long
+292
View File
@@ -0,0 +1,292 @@
"use strict";
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
const SAOShader = require("../shaders/SAOShader.cjs");
const DepthLimitedBlurShader = require("../shaders/DepthLimitedBlurShader.cjs");
const CopyShader = require("../shaders/CopyShader.cjs");
const UnpackDepthRGBAShader = require("../shaders/UnpackDepthRGBAShader.cjs");
const SAOPass = /* @__PURE__ */ (() => {
class SAOPass2 extends Pass.Pass {
constructor(scene, camera, useDepthTexture = false, useNormals = false, resolution = new THREE.Vector2(256, 256)) {
super();
this.scene = scene;
this.camera = camera;
this.clear = true;
this.needsSwap = false;
this.supportsDepthTextureExtension = useDepthTexture;
this.supportsNormalTexture = useNormals;
this.originalClearColor = new THREE.Color();
this._oldClearColor = new THREE.Color();
this.oldClearAlpha = 1;
this.params = {
output: 0,
saoBias: 0.5,
saoIntensity: 0.18,
saoScale: 1,
saoKernelRadius: 100,
saoMinResolution: 0,
saoBlur: true,
saoBlurRadius: 8,
saoBlurStdDev: 4,
saoBlurDepthCutoff: 0.01
};
this.resolution = new THREE.Vector2(resolution.x, resolution.y);
this.saoRenderTarget = new THREE.WebGLRenderTarget(this.resolution.x, this.resolution.y, { type: THREE.HalfFloatType });
this.blurIntermediateRenderTarget = this.saoRenderTarget.clone();
this.beautyRenderTarget = this.saoRenderTarget.clone();
this.normalRenderTarget = new THREE.WebGLRenderTarget(this.resolution.x, this.resolution.y, {
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
type: THREE.HalfFloatType
});
this.depthRenderTarget = this.normalRenderTarget.clone();
let depthTexture;
if (this.supportsDepthTextureExtension) {
depthTexture = new THREE.DepthTexture();
depthTexture.type = THREE.UnsignedShortType;
this.beautyRenderTarget.depthTexture = depthTexture;
this.beautyRenderTarget.depthBuffer = true;
}
this.depthMaterial = new THREE.MeshDepthMaterial();
this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
this.depthMaterial.blending = THREE.NoBlending;
this.normalMaterial = new THREE.MeshNormalMaterial();
this.normalMaterial.blending = THREE.NoBlending;
this.saoMaterial = new THREE.ShaderMaterial({
defines: Object.assign({}, SAOShader.SAOShader.defines),
fragmentShader: SAOShader.SAOShader.fragmentShader,
vertexShader: SAOShader.SAOShader.vertexShader,
uniforms: THREE.UniformsUtils.clone(SAOShader.SAOShader.uniforms)
});
this.saoMaterial.extensions.derivatives = true;
this.saoMaterial.defines["DEPTH_PACKING"] = this.supportsDepthTextureExtension ? 0 : 1;
this.saoMaterial.defines["NORMAL_TEXTURE"] = this.supportsNormalTexture ? 1 : 0;
this.saoMaterial.defines["PERSPECTIVE_CAMERA"] = this.camera.isPerspectiveCamera ? 1 : 0;
this.saoMaterial.uniforms["tDepth"].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
this.saoMaterial.uniforms["tNormal"].value = this.normalRenderTarget.texture;
this.saoMaterial.uniforms["size"].value.set(this.resolution.x, this.resolution.y);
this.saoMaterial.uniforms["cameraInverseProjectionMatrix"].value.copy(this.camera.projectionMatrixInverse);
this.saoMaterial.uniforms["cameraProjectionMatrix"].value = this.camera.projectionMatrix;
this.saoMaterial.blending = THREE.NoBlending;
this.vBlurMaterial = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(DepthLimitedBlurShader.DepthLimitedBlurShader.uniforms),
defines: Object.assign({}, DepthLimitedBlurShader.DepthLimitedBlurShader.defines),
vertexShader: DepthLimitedBlurShader.DepthLimitedBlurShader.vertexShader,
fragmentShader: DepthLimitedBlurShader.DepthLimitedBlurShader.fragmentShader
});
this.vBlurMaterial.defines["DEPTH_PACKING"] = this.supportsDepthTextureExtension ? 0 : 1;
this.vBlurMaterial.defines["PERSPECTIVE_CAMERA"] = this.camera.isPerspectiveCamera ? 1 : 0;
this.vBlurMaterial.uniforms["tDiffuse"].value = this.saoRenderTarget.texture;
this.vBlurMaterial.uniforms["tDepth"].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
this.vBlurMaterial.uniforms["size"].value.set(this.resolution.x, this.resolution.y);
this.vBlurMaterial.blending = THREE.NoBlending;
this.hBlurMaterial = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(DepthLimitedBlurShader.DepthLimitedBlurShader.uniforms),
defines: Object.assign({}, DepthLimitedBlurShader.DepthLimitedBlurShader.defines),
vertexShader: DepthLimitedBlurShader.DepthLimitedBlurShader.vertexShader,
fragmentShader: DepthLimitedBlurShader.DepthLimitedBlurShader.fragmentShader
});
this.hBlurMaterial.defines["DEPTH_PACKING"] = this.supportsDepthTextureExtension ? 0 : 1;
this.hBlurMaterial.defines["PERSPECTIVE_CAMERA"] = this.camera.isPerspectiveCamera ? 1 : 0;
this.hBlurMaterial.uniforms["tDiffuse"].value = this.blurIntermediateRenderTarget.texture;
this.hBlurMaterial.uniforms["tDepth"].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
this.hBlurMaterial.uniforms["size"].value.set(this.resolution.x, this.resolution.y);
this.hBlurMaterial.blending = THREE.NoBlending;
this.materialCopy = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(CopyShader.CopyShader.uniforms),
vertexShader: CopyShader.CopyShader.vertexShader,
fragmentShader: CopyShader.CopyShader.fragmentShader,
blending: THREE.NoBlending
});
this.materialCopy.transparent = true;
this.materialCopy.depthTest = false;
this.materialCopy.depthWrite = false;
this.materialCopy.blending = THREE.CustomBlending;
this.materialCopy.blendSrc = THREE.DstColorFactor;
this.materialCopy.blendDst = THREE.ZeroFactor;
this.materialCopy.blendEquation = THREE.AddEquation;
this.materialCopy.blendSrcAlpha = THREE.DstAlphaFactor;
this.materialCopy.blendDstAlpha = THREE.ZeroFactor;
this.materialCopy.blendEquationAlpha = THREE.AddEquation;
this.depthCopy = new THREE.ShaderMaterial({
uniforms: THREE.UniformsUtils.clone(UnpackDepthRGBAShader.UnpackDepthRGBAShader.uniforms),
vertexShader: UnpackDepthRGBAShader.UnpackDepthRGBAShader.vertexShader,
fragmentShader: UnpackDepthRGBAShader.UnpackDepthRGBAShader.fragmentShader,
blending: THREE.NoBlending
});
this.fsQuad = new Pass.FullScreenQuad(null);
}
render(renderer, writeBuffer, readBuffer) {
if (this.renderToScreen) {
this.materialCopy.blending = THREE.NoBlending;
this.materialCopy.uniforms["tDiffuse"].value = readBuffer.texture;
this.materialCopy.needsUpdate = true;
this.renderPass(renderer, this.materialCopy, null);
}
if (this.params.output === 1) {
return;
}
renderer.getClearColor(this._oldClearColor);
this.oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.setRenderTarget(this.depthRenderTarget);
renderer.clear();
this.saoMaterial.uniforms["bias"].value = this.params.saoBias;
this.saoMaterial.uniforms["intensity"].value = this.params.saoIntensity;
this.saoMaterial.uniforms["scale"].value = this.params.saoScale;
this.saoMaterial.uniforms["kernelRadius"].value = this.params.saoKernelRadius;
this.saoMaterial.uniforms["minResolution"].value = this.params.saoMinResolution;
this.saoMaterial.uniforms["cameraNear"].value = this.camera.near;
this.saoMaterial.uniforms["cameraFar"].value = this.camera.far;
const depthCutoff = this.params.saoBlurDepthCutoff * (this.camera.far - this.camera.near);
this.vBlurMaterial.uniforms["depthCutoff"].value = depthCutoff;
this.hBlurMaterial.uniforms["depthCutoff"].value = depthCutoff;
this.vBlurMaterial.uniforms["cameraNear"].value = this.camera.near;
this.vBlurMaterial.uniforms["cameraFar"].value = this.camera.far;
this.hBlurMaterial.uniforms["cameraNear"].value = this.camera.near;
this.hBlurMaterial.uniforms["cameraFar"].value = this.camera.far;
this.params.saoBlurRadius = Math.floor(this.params.saoBlurRadius);
if (this.prevStdDev !== this.params.saoBlurStdDev || this.prevNumSamples !== this.params.saoBlurRadius) {
DepthLimitedBlurShader.BlurShaderUtils.configure(
this.vBlurMaterial,
this.params.saoBlurRadius,
this.params.saoBlurStdDev,
new THREE.Vector2(0, 1)
);
DepthLimitedBlurShader.BlurShaderUtils.configure(
this.hBlurMaterial,
this.params.saoBlurRadius,
this.params.saoBlurStdDev,
new THREE.Vector2(1, 0)
);
this.prevStdDev = this.params.saoBlurStdDev;
this.prevNumSamples = this.params.saoBlurRadius;
}
renderer.setClearColor(0);
renderer.setRenderTarget(this.beautyRenderTarget);
renderer.clear();
renderer.render(this.scene, this.camera);
if (!this.supportsDepthTextureExtension) {
this.renderOverride(renderer, this.depthMaterial, this.depthRenderTarget, 0, 1);
}
if (this.supportsNormalTexture) {
this.renderOverride(renderer, this.normalMaterial, this.normalRenderTarget, 7829503, 1);
}
this.renderPass(renderer, this.saoMaterial, this.saoRenderTarget, 16777215, 1);
if (this.params.saoBlur) {
this.renderPass(renderer, this.vBlurMaterial, this.blurIntermediateRenderTarget, 16777215, 1);
this.renderPass(renderer, this.hBlurMaterial, this.saoRenderTarget, 16777215, 1);
}
let outputMaterial = this.materialCopy;
if (this.params.output === 3) {
if (this.supportsDepthTextureExtension) {
this.materialCopy.uniforms["tDiffuse"].value = this.beautyRenderTarget.depthTexture;
this.materialCopy.needsUpdate = true;
} else {
this.depthCopy.uniforms["tDiffuse"].value = this.depthRenderTarget.texture;
this.depthCopy.needsUpdate = true;
outputMaterial = this.depthCopy;
}
} else if (this.params.output === 4) {
this.materialCopy.uniforms["tDiffuse"].value = this.normalRenderTarget.texture;
this.materialCopy.needsUpdate = true;
} else {
this.materialCopy.uniforms["tDiffuse"].value = this.saoRenderTarget.texture;
this.materialCopy.needsUpdate = true;
}
if (this.params.output === 0) {
outputMaterial.blending = THREE.CustomBlending;
} else {
outputMaterial.blending = THREE.NoBlending;
}
this.renderPass(renderer, outputMaterial, this.renderToScreen ? null : readBuffer);
renderer.setClearColor(this._oldClearColor, this.oldClearAlpha);
renderer.autoClear = oldAutoClear;
}
renderPass(renderer, passMaterial, renderTarget, clearColor, clearAlpha) {
renderer.getClearColor(this.originalClearColor);
const originalClearAlpha = renderer.getClearAlpha();
const originalAutoClear = renderer.autoClear;
renderer.setRenderTarget(renderTarget);
renderer.autoClear = false;
if (clearColor !== void 0 && clearColor !== null) {
renderer.setClearColor(clearColor);
renderer.setClearAlpha(clearAlpha || 0);
renderer.clear();
}
this.fsQuad.material = passMaterial;
this.fsQuad.render(renderer);
renderer.autoClear = originalAutoClear;
renderer.setClearColor(this.originalClearColor);
renderer.setClearAlpha(originalClearAlpha);
}
renderOverride(renderer, overrideMaterial, renderTarget, clearColor, clearAlpha) {
renderer.getClearColor(this.originalClearColor);
const originalClearAlpha = renderer.getClearAlpha();
const originalAutoClear = renderer.autoClear;
renderer.setRenderTarget(renderTarget);
renderer.autoClear = false;
clearColor = overrideMaterial.clearColor || clearColor;
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
if (clearColor !== void 0 && clearColor !== null) {
renderer.setClearColor(clearColor);
renderer.setClearAlpha(clearAlpha || 0);
renderer.clear();
}
this.scene.overrideMaterial = overrideMaterial;
renderer.render(this.scene, this.camera);
this.scene.overrideMaterial = null;
renderer.autoClear = originalAutoClear;
renderer.setClearColor(this.originalClearColor);
renderer.setClearAlpha(originalClearAlpha);
}
setSize(width, height) {
this.beautyRenderTarget.setSize(width, height);
this.saoRenderTarget.setSize(width, height);
this.blurIntermediateRenderTarget.setSize(width, height);
this.normalRenderTarget.setSize(width, height);
this.depthRenderTarget.setSize(width, height);
this.saoMaterial.uniforms["size"].value.set(width, height);
this.saoMaterial.uniforms["cameraInverseProjectionMatrix"].value.copy(this.camera.projectionMatrixInverse);
this.saoMaterial.uniforms["cameraProjectionMatrix"].value = this.camera.projectionMatrix;
this.saoMaterial.needsUpdate = true;
this.vBlurMaterial.uniforms["size"].value.set(width, height);
this.vBlurMaterial.needsUpdate = true;
this.hBlurMaterial.uniforms["size"].value.set(width, height);
this.hBlurMaterial.needsUpdate = true;
}
dispose() {
this.saoRenderTarget.dispose();
this.blurIntermediateRenderTarget.dispose();
this.beautyRenderTarget.dispose();
this.normalRenderTarget.dispose();
this.depthRenderTarget.dispose();
this.depthMaterial.dispose();
this.normalMaterial.dispose();
this.saoMaterial.dispose();
this.vBlurMaterial.dispose();
this.hBlurMaterial.dispose();
this.materialCopy.dispose();
this.depthCopy.dispose();
this.fsQuad.dispose();
}
}
__publicField(SAOPass2, "OUTPUT", {
Beauty: 1,
Default: 0,
SAO: 2,
Depth: 3,
Normal: 4
});
return SAOPass2;
})();
exports.SAOPass = SAOPass;
//# sourceMappingURL=SAOPass.cjs.map
File diff suppressed because one or more lines are too long
+78
View File
@@ -0,0 +1,78 @@
import {
Scene,
Camera,
Material,
MeshDepthMaterial,
MeshNormalMaterial,
ShaderMaterial,
Color,
Vector2,
WebGLRenderer,
WebGLRenderTarget,
} from 'three'
import { Pass, FullScreenQuad } from './Pass'
export enum OUTPUT {
Beauty,
Default,
SAO,
Depth,
Normal,
}
export interface SAOPassParams {
output: OUTPUT
saoBias: number
saoIntensity: number
saoScale: number
saoKernelRadius: number
saoMinResolution: number
saoBlur: boolean
saoBlurRadius: number
saoBlurStdDev: number
saoBlurDepthCutoff: number
}
export class SAOPass extends Pass {
constructor(scene: Scene, camera: Camera, depthTexture?: boolean, useNormals?: boolean, resolution?: Vector2)
scene: Scene
camera: Camera
supportsDepthTextureExtension: boolean
supportsNormalTexture: boolean
originalClearColor: Color
oldClearColor: Color
oldClearAlpha: number
resolution: Vector2
saoRenderTarget: WebGLRenderTarget
blurIntermediateRenderTarget: WebGLRenderTarget
beautyRenderTarget: WebGLRenderTarget
normalRenderTarget: WebGLRenderTarget
depthRenderTarget: WebGLRenderTarget
depthMaterial: MeshDepthMaterial
normalMaterial: MeshNormalMaterial
saoMaterial: ShaderMaterial
vBlurMaterial: ShaderMaterial
hBlurMaterial: ShaderMaterial
materialCopy: ShaderMaterial
depthCopy: ShaderMaterial
fsQuad: FullScreenQuad
params: SAOPassParams
static OUTPUT: typeof OUTPUT
renderPass(
renderer: WebGLRenderer,
passMaterial: Material,
renderTarget: WebGLRenderTarget,
clearColor?: Color | string | number,
clearAlpha?: number,
): void
renderOverride(
renderer: WebGLRenderer,
overrideMaterial: Material,
renderTarget: WebGLRenderTarget,
clearColor?: Color | string | number,
clearAlpha?: number,
): void
}
+292
View File
@@ -0,0 +1,292 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
import { Color, Vector2, WebGLRenderTarget, HalfFloatType, NearestFilter, DepthTexture, UnsignedShortType, MeshDepthMaterial, RGBADepthPacking, NoBlending, MeshNormalMaterial, ShaderMaterial, UniformsUtils, CustomBlending, DstColorFactor, ZeroFactor, AddEquation, DstAlphaFactor } from "three";
import { Pass, FullScreenQuad } from "./Pass.js";
import { SAOShader } from "../shaders/SAOShader.js";
import { DepthLimitedBlurShader, BlurShaderUtils } from "../shaders/DepthLimitedBlurShader.js";
import { CopyShader } from "../shaders/CopyShader.js";
import { UnpackDepthRGBAShader } from "../shaders/UnpackDepthRGBAShader.js";
const SAOPass = /* @__PURE__ */ (() => {
class SAOPass2 extends Pass {
constructor(scene, camera, useDepthTexture = false, useNormals = false, resolution = new Vector2(256, 256)) {
super();
this.scene = scene;
this.camera = camera;
this.clear = true;
this.needsSwap = false;
this.supportsDepthTextureExtension = useDepthTexture;
this.supportsNormalTexture = useNormals;
this.originalClearColor = new Color();
this._oldClearColor = new Color();
this.oldClearAlpha = 1;
this.params = {
output: 0,
saoBias: 0.5,
saoIntensity: 0.18,
saoScale: 1,
saoKernelRadius: 100,
saoMinResolution: 0,
saoBlur: true,
saoBlurRadius: 8,
saoBlurStdDev: 4,
saoBlurDepthCutoff: 0.01
};
this.resolution = new Vector2(resolution.x, resolution.y);
this.saoRenderTarget = new WebGLRenderTarget(this.resolution.x, this.resolution.y, { type: HalfFloatType });
this.blurIntermediateRenderTarget = this.saoRenderTarget.clone();
this.beautyRenderTarget = this.saoRenderTarget.clone();
this.normalRenderTarget = new WebGLRenderTarget(this.resolution.x, this.resolution.y, {
minFilter: NearestFilter,
magFilter: NearestFilter,
type: HalfFloatType
});
this.depthRenderTarget = this.normalRenderTarget.clone();
let depthTexture;
if (this.supportsDepthTextureExtension) {
depthTexture = new DepthTexture();
depthTexture.type = UnsignedShortType;
this.beautyRenderTarget.depthTexture = depthTexture;
this.beautyRenderTarget.depthBuffer = true;
}
this.depthMaterial = new MeshDepthMaterial();
this.depthMaterial.depthPacking = RGBADepthPacking;
this.depthMaterial.blending = NoBlending;
this.normalMaterial = new MeshNormalMaterial();
this.normalMaterial.blending = NoBlending;
this.saoMaterial = new ShaderMaterial({
defines: Object.assign({}, SAOShader.defines),
fragmentShader: SAOShader.fragmentShader,
vertexShader: SAOShader.vertexShader,
uniforms: UniformsUtils.clone(SAOShader.uniforms)
});
this.saoMaterial.extensions.derivatives = true;
this.saoMaterial.defines["DEPTH_PACKING"] = this.supportsDepthTextureExtension ? 0 : 1;
this.saoMaterial.defines["NORMAL_TEXTURE"] = this.supportsNormalTexture ? 1 : 0;
this.saoMaterial.defines["PERSPECTIVE_CAMERA"] = this.camera.isPerspectiveCamera ? 1 : 0;
this.saoMaterial.uniforms["tDepth"].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
this.saoMaterial.uniforms["tNormal"].value = this.normalRenderTarget.texture;
this.saoMaterial.uniforms["size"].value.set(this.resolution.x, this.resolution.y);
this.saoMaterial.uniforms["cameraInverseProjectionMatrix"].value.copy(this.camera.projectionMatrixInverse);
this.saoMaterial.uniforms["cameraProjectionMatrix"].value = this.camera.projectionMatrix;
this.saoMaterial.blending = NoBlending;
this.vBlurMaterial = new ShaderMaterial({
uniforms: UniformsUtils.clone(DepthLimitedBlurShader.uniforms),
defines: Object.assign({}, DepthLimitedBlurShader.defines),
vertexShader: DepthLimitedBlurShader.vertexShader,
fragmentShader: DepthLimitedBlurShader.fragmentShader
});
this.vBlurMaterial.defines["DEPTH_PACKING"] = this.supportsDepthTextureExtension ? 0 : 1;
this.vBlurMaterial.defines["PERSPECTIVE_CAMERA"] = this.camera.isPerspectiveCamera ? 1 : 0;
this.vBlurMaterial.uniforms["tDiffuse"].value = this.saoRenderTarget.texture;
this.vBlurMaterial.uniforms["tDepth"].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
this.vBlurMaterial.uniforms["size"].value.set(this.resolution.x, this.resolution.y);
this.vBlurMaterial.blending = NoBlending;
this.hBlurMaterial = new ShaderMaterial({
uniforms: UniformsUtils.clone(DepthLimitedBlurShader.uniforms),
defines: Object.assign({}, DepthLimitedBlurShader.defines),
vertexShader: DepthLimitedBlurShader.vertexShader,
fragmentShader: DepthLimitedBlurShader.fragmentShader
});
this.hBlurMaterial.defines["DEPTH_PACKING"] = this.supportsDepthTextureExtension ? 0 : 1;
this.hBlurMaterial.defines["PERSPECTIVE_CAMERA"] = this.camera.isPerspectiveCamera ? 1 : 0;
this.hBlurMaterial.uniforms["tDiffuse"].value = this.blurIntermediateRenderTarget.texture;
this.hBlurMaterial.uniforms["tDepth"].value = this.supportsDepthTextureExtension ? depthTexture : this.depthRenderTarget.texture;
this.hBlurMaterial.uniforms["size"].value.set(this.resolution.x, this.resolution.y);
this.hBlurMaterial.blending = NoBlending;
this.materialCopy = new ShaderMaterial({
uniforms: UniformsUtils.clone(CopyShader.uniforms),
vertexShader: CopyShader.vertexShader,
fragmentShader: CopyShader.fragmentShader,
blending: NoBlending
});
this.materialCopy.transparent = true;
this.materialCopy.depthTest = false;
this.materialCopy.depthWrite = false;
this.materialCopy.blending = CustomBlending;
this.materialCopy.blendSrc = DstColorFactor;
this.materialCopy.blendDst = ZeroFactor;
this.materialCopy.blendEquation = AddEquation;
this.materialCopy.blendSrcAlpha = DstAlphaFactor;
this.materialCopy.blendDstAlpha = ZeroFactor;
this.materialCopy.blendEquationAlpha = AddEquation;
this.depthCopy = new ShaderMaterial({
uniforms: UniformsUtils.clone(UnpackDepthRGBAShader.uniforms),
vertexShader: UnpackDepthRGBAShader.vertexShader,
fragmentShader: UnpackDepthRGBAShader.fragmentShader,
blending: NoBlending
});
this.fsQuad = new FullScreenQuad(null);
}
render(renderer, writeBuffer, readBuffer) {
if (this.renderToScreen) {
this.materialCopy.blending = NoBlending;
this.materialCopy.uniforms["tDiffuse"].value = readBuffer.texture;
this.materialCopy.needsUpdate = true;
this.renderPass(renderer, this.materialCopy, null);
}
if (this.params.output === 1) {
return;
}
renderer.getClearColor(this._oldClearColor);
this.oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.setRenderTarget(this.depthRenderTarget);
renderer.clear();
this.saoMaterial.uniforms["bias"].value = this.params.saoBias;
this.saoMaterial.uniforms["intensity"].value = this.params.saoIntensity;
this.saoMaterial.uniforms["scale"].value = this.params.saoScale;
this.saoMaterial.uniforms["kernelRadius"].value = this.params.saoKernelRadius;
this.saoMaterial.uniforms["minResolution"].value = this.params.saoMinResolution;
this.saoMaterial.uniforms["cameraNear"].value = this.camera.near;
this.saoMaterial.uniforms["cameraFar"].value = this.camera.far;
const depthCutoff = this.params.saoBlurDepthCutoff * (this.camera.far - this.camera.near);
this.vBlurMaterial.uniforms["depthCutoff"].value = depthCutoff;
this.hBlurMaterial.uniforms["depthCutoff"].value = depthCutoff;
this.vBlurMaterial.uniforms["cameraNear"].value = this.camera.near;
this.vBlurMaterial.uniforms["cameraFar"].value = this.camera.far;
this.hBlurMaterial.uniforms["cameraNear"].value = this.camera.near;
this.hBlurMaterial.uniforms["cameraFar"].value = this.camera.far;
this.params.saoBlurRadius = Math.floor(this.params.saoBlurRadius);
if (this.prevStdDev !== this.params.saoBlurStdDev || this.prevNumSamples !== this.params.saoBlurRadius) {
BlurShaderUtils.configure(
this.vBlurMaterial,
this.params.saoBlurRadius,
this.params.saoBlurStdDev,
new Vector2(0, 1)
);
BlurShaderUtils.configure(
this.hBlurMaterial,
this.params.saoBlurRadius,
this.params.saoBlurStdDev,
new Vector2(1, 0)
);
this.prevStdDev = this.params.saoBlurStdDev;
this.prevNumSamples = this.params.saoBlurRadius;
}
renderer.setClearColor(0);
renderer.setRenderTarget(this.beautyRenderTarget);
renderer.clear();
renderer.render(this.scene, this.camera);
if (!this.supportsDepthTextureExtension) {
this.renderOverride(renderer, this.depthMaterial, this.depthRenderTarget, 0, 1);
}
if (this.supportsNormalTexture) {
this.renderOverride(renderer, this.normalMaterial, this.normalRenderTarget, 7829503, 1);
}
this.renderPass(renderer, this.saoMaterial, this.saoRenderTarget, 16777215, 1);
if (this.params.saoBlur) {
this.renderPass(renderer, this.vBlurMaterial, this.blurIntermediateRenderTarget, 16777215, 1);
this.renderPass(renderer, this.hBlurMaterial, this.saoRenderTarget, 16777215, 1);
}
let outputMaterial = this.materialCopy;
if (this.params.output === 3) {
if (this.supportsDepthTextureExtension) {
this.materialCopy.uniforms["tDiffuse"].value = this.beautyRenderTarget.depthTexture;
this.materialCopy.needsUpdate = true;
} else {
this.depthCopy.uniforms["tDiffuse"].value = this.depthRenderTarget.texture;
this.depthCopy.needsUpdate = true;
outputMaterial = this.depthCopy;
}
} else if (this.params.output === 4) {
this.materialCopy.uniforms["tDiffuse"].value = this.normalRenderTarget.texture;
this.materialCopy.needsUpdate = true;
} else {
this.materialCopy.uniforms["tDiffuse"].value = this.saoRenderTarget.texture;
this.materialCopy.needsUpdate = true;
}
if (this.params.output === 0) {
outputMaterial.blending = CustomBlending;
} else {
outputMaterial.blending = NoBlending;
}
this.renderPass(renderer, outputMaterial, this.renderToScreen ? null : readBuffer);
renderer.setClearColor(this._oldClearColor, this.oldClearAlpha);
renderer.autoClear = oldAutoClear;
}
renderPass(renderer, passMaterial, renderTarget, clearColor, clearAlpha) {
renderer.getClearColor(this.originalClearColor);
const originalClearAlpha = renderer.getClearAlpha();
const originalAutoClear = renderer.autoClear;
renderer.setRenderTarget(renderTarget);
renderer.autoClear = false;
if (clearColor !== void 0 && clearColor !== null) {
renderer.setClearColor(clearColor);
renderer.setClearAlpha(clearAlpha || 0);
renderer.clear();
}
this.fsQuad.material = passMaterial;
this.fsQuad.render(renderer);
renderer.autoClear = originalAutoClear;
renderer.setClearColor(this.originalClearColor);
renderer.setClearAlpha(originalClearAlpha);
}
renderOverride(renderer, overrideMaterial, renderTarget, clearColor, clearAlpha) {
renderer.getClearColor(this.originalClearColor);
const originalClearAlpha = renderer.getClearAlpha();
const originalAutoClear = renderer.autoClear;
renderer.setRenderTarget(renderTarget);
renderer.autoClear = false;
clearColor = overrideMaterial.clearColor || clearColor;
clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
if (clearColor !== void 0 && clearColor !== null) {
renderer.setClearColor(clearColor);
renderer.setClearAlpha(clearAlpha || 0);
renderer.clear();
}
this.scene.overrideMaterial = overrideMaterial;
renderer.render(this.scene, this.camera);
this.scene.overrideMaterial = null;
renderer.autoClear = originalAutoClear;
renderer.setClearColor(this.originalClearColor);
renderer.setClearAlpha(originalClearAlpha);
}
setSize(width, height) {
this.beautyRenderTarget.setSize(width, height);
this.saoRenderTarget.setSize(width, height);
this.blurIntermediateRenderTarget.setSize(width, height);
this.normalRenderTarget.setSize(width, height);
this.depthRenderTarget.setSize(width, height);
this.saoMaterial.uniforms["size"].value.set(width, height);
this.saoMaterial.uniforms["cameraInverseProjectionMatrix"].value.copy(this.camera.projectionMatrixInverse);
this.saoMaterial.uniforms["cameraProjectionMatrix"].value = this.camera.projectionMatrix;
this.saoMaterial.needsUpdate = true;
this.vBlurMaterial.uniforms["size"].value.set(width, height);
this.vBlurMaterial.needsUpdate = true;
this.hBlurMaterial.uniforms["size"].value.set(width, height);
this.hBlurMaterial.needsUpdate = true;
}
dispose() {
this.saoRenderTarget.dispose();
this.blurIntermediateRenderTarget.dispose();
this.beautyRenderTarget.dispose();
this.normalRenderTarget.dispose();
this.depthRenderTarget.dispose();
this.depthMaterial.dispose();
this.normalMaterial.dispose();
this.saoMaterial.dispose();
this.vBlurMaterial.dispose();
this.hBlurMaterial.dispose();
this.materialCopy.dispose();
this.depthCopy.dispose();
this.fsQuad.dispose();
}
}
__publicField(SAOPass2, "OUTPUT", {
Beauty: 1,
Default: 0,
SAO: 2,
Depth: 3,
Normal: 4
});
return SAOPass2;
})();
export {
SAOPass
};
//# sourceMappingURL=SAOPass.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+21
View File
@@ -0,0 +1,21 @@
import { ShaderMaterial, Texture, WebGLRenderTarget } from 'three'
import { Pass } from './Pass'
export class SMAAPass extends Pass {
constructor(width: number, height: number)
edgesRT: WebGLRenderTarget
weightsRT: WebGLRenderTarget
areaTexture: Texture
searchTexture: Texture
uniformsEdges: object
materialEdges: ShaderMaterial
uniformsWeights: object
materialWeights: ShaderMaterial
uniformsBlend: object
materialBlend: ShaderMaterial
fsQuad: object
getAreaTexture(): string
getSearchTexture(): string
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+190
View File
@@ -0,0 +1,190 @@
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const THREE = require("three");
const Pass = require("./Pass.cjs");
const CopyShader = require("../shaders/CopyShader.cjs");
class SSAARenderPass extends Pass.Pass {
constructor(scene, camera, clearColor, clearAlpha) {
super();
this.scene = scene;
this.camera = camera;
this.sampleLevel = 4;
this.unbiased = true;
this.clearColor = clearColor !== void 0 ? clearColor : 0;
this.clearAlpha = clearAlpha !== void 0 ? clearAlpha : 0;
this._oldClearColor = new THREE.Color();
const copyShader = CopyShader.CopyShader;
this.copyUniforms = THREE.UniformsUtils.clone(copyShader.uniforms);
this.copyMaterial = new THREE.ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
transparent: true,
depthTest: false,
depthWrite: false,
premultipliedAlpha: true,
blending: THREE.AdditiveBlending
});
this.fsQuad = new Pass.FullScreenQuad(this.copyMaterial);
}
dispose() {
if (this.sampleRenderTarget) {
this.sampleRenderTarget.dispose();
this.sampleRenderTarget = null;
}
this.copyMaterial.dispose();
this.fsQuad.dispose();
}
setSize(width, height) {
if (this.sampleRenderTarget)
this.sampleRenderTarget.setSize(width, height);
}
render(renderer, writeBuffer, readBuffer) {
if (!this.sampleRenderTarget) {
this.sampleRenderTarget = new THREE.WebGLRenderTarget(readBuffer.width, readBuffer.height, { type: THREE.HalfFloatType });
this.sampleRenderTarget.texture.name = "SSAARenderPass.sample";
}
const jitterOffsets = _JitterVectors[Math.max(0, Math.min(this.sampleLevel, 5))];
const autoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.getClearColor(this._oldClearColor);
const oldClearAlpha = renderer.getClearAlpha();
const baseSampleWeight = 1 / jitterOffsets.length;
const roundingRange = 1 / 32;
this.copyUniforms["tDiffuse"].value = this.sampleRenderTarget.texture;
const viewOffset = {
fullWidth: readBuffer.width,
fullHeight: readBuffer.height,
offsetX: 0,
offsetY: 0,
width: readBuffer.width,
height: readBuffer.height
};
const originalViewOffset = Object.assign({}, this.camera.view);
if (originalViewOffset.enabled)
Object.assign(viewOffset, originalViewOffset);
for (let i = 0; i < jitterOffsets.length; i++) {
const jitterOffset = jitterOffsets[i];
if (this.camera.setViewOffset) {
this.camera.setViewOffset(
viewOffset.fullWidth,
viewOffset.fullHeight,
viewOffset.offsetX + jitterOffset[0] * 0.0625,
viewOffset.offsetY + jitterOffset[1] * 0.0625,
// 0.0625 = 1 / 16
viewOffset.width,
viewOffset.height
);
}
let sampleWeight = baseSampleWeight;
if (this.unbiased) {
const uniformCenteredDistribution = -0.5 + (i + 0.5) / jitterOffsets.length;
sampleWeight += roundingRange * uniformCenteredDistribution;
}
this.copyUniforms["opacity"].value = sampleWeight;
renderer.setClearColor(this.clearColor, this.clearAlpha);
renderer.setRenderTarget(this.sampleRenderTarget);
renderer.clear();
renderer.render(this.scene, this.camera);
renderer.setRenderTarget(this.renderToScreen ? null : writeBuffer);
if (i === 0) {
renderer.setClearColor(0, 0);
renderer.clear();
}
this.fsQuad.render(renderer);
}
if (this.camera.setViewOffset && originalViewOffset.enabled) {
this.camera.setViewOffset(
originalViewOffset.fullWidth,
originalViewOffset.fullHeight,
originalViewOffset.offsetX,
originalViewOffset.offsetY,
originalViewOffset.width,
originalViewOffset.height
);
} else if (this.camera.clearViewOffset) {
this.camera.clearViewOffset();
}
renderer.autoClear = autoClear;
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
}
}
const _JitterVectors = [
[
[0, 0]
],
[
[4, 4],
[-4, -4]
],
[
[-2, -6],
[6, -2],
[-6, 2],
[2, 6]
],
[
[1, -3],
[-1, 3],
[5, 1],
[-3, -5],
[-5, 5],
[-7, -1],
[3, 7],
[7, -7]
],
[
[1, 1],
[-1, -3],
[-3, 2],
[4, -1],
[-5, -2],
[2, 5],
[5, 3],
[3, -5],
[-2, 6],
[0, -7],
[-4, -6],
[-6, 4],
[-8, 0],
[7, -4],
[6, 7],
[-7, -8]
],
[
[-4, -7],
[-7, -5],
[-3, -5],
[-5, -4],
[-1, -4],
[-2, -2],
[-6, -1],
[-4, 0],
[-7, 1],
[-1, 2],
[-6, 3],
[-3, 3],
[-7, 6],
[-3, 6],
[-5, 7],
[-1, 7],
[5, -7],
[1, -6],
[6, -5],
[4, -4],
[2, -3],
[7, -2],
[1, -1],
[4, -1],
[2, 1],
[6, 2],
[0, 4],
[4, 4],
[2, 5],
[7, 5],
[5, 6],
[3, 7]
]
];
exports.SSAARenderPass = SSAARenderPass;
//# sourceMappingURL=SSAARenderPass.cjs.map
File diff suppressed because one or more lines are too long
+17
View File
@@ -0,0 +1,17 @@
import { Scene, Camera, Color, ShaderMaterial, WebGLRenderTarget } from 'three'
import { Pass, FullScreenQuad } from './Pass'
export class SSAARenderPass extends Pass {
constructor(scene: Scene, camera: Camera, clearColor?: Color | string | number, clearAlpha?: number)
scene: Scene
camera: Camera
sampleLevel: number
unbiased: boolean
clearColor: Color | string | number
clearAlpha: number
copyUniforms: object
copyMaterial: ShaderMaterial
fsQuad: FullScreenQuad
sampleRenderTarget: undefined | WebGLRenderTarget
}
+190
View File
@@ -0,0 +1,190 @@
import { Color, UniformsUtils, ShaderMaterial, AdditiveBlending, WebGLRenderTarget, HalfFloatType } from "three";
import { Pass, FullScreenQuad } from "./Pass.js";
import { CopyShader } from "../shaders/CopyShader.js";
class SSAARenderPass extends Pass {
constructor(scene, camera, clearColor, clearAlpha) {
super();
this.scene = scene;
this.camera = camera;
this.sampleLevel = 4;
this.unbiased = true;
this.clearColor = clearColor !== void 0 ? clearColor : 0;
this.clearAlpha = clearAlpha !== void 0 ? clearAlpha : 0;
this._oldClearColor = new Color();
const copyShader = CopyShader;
this.copyUniforms = UniformsUtils.clone(copyShader.uniforms);
this.copyMaterial = new ShaderMaterial({
uniforms: this.copyUniforms,
vertexShader: copyShader.vertexShader,
fragmentShader: copyShader.fragmentShader,
transparent: true,
depthTest: false,
depthWrite: false,
premultipliedAlpha: true,
blending: AdditiveBlending
});
this.fsQuad = new FullScreenQuad(this.copyMaterial);
}
dispose() {
if (this.sampleRenderTarget) {
this.sampleRenderTarget.dispose();
this.sampleRenderTarget = null;
}
this.copyMaterial.dispose();
this.fsQuad.dispose();
}
setSize(width, height) {
if (this.sampleRenderTarget)
this.sampleRenderTarget.setSize(width, height);
}
render(renderer, writeBuffer, readBuffer) {
if (!this.sampleRenderTarget) {
this.sampleRenderTarget = new WebGLRenderTarget(readBuffer.width, readBuffer.height, { type: HalfFloatType });
this.sampleRenderTarget.texture.name = "SSAARenderPass.sample";
}
const jitterOffsets = _JitterVectors[Math.max(0, Math.min(this.sampleLevel, 5))];
const autoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.getClearColor(this._oldClearColor);
const oldClearAlpha = renderer.getClearAlpha();
const baseSampleWeight = 1 / jitterOffsets.length;
const roundingRange = 1 / 32;
this.copyUniforms["tDiffuse"].value = this.sampleRenderTarget.texture;
const viewOffset = {
fullWidth: readBuffer.width,
fullHeight: readBuffer.height,
offsetX: 0,
offsetY: 0,
width: readBuffer.width,
height: readBuffer.height
};
const originalViewOffset = Object.assign({}, this.camera.view);
if (originalViewOffset.enabled)
Object.assign(viewOffset, originalViewOffset);
for (let i = 0; i < jitterOffsets.length; i++) {
const jitterOffset = jitterOffsets[i];
if (this.camera.setViewOffset) {
this.camera.setViewOffset(
viewOffset.fullWidth,
viewOffset.fullHeight,
viewOffset.offsetX + jitterOffset[0] * 0.0625,
viewOffset.offsetY + jitterOffset[1] * 0.0625,
// 0.0625 = 1 / 16
viewOffset.width,
viewOffset.height
);
}
let sampleWeight = baseSampleWeight;
if (this.unbiased) {
const uniformCenteredDistribution = -0.5 + (i + 0.5) / jitterOffsets.length;
sampleWeight += roundingRange * uniformCenteredDistribution;
}
this.copyUniforms["opacity"].value = sampleWeight;
renderer.setClearColor(this.clearColor, this.clearAlpha);
renderer.setRenderTarget(this.sampleRenderTarget);
renderer.clear();
renderer.render(this.scene, this.camera);
renderer.setRenderTarget(this.renderToScreen ? null : writeBuffer);
if (i === 0) {
renderer.setClearColor(0, 0);
renderer.clear();
}
this.fsQuad.render(renderer);
}
if (this.camera.setViewOffset && originalViewOffset.enabled) {
this.camera.setViewOffset(
originalViewOffset.fullWidth,
originalViewOffset.fullHeight,
originalViewOffset.offsetX,
originalViewOffset.offsetY,
originalViewOffset.width,
originalViewOffset.height
);
} else if (this.camera.clearViewOffset) {
this.camera.clearViewOffset();
}
renderer.autoClear = autoClear;
renderer.setClearColor(this._oldClearColor, oldClearAlpha);
}
}
const _JitterVectors = [
[
[0, 0]
],
[
[4, 4],
[-4, -4]
],
[
[-2, -6],
[6, -2],
[-6, 2],
[2, 6]
],
[
[1, -3],
[-1, 3],
[5, 1],
[-3, -5],
[-5, 5],
[-7, -1],
[3, 7],
[7, -7]
],
[
[1, 1],
[-1, -3],
[-3, 2],
[4, -1],
[-5, -2],
[2, 5],
[5, 3],
[3, -5],
[-2, 6],
[0, -7],
[-4, -6],
[-6, 4],
[-8, 0],
[7, -4],
[6, 7],
[-7, -8]
],
[
[-4, -7],
[-7, -5],
[-3, -5],
[-5, -4],
[-1, -4],
[-2, -2],
[-6, -1],
[-4, 0],
[-7, 1],
[-1, 2],
[-6, 3],
[-3, 3],
[-7, 6],
[-3, 6],
[-5, 7],
[-1, 7],
[5, -7],
[1, -6],
[6, -5],
[4, -4],
[2, -3],
[7, -2],
[1, -1],
[4, -1],
[2, 1],
[6, 2],
[0, 4],
[4, 4],
[2, 5],
[7, 5],
[5, 6],
[3, 7]
]
];
export {
SSAARenderPass
};
//# sourceMappingURL=SSAARenderPass.js.map
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More