polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
91 lines (86 loc) • 2.6 kB
text/typescript
/**
* Allows to render with a mask.
*
*
*/
import {TypedPostProcessNode, TypedPostNodeContext, PostParamOptions} from './_Base';
import {MaskPass} from '../../../modules/three/examples/jsm/postprocessing/MaskPass';
import {NodeContext} from '../../poly/NodeContext';
import {SceneObjNode} from '../obj/Scene';
import {BaseCameraObjNodeType} from '../obj/_BaseCamera';
import {Scene} from 'three/src/scenes/Scene';
import {Camera} from 'three/src/cameras/Camera';
interface MaskPassWithContext extends MaskPass {
context: {
scene: Scene;
camera: Camera;
};
}
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
class MaskPostParamsConfig extends NodeParamsConfig {
overrideScene = ParamConfig.BOOLEAN(0, PostParamOptions);
scene = ParamConfig.OPERATOR_PATH('/scene1', {
visibleIf: {overrideScene: 1},
nodeSelection: {
context: NodeContext.OBJ,
types: [SceneObjNode.type()],
},
...PostParamOptions,
});
overrideCamera = ParamConfig.BOOLEAN(0, PostParamOptions);
camera = ParamConfig.OPERATOR_PATH('/perspective_camera1', {
visibleIf: {overrideCamera: 1},
nodeSelection: {
context: NodeContext.OBJ,
},
...PostParamOptions,
});
inverse = ParamConfig.BOOLEAN(0, PostParamOptions);
}
const ParamsConfig = new MaskPostParamsConfig();
export class MaskPostNode extends TypedPostProcessNode<MaskPassWithContext, MaskPostParamsConfig> {
params_config = ParamsConfig;
static type() {
return 'mask';
}
protected _create_pass(context: TypedPostNodeContext) {
const pass = new MaskPass(context.scene, context.camera) as MaskPassWithContext;
pass.context = {
scene: context.scene,
camera: context.camera,
};
this.update_pass(pass);
return pass;
}
update_pass(pass: MaskPassWithContext) {
pass.inverse = this.pv.inverse;
this._update_scene(pass);
this._update_camera(pass);
}
private async _update_scene(pass: MaskPassWithContext) {
if (this.pv.overrideScene) {
if (this.p.scene.isDirty()) {
await this.p.scene.compute();
}
const scene_node = this.p.scene.found_node_with_expected_type() as SceneObjNode;
if (scene_node) {
pass.scene = scene_node.object;
return;
}
}
pass.scene = pass.context.scene;
}
private async _update_camera(pass: MaskPassWithContext) {
if (this.pv.overrideCamera) {
if (this.p.camera.isDirty()) {
await this.p.camera.compute();
}
const camera_node = this.p.camera.found_node_with_expected_type() as BaseCameraObjNodeType;
if (camera_node) {
pass.camera = camera_node.object;
return;
}
}
pass.camera = pass.context.camera;
}
}