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.

148 lines 6.31 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; }; // noinspection ES6PreferShortImport import { uiDropdown, uiFolderContainer, uiSlider, uiToggle } from 'uiconfig.js'; import { ACESFilmicToneMapping, AgXToneMapping, CineonToneMapping, CustomToneMapping, LinearToneMapping, ReinhardToneMapping, ShaderChunk, } from 'three'; import { glsl, onChange, serialize } from 'ts-browser-helpers'; import { updateBit } from '../../utils'; import { uniform } from '../../three'; import Uncharted2ToneMappingShader from './shaders/Uncharted2ToneMapping.glsl'; import TonemapShader from './shaders/TonemapPlugin.pars.glsl'; import TonemapShaderPatch from './shaders/TonemapPlugin.patch.glsl'; import { AScreenPassExtensionPlugin } from './AScreenPassExtensionPlugin'; import { matDefineBool } from '../../three/utils/decorators'; // eslint-disable-next-line @typescript-eslint/naming-convention export const Uncharted2Tonemapping = CustomToneMapping; /** * Tonemap Plugin * * Adds an extension to {@link ScreenPass} material * for applying tonemapping on the final buffer before rendering to screen. * * Also adds support for Uncharted2 tone-mapping. * @category Plugins */ let TonemapPlugin = class TonemapPlugin extends AScreenPassExtensionPlugin { constructor() { super(...arguments); this.extraUniforms = { toneMappingContrast: { value: 1 }, toneMappingSaturation: { value: 1 }, }; this.extraDefines = { ['TONEMAP_BACKGROUND']: '1', }; this.enabled = true; this.toneMapping = ACESFilmicToneMapping; this.tonemapBackground = true; // todo handle legacy deserialize // @onChange(TonemapPlugin.prototype.setDirty) // @uiToggle('Clip Background') // @serialize() clipBackground = false this.exposure = 1; /** * The priority of the material extension when applied to the material in ScreenPass * set to very low priority, so applied at the end */ this.priority = -100; this.parsFragmentSnippet = () => { if (this.isDisabled()) return ''; return glsl ` uniform float toneMappingContrast; uniform float toneMappingSaturation; ${TonemapShader} `; }; this._shaderPatch = TonemapShaderPatch; this._rendererState = {}; } onObjectRender(_, material, renderer) { if (this.isDisabled()) return; const { toneMapping, toneMappingExposure } = renderer; this._rendererState.toneMapping = toneMapping; this._rendererState.toneMappingExposure = toneMappingExposure; renderer.toneMapping = this.toneMapping; renderer.toneMappingExposure = this.exposure; material.toneMapped = true; material.needsUpdate = true; } onAfterRender(_, _1, renderer) { renderer.toneMapping = this._rendererState.toneMapping; renderer.toneMappingExposure = this._rendererState.toneMappingExposure; } fromJSON(data, meta) { // legacy if (data.extension) { if (data.clipBackground !== undefined) { if (this._viewer) this._viewer.renderManager.screenPass.clipBackground = data.clipBackground; else console.warn('TonemapPlugin: no viewer attached, clipBackground ignored'); delete data.clipBackground; } } return super.fromJSON(data, meta); } // TODO: add gBufferData or just tonemapEnabled to the scene material UI with an extension like bloom updateGBufferFlags(data, c) { const x = (c.material.userData.gBufferData?.tonemapEnabled ?? c.material?.userData.postTonemap) === false ? 0 : 1; data.w = updateBit(data.w, 1, x); // 2nd Bit super.updateGBufferFlags(data, c); } }; TonemapPlugin.PluginType = 'Tonemap'; (() => { // Add support for Uncharted2 tone mapping ShaderChunk.tonemapping_pars_fragment = ShaderChunk.tonemapping_pars_fragment.replace('vec3 CustomToneMapping( vec3 color ) { return color; }', Uncharted2ToneMappingShader); })(); __decorate([ serialize(), onChange(TonemapPlugin.prototype.setDirty), uiToggle('Enabled') ], TonemapPlugin.prototype, "enabled", void 0); __decorate([ uiDropdown('Mode', [ ['Linear', LinearToneMapping], ['Reinhard', ReinhardToneMapping], ['Cineon', CineonToneMapping], ['ACESFilmic', ACESFilmicToneMapping], ['Uncharted2', Uncharted2Tonemapping], ['AgX', AgXToneMapping], ].map(value => ({ label: value[0], value: value[1], }))), onChange(TonemapPlugin.prototype.setDirty), serialize() ], TonemapPlugin.prototype, "toneMapping", void 0); __decorate([ uiToggle('Tonemap Background', (t) => ({ hidden: () => !t._viewer?.renderManager.gbufferTarget })), matDefineBool('TONEMAP_BACKGROUND', undefined, true, TonemapPlugin.prototype.setDirty), serialize() ], TonemapPlugin.prototype, "tonemapBackground", void 0); __decorate([ onChange(TonemapPlugin.prototype.setDirty), uiSlider('Exposure', [0, 2 * Math.PI], 0.01), serialize() ], TonemapPlugin.prototype, "exposure", void 0); __decorate([ uiSlider('Saturation', [0, 2], 0.01), uniform({ propKey: 'toneMappingSaturation' }), serialize() ], TonemapPlugin.prototype, "saturation", void 0); __decorate([ uiSlider('Contrast', [0, 2], 0.01), uniform({ propKey: 'toneMappingContrast' }), serialize() ], TonemapPlugin.prototype, "contrast", void 0); TonemapPlugin = __decorate([ uiFolderContainer('Tonemapping') ], TonemapPlugin); export { TonemapPlugin }; //# sourceMappingURL=TonemapPlugin.js.map