polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
90 lines (84 loc) • 2.62 kB
text/typescript
/**
* Adds an image effect.
*
*
*/
import {TypedPostProcessNode, TypedPostNodeContext, PostParamOptions} from './_Base';
import {ShaderPass} from '../../../modules/three/examples/jsm/postprocessing/ShaderPass';
import {IUniformN, IUniformTexture} from '../utils/code/gl/Uniforms';
import VertexShader from './Image/vert.glsl';
import FragmentShader from './Image/frag.glsl';
import {NodeContext} from '../../poly/NodeContext';
interface ShaderPassWithRequiredUniforms extends ShaderPass {
uniforms: {
map: IUniformTexture;
darkness: IUniformN;
offset: IUniformN;
};
}
import {NodeParamsConfig, ParamConfig} from '../utils/params/ParamsConfig';
import {BaseCopNodeType} from '../cop/_Base';
import {NODE_PATH_DEFAULT} from '../../../core/Walker';
class ImagePostParamsConfig extends NodeParamsConfig {
map = ParamConfig.OPERATOR_PATH(NODE_PATH_DEFAULT.NODE.UV, {
nodeSelection: {context: NodeContext.COP},
...PostParamOptions,
});
darkness = ParamConfig.FLOAT(0, {
range: [0, 2],
rangeLocked: [true, false],
...PostParamOptions,
});
offset = ParamConfig.FLOAT(0, {
range: [0, 2],
rangeLocked: [true, false],
...PostParamOptions,
});
}
const ParamsConfig = new ImagePostParamsConfig();
export class ImagePostNode extends TypedPostProcessNode<ShaderPass, ImagePostParamsConfig> {
params_config = ParamsConfig;
static type() {
return 'image';
}
static _create_shader() {
return {
uniforms: {
tDiffuse: {value: null} as IUniformTexture,
map: {value: null} as IUniformTexture,
offset: {value: 1.0},
darkness: {value: 1.0},
},
vertexShader: VertexShader,
fragmentShader: FragmentShader,
};
}
protected _create_pass(context: TypedPostNodeContext) {
const pass = new ShaderPass(ImagePostNode._create_shader()) as ShaderPassWithRequiredUniforms;
this.update_pass(pass);
return pass;
}
update_pass(pass: ShaderPassWithRequiredUniforms) {
pass.uniforms.darkness.value = this.pv.darkness;
pass.uniforms.offset.value = this.pv.offset;
this._update_map(pass);
}
private async _update_map(pass: ShaderPassWithRequiredUniforms) {
if (this.p.map.isDirty()) {
await this.p.map.compute();
}
const found_node = this.p.map.found_node();
if (found_node) {
if (found_node.nodeContext() == NodeContext.COP) {
const cop_node = found_node as BaseCopNodeType;
const map_container = await cop_node.requestContainer();
const texture = map_container.coreContent();
pass.uniforms.map.value = texture;
} else {
this.states.error.set('node is not COP');
}
} else {
this.states.error.set('no map found');
}
}
}