@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in
139 lines • 6.84 kB
JavaScript
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 { ACESFilmicToneMapping, AgXToneMapping, LinearToneMapping, NeutralToneMapping, ReinhardToneMapping } from "three";
import { MODULES } from "../../../engine/engine_modules.js";
import { serializable } from "../../../engine/engine_serialization.js";
import { getParam } from "../../../engine/engine_utils.js";
import { PostProcessingEffect } from "../PostProcessingEffect.js";
import { findPostProcessingManager } from "../utils.js";
import { VolumeParameter } from "../VolumeParameter.js";
import { registerCustomEffectType } from "../VolumeProfile.js";
const debug = getParam("debugpost");
var NEToneMappingMode;
(function (NEToneMappingMode) {
NEToneMappingMode[NEToneMappingMode["None"] = 0] = "None";
NEToneMappingMode[NEToneMappingMode["Neutral"] = 1] = "Neutral";
NEToneMappingMode[NEToneMappingMode["ACES"] = 2] = "ACES";
NEToneMappingMode[NEToneMappingMode["AgX"] = 3] = "AgX";
NEToneMappingMode[NEToneMappingMode["KhronosNeutral"] = 4] = "KhronosNeutral";
})(NEToneMappingMode || (NEToneMappingMode = {}));
function toThreeToneMapping(mode) {
switch (mode) {
case NEToneMappingMode.None:
return LinearToneMapping;
case NEToneMappingMode.Neutral:
return ReinhardToneMapping;
case NEToneMappingMode.ACES:
return ACESFilmicToneMapping;
case NEToneMappingMode.AgX:
return AgXToneMapping;
case NEToneMappingMode.KhronosNeutral:
return NeutralToneMapping;
default:
return NeutralToneMapping;
}
}
function threeToNeToneMapping(mode) {
switch (mode) {
case LinearToneMapping: return NEToneMappingMode.None;
case ACESFilmicToneMapping: return NEToneMappingMode.ACES;
case AgXToneMapping: return NEToneMappingMode.AgX;
case NeutralToneMapping: return NEToneMappingMode.Neutral;
case ReinhardToneMapping: return NEToneMappingMode.Neutral;
default: return NEToneMappingMode.None;
}
}
function threeToneMappingToEffectMode(mode) {
switch (mode) {
case LinearToneMapping: return MODULES.POSTPROCESSING.MODULE.ToneMappingMode.LINEAR;
case ACESFilmicToneMapping: return MODULES.POSTPROCESSING.MODULE.ToneMappingMode.ACES_FILMIC;
case AgXToneMapping: return MODULES.POSTPROCESSING.MODULE.ToneMappingMode.AGX;
case NeutralToneMapping: return MODULES.POSTPROCESSING.MODULE.ToneMappingMode.NEUTRAL;
case ReinhardToneMapping: return MODULES.POSTPROCESSING.MODULE.ToneMappingMode.REINHARD;
default: return MODULES.POSTPROCESSING.MODULE.ToneMappingMode.LINEAR;
}
}
/**
* @category Effects
* @group Components
*/
export class ToneMappingEffect extends PostProcessingEffect {
get typeName() {
return "ToneMapping";
}
mode = new VolumeParameter(undefined);
exposure = new VolumeParameter(1);
/** Set the tonemapping mode to e.g. "agx" */
setMode(mode) {
const enumValue = NEToneMappingMode[mode];
if (enumValue === undefined) {
console.error("Invalid ToneMapping mode", mode);
return this;
}
this.mode.value = enumValue;
return this;
}
get isToneMapping() { return true; }
onEffectEnabled() {
// Tonemapping works with and without a postprocessing manager.
// If there's no manager already in the scene we don't need to create one because tonemapping can also be applied without a postprocessing pass
const ppmanager = findPostProcessingManager(this);
if (!ppmanager)
return;
super.onEffectEnabled(ppmanager);
}
onCreateEffect() {
// TODO: this should be done in the PostProcessingHandler
if (this.postprocessingContext) {
for (const other of this.postprocessingContext.components) {
// If we're the first tonemapping effect it's all good
if (other === this)
break;
// If another tonemapping effect is found, warn the user
if (other != this && other instanceof ToneMappingEffect) {
console.warn("Multiple tonemapping effects found in the same postprocessing stack: Please check your scene setup.", { activeEffect: other, ignoredEffect: this });
return undefined;
}
}
}
// ensure the effect tonemapping value is initialized
if (this.mode.isInitialized == false) {
const init = threeToNeToneMapping(this.context.renderer.toneMapping);
this.mode.initialize(init);
}
const threeMode = toThreeToneMapping(this.mode.value);
const tonemapping = new MODULES.POSTPROCESSING.MODULE.ToneMappingEffect({
mode: threeToneMappingToEffectMode(threeMode),
});
this.mode.onValueChanged = (newValue) => {
const threeMode = toThreeToneMapping(newValue);
tonemapping.mode = threeToneMappingToEffectMode(threeMode);
if (debug)
console.log("ToneMapping mode changed to", NEToneMappingMode[newValue], threeMode, tonemapping.mode);
};
if (debug)
console.log("Use ToneMapping", NEToneMappingMode[this.mode.value], threeMode, tonemapping.mode, "renderer.tonemapping: " + this.context.renderer.toneMapping);
this.exposure.onValueChanged = (newValue) => {
this.context.renderer.toneMappingExposure = newValue;
};
return tonemapping;
}
onBeforeRender() {
if (this.mode.overrideState)
this.context.renderer.toneMapping = toThreeToneMapping(this.mode.value);
if (this.exposure.overrideState && this.exposure.value !== undefined)
this.context.renderer.toneMappingExposure = this.exposure.value;
}
}
__decorate([
serializable(VolumeParameter)
], ToneMappingEffect.prototype, "mode", void 0);
__decorate([
serializable(VolumeParameter)
], ToneMappingEffect.prototype, "exposure", void 0);
registerCustomEffectType("Tonemapping", ToneMappingEffect);
//# sourceMappingURL=Tonemapping.js.map