UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 4.82 kB
import{FILTER_NEAREST as e,ADDRESS_CLAMP_TO_EDGE as t,PIXELFORMAT_RGBA16F as s,PIXELFORMAT_RGBA32F as r,PIXELFORMAT_RGBA8 as i}from"../../../platform/graphics/constants.js";import{RenderTarget as a}from"../../../platform/graphics/render-target.js";import{Texture as h}from"../../../platform/graphics/texture.js";import{LAYERID_DEPTH as n}from"../../../scene/constants.js";class f{constructor(e,t){this.effect=e,this.inputTarget=t,this.outputTarget=null,this.name=e.constructor.name}}class c{constructor(e,t){this.app=e,this.camera=t,this.destinationRenderTarget=null,this.effects=[],this.enabled=!1,this.depthTarget=null,t.on("set:rect",this.onCameraRectChanged,this)}_allocateColorBuffer(s,r){var i,a;const n=this.camera.rect,f=this.destinationRenderTarget,c=this.app.graphicsDevice,o=Math.floor(n.z*(null!=(i=null==f?void 0:f.width)?i:c.width)),l=Math.floor(n.w*(null!=(a=null==f?void 0:f.height)?a:c.height));return new h(c,{name:r,format:s,width:o,height:l,mipmaps:!1,minFilter:e,magFilter:e,addressU:t,addressV:t})}_createOffscreenTarget(e,t){const h=this.app.graphicsDevice,n=t&&h.getRenderableHdrFormat([s,r],!0)||i,f=`${this.camera.entity.name}-posteffect-${this.effects.length}`,c=this._allocateColorBuffer(n,f);return new a({colorBuffer:c,depth:e,stencil:e&&this.app.graphicsDevice.supportsStencil,samples:e?h.samples:1})}_resizeOffscreenTarget(e){const t=e.colorBuffer.format,s=e.colorBuffer.name;e.destroyFrameBuffers(),e.destroyTextureBuffers(),e._colorBuffer=this._allocateColorBuffer(t,s),e._colorBuffers=[e._colorBuffer]}_destroyOffscreenTarget(e){e.destroyTextureBuffers(),e.destroy()}addEffect(e){const t=this.effects,s=0===t.length,r=this._createOffscreenTarget(s,e.hdr),i=new f(e,r);t.push(i),this._sourceTarget=i.inputTarget,t.length>1&&(t[t.length-2].outputTarget=i.inputTarget),this._newPostEffect=e,e.needsDepthBuffer&&this._requestDepthMap(),this.enable(),this._newPostEffect=void 0}removeEffect(e){let t=-1;for(let s=0,r=this.effects.length;s<r;s++)if(this.effects[s].effect===e){t=s;break}t>=0&&(t>0?this.effects[t-1].outputTarget=t+1<this.effects.length?this.effects[t+1].inputTarget:null:this.effects.length>1&&(this.effects[1].inputTarget._depth||(this._destroyOffscreenTarget(this.effects[1].inputTarget),this.effects[1].inputTarget=this._createOffscreenTarget(!0,this.effects[1].hdr),this._sourceTarget=this.effects[1].inputTarget),this.camera.renderTarget=this.effects[1].inputTarget),this._destroyOffscreenTarget(this.effects[t].inputTarget),this.effects.splice(t,1)),this.enabled&&e.needsDepthBuffer&&this._releaseDepthMap(),0===this.effects.length&&this.disable()}_requestDepthMaps(){for(let e=0,t=this.effects.length;e<t;e++){const t=this.effects[e].effect;this._newPostEffect!==t&&(t.needsDepthBuffer&&this._requestDepthMap())}}_releaseDepthMaps(){for(let e=0,t=this.effects.length;e<t;e++){this.effects[e].effect.needsDepthBuffer&&this._releaseDepthMap()}}_requestDepthMap(){const e=this.app.scene.layers.getLayerById(n);e&&(e.incrementCounter(),this.camera.requestSceneDepthMap(!0))}_releaseDepthMap(){const e=this.app.scene.layers.getLayerById(n);e&&(e.decrementCounter(),this.camera.requestSceneDepthMap(!1))}destroy(){for(let e=0,t=this.effects.length;e<t;e++)this.effects[e].inputTarget.destroy();this.effects.length=0,this.disable()}enable(){!this.enabled&&this.effects.length&&(this.enabled=!0,this._requestDepthMaps(),this.app.graphicsDevice.on("resizecanvas",this._onCanvasResized,this),this.destinationRenderTarget=this.camera.renderTarget,this.camera.renderTarget=this.effects[0].inputTarget,this.camera.onPostprocessing=()=>{if(this.enabled){let e=null;const t=this.effects.length;if(t)for(let s=0;s<t;s++){const r=this.effects[s];let i=r.outputTarget;s===t-1&&(e=this.camera.rect,this.destinationRenderTarget&&(i=this.destinationRenderTarget)),r.effect.render(r.inputTarget,i,e)}}})}disable(){this.enabled&&(this.enabled=!1,this.app.graphicsDevice.off("resizecanvas",this._onCanvasResized,this),this._releaseDepthMaps(),this._destroyOffscreenTarget(this._sourceTarget),this.camera.renderTarget=null,this.camera.onPostprocessing=null)}_onCanvasResized(e,t){var s,r;const i=this.camera.rect,a=this.destinationRenderTarget;e=null!=(s=null==a?void 0:a.width)?s:e,t=null!=(r=null==a?void 0:a.height)?r:t,this.camera.camera.aspectRatio=e*i.z/(t*i.w),this.resizeRenderTargets()}resizeRenderTargets(){var e,t;const s=this.app.graphicsDevice,r=this.destinationRenderTarget,i=null!=(e=null==r?void 0:r.width)?e:s.width,a=null!=(t=null==r?void 0:r.height)?t:s.height,h=this.camera.rect,n=Math.floor(h.z*i),f=Math.floor(h.w*a),c=this.effects;for(let e=0,t=c.length;e<t;e++){const t=c[e];t.inputTarget.width===n&&t.inputTarget.height===f||this._resizeOffscreenTarget(t.inputTarget)}}onCameraRectChanged(e,t,s){this.enabled&&this.resizeRenderTargets()}}export{c as PostEffectQueue};