UNPKG

threepipe

Version:

A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.

116 lines 5.79 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { ExtendedShaderPass } from './ExtendedShaderPass'; import { FrontSide, NoBlending, SRGBColorSpace, } from 'three'; import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js'; import { uiDropdown, uiFolderContainer, uiToggle } from 'uiconfig.js'; import { matDefineBool, threeConstMappings } from '../three'; import ScreenPassShader from './ScreenPass.glsl'; import { shaderReplaceString } from '../utils'; /** * Screen Pass * * This pass renders the final scene to the screen. * It can be extended by Screen Pass Extensions to apply post-processing effects, such as tonemapping, color grading, etc. * * It is used by default in {@link ViewerRenderManager} to render the final scene. * A custom material/shader can be passed to the constructor to use a custom base fragment shader. */ let ScreenPass = class ScreenPass extends ExtendedShaderPass { constructor(shader = '', ...textureID) { super(shader?.fragmentShader || shader?.isShaderMaterial ? shader : makeScreenShader(shader), ...textureID.length ? textureID : ['tDiffuse', 'tTransparent']); this.passId = 'screen'; this.after = ['render']; this.required = ['render']; /** * Output Color Space * Note: this is ignored when renderToScreen is false (it will take the color space of the render target) */ this.outputColorSpace = SRGBColorSpace; this._needsReRender = false; /** * Force clip background. If this is `true` {@link clipBackground} is overridden. * This happens when scene.background and scene.backgroundColor are both null. * This is set in {@link ViewerRenderManager.render}. */ this.clipBackgroundForce = false; // todo: this is not serialized anymore? we should serialize this in some plugin... this.clipBackground = false; this.material.addEventListener('materialUpdate', this.setDirty); } render(renderer, writeBuffer, readBuffer, deltaTime, maskActive) { const colorSpace = renderer.outputColorSpace; if (!writeBuffer || this.renderToScreen) renderer.outputColorSpace = this.outputColorSpace; // else console.warn('ScreenPass: outputColorSpace is ignored when renderToScreen is false') super.render(renderer, writeBuffer, readBuffer, deltaTime, maskActive); this._lastReadBuffer = readBuffer; renderer.outputColorSpace = colorSpace; this._needsReRender = false; } reRender(renderer, writeBuffer, deltaTime, maskActive) { if (this._lastReadBuffer) this.render(renderer, writeBuffer, this._lastReadBuffer, deltaTime, maskActive); } onPostFrame(renderManager) { if (!this._needsReRender) return; this._needsReRender = false; this.reRender(renderManager.renderer); if (this.clipBackground && !renderManager.gbufferTarget) { // todo warn only when rgbm console.warn('ScreenPass: clipBackground set to true but no gbufferTarget set. Try adding GBufferPlugin.'); } } dispose() { this._lastReadBuffer = undefined; super.dispose(); } beforeRender(_, _1, renderManager) { if (this.material.uniforms.tTransparent) { this.material.uniforms.tTransparent.value = renderManager.renderPass.preserveTransparentTarget ? renderManager.renderPass.transparentTarget?.texture || null : null; this.material.defines.HAS_TRANSPARENT_TARGET = this.material.uniforms.tTransparent.value ? 1 : undefined; if (!this.material.defines.HAS_TRANSPARENT_TARGET) delete this.material.defines.HAS_TRANSPARENT_TARGET; } } setDirty() { super.setDirty(); this._needsReRender = true; } }; __decorate([ uiDropdown('Output Color Space', threeConstMappings.ColorSpace.uiConfig, (t) => ({ onChange: t.setDirty })) ], ScreenPass.prototype, "outputColorSpace", void 0); __decorate([ matDefineBool('CLIP_BACKGROUND_FORCE', undefined, undefined, ScreenPass.prototype.setDirty, true) ], ScreenPass.prototype, "clipBackgroundForce", void 0); __decorate([ matDefineBool('CLIP_BACKGROUND', undefined, undefined, ScreenPass.prototype.setDirty), uiToggle() ], ScreenPass.prototype, "clipBackground", void 0); ScreenPass = __decorate([ uiFolderContainer('Screen Pass') ], ScreenPass); export { ScreenPass }; function makeScreenShader(shader) { const baseShader = shaderReplaceString(ScreenPassShader, 'void main()', (Array.isArray(shader) ? shader[0] : shader?.pars || '') + '\n', { prepend: true }); const finalShader = baseShader.includes('#glMarker') ? shaderReplaceString(baseShader, '#glMarker', (Array.isArray(shader) ? shader[1] : typeof shader === 'string' ? shader : shader?.main || '') + '\n', { prepend: true }) : baseShader; return { ...CopyShader, fragmentShader: finalShader, uniforms: { tDiffuse: { value: null }, tTransparent: { value: null }, }, transparent: true, blending: NoBlending, side: FrontSide, }; } //# sourceMappingURL=ScreenPass.js.map