import { IBloomEffect , IOutlineEffect , ISepiaEffect , IVignetteEffect } from "@here/harp-datasource-protocol" ; import { SepiaShader , VignetteShader } from "@here/harp-materials" ; import * as THREE from "three" ; import { IPassManager } from "./IPassManager" ; import { LowResRenderPass } from "./LowResRenderPass" ; import { MSAARenderPass , MSAASampling } from "./MSAARenderPass" ; import { OutlineEffect } from "./Outline" ; import { RenderPass , ShaderPass } from "./Pass" ; import { BloomPass } from "./UnrealBloomPass" ; const DEFAULT_DYNAMIC_MSAA_SAMPLING_LEVEL = MSAASampling . Level_1 ; const DEFAULT_STATIC_MSAA_SAMPLING_LEVEL = MSAASampling . Level_4 ; /**
 * Interface for the antialias settings passed when instantiating
 * a  MapView , and transferred to
 * the  MapRenderingManager instance.
 *
 *  remarks export interface IMapAntialiasSettings { default msaaEnabled : boolean ; default dynamicMsaaSamplingLevel ? : MSAASampling ; default staticMsaaSamplingLevel ? : MSAASampling ; } /**
 * The `MapRenderingManager` class manages the map rendering (as opposed to text) by dispatching the
 *  MapRenderingManager . render call to a set of internal  Pass instances.
 *
 *  remarks export interface IMapRenderingManager extends IPassManager { /**
     * Bloom effect parameters.
     */ bloom : IBloomEffect ; /**
     * Outline effect parameters.
     */ outline : IOutlineEffect ; /**
     * Vignette effect parameters.
     */ vignette : IVignetteEffect ; /**
     * Sepia effect parameters.
     */ sepia : ISepiaEffect ; /**
     * Set a `pixelRatio` for dynamic rendering (i.e. during animations). If a value is specified,
     * the `LowResRenderPass` will be employed to used to render the scene into a lower resolution
     * render target, which will then be rendered to the screen.
     */ lowResPixelRatio ? : number ; /**
     * The level of MSAA sampling while the user interacts. It should be a low level so that the
     * MSAA does not impact the framerate.
     */ dynamicMsaaSamplingLevel : MSAASampling ; /**
     * Enable or disable the MSAA. If disabled, `MapRenderingManager` will use the renderer provided
     * in the  MapRenderingManager . render method to render the scene.
      msaaEnabled : boolean ; /**
     * The higher level of MSAA sampling for a last frame to render, when the camera is static. It
     * can be a high level, providing high quality renders requiring few tens of seconds, since no
     * frame is expected to immediately follow in the requestAnimationFrame. It is still limited by
     * zooming, since zooming is not requestAnimationFrame-based and can lead to stuttering if the
     * render time is too long, except on desktop Mac, where mouse interaction already implements
     * some damping. Higher levels of sampling may lead to noticeable color banding, visible in
     * areas with a slight color gradient, like large areas or the sky background.
     */ staticMsaaSamplingLevel : MSAASampling ; param renderer param isStaticFrame param time render ( renderer , scene , camera , isStaticFrame , time ? ) : void ; param options - outline options from the  {@link @here/harp-datasource-protocol#Theme} .
      updateOutline ( options ) : void ; } /**
 * The implementation of  IMapRenderingManager to
 * instantiate in  MapView and manage the map
 * rendering.
  export class MapRenderingManager implements IMapRenderingManager { bloom = { enabled : false , strength : 1.5 , radius : 0.4 , threshold : 0.85 } ; outline = { enabled : false , thickness : 0.005 , color : "#000000" , ghostExtrudedPolygons : false , needsUpdate : false } ; vignette = { enabled : false , offset : 1.0 , darkness : 1.0 } ; sepia = { enabled : false , amount : 0.5 } ; private m_width : number = 1 ; private m_height : number = 1 ; private m_outlineEffect ? : OutlineEffect ; private m_msaaPass : MSAARenderPass ; private readonly m_renderPass : RenderPass = new RenderPass ( ) ; private readonly m_target1 : THREE . WebGLRenderTarget = new THREE . WebGLRenderTarget ( 1 , 1 ) ; private readonly m_target2 : THREE . WebGLRenderTarget = new THREE . WebGLRenderTarget ( 1 , 1 ) ; private m_bloomPass ? : BloomPass ; private m_sepiaPass : ShaderPass = new ShaderPass ( SepiaShader ) ; private m_vignettePass : ShaderPass = new ShaderPass ( VignetteShader ) ; private readonly m_readBuffer : THREE . WebGLRenderTarget ; private m_dynamicMsaaSamplingLevel : MSAASampling ; private m_staticMsaaSamplingLevel : MSAASampling ; private m_lowResPass : LowResRenderPass ; param width param height param lowResPixelRatio param antialiasSetting constructor ( width , height , lowResPixelRatio , antialiasSettings = { msaaEnabled : false } ) { this . m_readBuffer = new THREE . WebGLRenderTarget ( width , height ) ; this . m_msaaPass = new MSAARenderPass ( ) ; this . m_msaaPass . enabled = antialiasSettings !== undefined ? antialiasSettings . msaaEnabled === true : false ; this . m_dynamicMsaaSamplingLevel = antialiasSettings . dynamicMsaaSamplingLevel === undefined ? DEFAULT_DYNAMIC_MSAA_SAMPLING_LEVEL : antialiasSettings . dynamicMsaaSamplingLevel ; this . m_staticMsaaSamplingLevel = antialiasSettings . staticMsaaSamplingLevel === undefined ? DEFAULT_STATIC_MSAA_SAMPLING_LEVEL : antialiasSettings . staticMsaaSamplingLevel ; this . m_lowResPass = new LowResRenderPass ( lowResPixelRatio ) ; this . m_lowResPass . enabled = lowResPixelRatio !== undefined ; } updateOutline ( options ) { this . outline . color = options . color ; this . outline . thickness = options . thickness ; this . outline . ghostExtrudedPolygons = options . ghostExtrudedPolygons ; this . outline . needsUpdate = true ; } param renderer param scene param camera param isStaticFrame render ( renderer , scene , camera , isStaticFrame ) { const target = null ; if ( ! isStaticFrame && this . m_lowResPass . pixelRatio !== undefined ) { this . m_lowResPass . renderToScreen = true ; this . m_lowResPass . render ( renderer , scene , camera , target , this . m_readBuffer ) ; return ; } const usePostEffects = this . bloom . enabled || this . outline . enabled || this . vignette . enabled || this . sepia . enabled ; let activeTarget = null ; if ( this . bloom . enabled || this . vignette . enabled || this . sepia . enabled ) { renderer . setRenderTarget ( this . m_target1 ) ; renderer . clearDepth ( ) ; } if ( this . m_msaaPass . enabled ) { this . m_msaaPass . samplingLevel = isStaticFrame ? this . m_staticMsaaSamplingLevel : this . m_dynamicMsaaSamplingLevel ; this . m_msaaPass . renderToScreen = ! usePostEffects ; this . m_msaaPass . render ( renderer , scene , camera , target , this . m_readBuffer ) ; } else { if ( this . bloom . enabled || this . vignette . enabled || this . sepia . enabled ) { activeTarget = this . m_target1 ; this . m_renderPass . render ( renderer , scene , camera , this . m_target1 , null ! ) ; } else if ( ! this . outline . enabled || ( this . outline . enabled && ! this . bloom . enabled ) ) { renderer . render ( scene , camera ) ; } } if ( this . outline . enabled ) { if ( this . m_outlineEffect === undefined ) { this . m_outlineEffect = new OutlineEffect ( renderer ) ; } if ( this . outline . needsUpdate ) { this . m_outlineEffect . color = this . outline . color ; this . m_outlineEffect . thickness = this . outline . thickness ; this . m_outlineEffect . ghostExtrudedPolygons = this . outline . ghostExtrudedPolygons ; this . outline . needsUpdate = false ; } const nextEffectEnabled = this . bloom . enabled || this . vignette . enabled || this . sepia . enabled ; if ( nextEffectEnabled ) { activeTarget = this . m_target1 ; } renderer . setRenderTarget ( nextEffectEnabled ? activeTarget : null ! ) ; this . m_outlineEffect . render ( scene , camera ) ; } if ( this . bloom . enabled ) { if ( this . m_bloomPass === undefined ) { this . m_bloomPass = new BloomPass ( new THREE . Vector2 ( this . m_width , this . m_height ) , this . bloom . strength , this . bloom . radius , this . bloom . threshold ) ; } const nextEffectEnabled = this . vignette . enabled || this . sepia . enabled ; this . m_bloomPass . renderToScreen = ! nextEffectEnabled ; this . m_bloomPass . radius = this . bloom . radius ; this . m_bloomPass . strength = this . bloom . strength ; this . m_bloomPass . threshold = this . bloom . threshold ; this . m_bloomPass . render ( renderer , scene , camera , null ! , activeTarget ! ) ; } else if ( this . m_bloomPass !== undefined ) { this . m_bloomPass . dispose ( ) ; this . m_bloomPass = undefined ; } if ( this . vignette . enabled ) { const oldTarget = activeTarget ! ; const nextEffectEnabled = this . sepia . enabled ; this . m_vignettePass . uniforms . offset . value = this . vignette . offset ; this . m_vignettePass . uniforms . darkness . value = this . vignette . darkness ; this . m_vignettePass . renderToScreen = ! nextEffectEnabled ; if ( nextEffectEnabled ) { activeTarget = activeTarget === this . m_target1 ? this . m_target2 : this . m_target1 ; } this . m_vignettePass . render ( renderer , scene , camera , activeTarget ! , oldTarget ) ; } if ( this . sepia . enabled ) { this . m_sepiaPass . renderToScreen = true ; this . m_sepiaPass . uniforms . amount . value = this . sepia . amount ; this . m_sepiaPass . render ( renderer , scene , camera , null ! , activeTarget ! ) ; } } param width param height setSize ( width , height ) { this . m_readBuffer . setSize ( width , height ) ; this . m_msaaPass . setSize ( width , height ) ; if ( this . m_bloomPass !== undefined ) { this . m_bloomPass . setSize ( width , height ) ; } this . m_lowResPass . setSize ( width , height ) ; this . m_target1 . setSize ( width , height ) ; this . m_target2 . setSize ( width , height ) ; this . m_width = width ; this . m_height = height ; } /**
     * The `lowResPixelRatio` determines the resolution of the internal `WebGLRenderTarget`. Values
     * between 0.5 and `window.devicePixelRatio` can be tried to give  good results. A value of
     * `undefined` disables the low res render pass. The value should not be larger than
     * `window.devicePixelRatio`.
     */ get lowResPixelRatio ( ) : number | undefined { return this . m_lowResPass . pixelRatio ; } set lowResPixelRatio ( pixelRatio ) { this . m_lowResPass . pixelRatio = pixelRatio ; this . m_lowResPass . enabled = pixelRatio !== undefined ; } param samplingLevel set dynamicMsaaSamplingLevel ( samplingLevel ) { this . m_dynamicMsaaSamplingLevel = samplingLevel ; } /**
     * Return the sampling level defined during continuous rendering.
     */ get dynamicMsaaSamplingLevel ( ) : MSAASampling { return this . m_dynamicMsaaSamplingLevel ; } /**
     * Enable or disable the MSAA. If disabled, `MapRenderingManager` will use the renderer provided
     * in the  MapRenderingManager . render method to render the scene.
     *
     *  param value set msaaEnabled ( value ) { this . m_msaaPass . enabled = value ; } /**
     * Return whether the MSAA is enabled.
     */ get msaaEnabled ( ) : boolean { return this . m_msaaPass . enabled ; } param samplingLevel set staticMsaaSamplingLevel ( samplingLevel ) { this . m_staticMsaaSamplingLevel = samplingLevel ; } /**
     * Return the sampling level defined for rendering static frames.
     */ get staticMsaaSamplingLevel ( ) : MSAASampling { return this . m_staticMsaaSamplingLevel ; } }