UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

137 lines (136 loc) 4.65 kB
"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(); } }