@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
137 lines (136 loc) • 4.65 kB
JavaScript
"use strict";
import { GODRAYS_RESOLUTION_SCALE } from "./utils/GodRaysConstant";
import { GodraysIllumPass } from "./utils/GodRaysIlluminationPass";
import {
BasicDepthPacking,
Color,
WebGLRenderTarget,
LinearFilter,
RGBAFormat
} from "three";
import { Pass } from "postprocessing";
import { GodraysCompositorMaterial } from "./utils/GodRaysCompositorMaterial";
import { GodRaysPassDefaultParams } from "./utils/GodRaysPassParams";
class GodraysCompositorPass extends Pass {
constructor(props) {
super("GodraysCompositorPass");
this.fullscreenMaterial = new GodraysCompositorMaterial(props);
this.sceneCamera = props.camera;
}
updateUniforms(params) {
this.fullscreenMaterial.updateUniforms(
params.edgeStrength,
params.edgeRadius,
params.color,
this.sceneCamera.near,
this.sceneCamera.far
);
}
render(renderer, inputBuffer, outputBuffer, _deltaTime, _stencilTest) {
this.fullscreenMaterial.uniforms.sceneDiffuse.value = inputBuffer.texture;
renderer.setRenderTarget(outputBuffer);
renderer.render(this.scene, this.camera);
}
setDepthTexture(depthTexture, depthPacking) {
if (depthPacking && depthPacking !== BasicDepthPacking) {
throw new Error("Only BasicDepthPacking is supported");
}
this.fullscreenMaterial.uniforms.sceneDepth.value = depthTexture;
}
setSize(width, height) {
this.fullscreenMaterial.setSize(width, height);
}
}
const populateParams = (partialParams) => {
var _a;
return {
...GodRaysPassDefaultParams,
...partialParams,
color: new Color((_a = partialParams.color) != null ? _a : GodRaysPassDefaultParams.color)
};
};
export class GodraysPass extends Pass {
/**
* Constructs a new GodraysPass. Casts godrays from a point light source. Add to your scene's composer like this:
*
* ```ts
* import { EffectComposer, RenderPass } from 'postprocessing';
* import { GodraysPass } from 'three-good-godrays';
*
* const composer = new EffectComposer(renderer);
* const renderPass = new RenderPass(scene, camera);
* renderPass.renderToScreen = false;
* composer.addPass(renderPass);
*
* const godraysPass = new GodraysPass(pointLight, camera);
* godraysPass.renderToScreen = true;
* composer.addPass(godraysPass);
*
* function animate() {
* composer.render(scene, camera);
* }
* ```
*
* @param light The light source to use for the godrays.
* @param camera The camera used to render the scene.
* @param partialParams The parameters to use for the godrays effect. Will use default values for any parameters not specified.
*/
constructor(light, camera, partialParams = {}) {
super("GodraysPass");
this.godraysRenderTarget = new WebGLRenderTarget(1, 1, {
minFilter: LinearFilter,
magFilter: LinearFilter,
format: RGBAFormat
});
this.props = {
light,
camera
};
const params = populateParams(partialParams);
this.illumPass = new GodraysIllumPass(this.props, params);
this.illumPass.needsDepthTexture = true;
this.compositorPass = new GodraysCompositorPass({
godrays: this.godraysRenderTarget.texture,
edgeStrength: params.edgeStrength,
edgeRadius: params.edgeRadius,
color: params.color,
camera
});
this.compositorPass.needsDepthTexture = true;
this.needsDepthTexture = true;
this.setParams(params);
}
setLight(light) {
this.props.light = light;
}
/**
* Updates the parameters used for the godrays effect. Will use default values for any parameters not specified.
*/
setParams(partialParams) {
const params = populateParams(partialParams);
this.illumPass.updateUniforms(this.props, params);
this.compositorPass.updateUniforms(params);
}
render(renderer, inputBuffer, outputBuffer, _deltaTime, _stencilTest) {
this.illumPass.render(renderer, inputBuffer, this.godraysRenderTarget);
this.compositorPass.render(renderer, inputBuffer, this.renderToScreen ? null : outputBuffer);
}
setDepthTexture(depthTexture, depthPacking) {
this.illumPass.setDepthTexture(depthTexture, depthPacking);
this.compositorPass.setDepthTexture(depthTexture, depthPacking);
}
setSize(width, height) {
this.godraysRenderTarget.setSize(
Math.ceil(width * GODRAYS_RESOLUTION_SCALE),
Math.ceil(height * GODRAYS_RESOLUTION_SCALE)
);
this.illumPass.setSize(width, height);
this.compositorPass.setSize(width, height);
}
dispose() {
this.godraysRenderTarget.dispose();
this.illumPass.dispose();
this.compositorPass.dispose();
super.dispose();
}
}