UNPKG

@deck.gl/experimental-layers

Version:

Experimental layers for deck.gl

155 lines (143 loc) 4.71 kB
import { PathLayer } from '@deck.gl/layers'; import GL from 'luma.gl/constants'; import { Framebuffer, Texture2D } from 'luma.gl'; import outline from '../shaderlib/outline/outline'; // TODO - this should be built into assembleShaders function injectShaderCode(_ref) { let source = _ref.source, _ref$declarations = _ref.declarations, declarations = _ref$declarations === void 0 ? '' : _ref$declarations, _ref$code = _ref.code, code = _ref$code === void 0 ? '' : _ref$code; const INJECT_DECLARATIONS = /^/; const INJECT_CODE = /}[^{}]*$/; return source.replace(INJECT_DECLARATIONS, declarations).replace(INJECT_CODE, code.concat('\n}\n')); } const VS_DECLARATIONS = `\ #ifdef MODULE_OUTLINE attribute float instanceZLevel; #endif `; const VS_CODE = `\ #ifdef MODULE_OUTLINE outline_setUV(gl_Position); outline_setZLevel(instanceZLevel); #endif `; const FS_CODE = `\ #ifdef MODULE_OUTLINE gl_FragColor = outline_filterColor(gl_FragColor); #endif `; const defaultProps = { getZLevel: { type: 'accessor', value: 0 } }; export default class PathOutlineLayer extends PathLayer { // Override getShaders to inject the outline module getShaders() { const shaders = super.getShaders(); return Object.assign({}, shaders, { modules: shaders.modules.concat([outline]), vs: injectShaderCode({ source: shaders.vs, declarations: VS_DECLARATIONS, code: VS_CODE }), fs: injectShaderCode({ source: shaders.fs, code: FS_CODE }) }); } initializeState(context) { super.initializeState(context); // Create an outline "shadow" map // TODO - we should create a single outlineMap for all layers this.setState({ outlineFramebuffer: new Framebuffer(context.gl), dummyTexture: new Texture2D(context.gl) }); // Create an attribute manager this.state.attributeManager.addInstanced({ instanceZLevel: { size: 1, type: GL.UNSIGNED_BYTE, update: this.calculateZLevels, accessor: 'getZLevel' } }); } // Override draw to add render module draw(_ref2) { let _ref2$moduleParameter = _ref2.moduleParameters, moduleParameters = _ref2$moduleParameter === void 0 ? {} : _ref2$moduleParameter, parameters = _ref2.parameters, uniforms = _ref2.uniforms, context = _ref2.context; // Need to calculate same uniforms as base layer const _this$props = this.props, rounded = _this$props.rounded, miterLimit = _this$props.miterLimit, widthScale = _this$props.widthScale, widthMinPixels = _this$props.widthMinPixels, widthMaxPixels = _this$props.widthMaxPixels, dashJustified = _this$props.dashJustified; uniforms = Object.assign({}, uniforms, { jointType: Number(rounded), alignMode: Number(dashJustified), widthScale, miterLimit, widthMinPixels, widthMaxPixels }); // Render the outline shadowmap (based on segment z orders) const _this$state = this.state, outlineFramebuffer = _this$state.outlineFramebuffer, dummyTexture = _this$state.dummyTexture; outlineFramebuffer.resize(); outlineFramebuffer.clear({ color: true, depth: true }); this.state.model.updateModuleSettings({ outlineEnabled: true, outlineRenderShadowmap: true, outlineShadowmap: dummyTexture }); this.state.model.draw({ uniforms: Object.assign({}, uniforms, { jointType: 0, widthScale: this.props.widthScale * 1.3 }), parameters: { depthTest: false, blendEquation: GL.MAX // Biggest value needs to go into buffer }, framebuffer: outlineFramebuffer }); // Now use the outline shadowmap to render the lines (with outlines) this.state.model.updateModuleSettings({ outlineEnabled: true, outlineRenderShadowmap: false, outlineShadowmap: outlineFramebuffer }); this.state.model.draw({ uniforms: Object.assign({}, uniforms, { jointType: Number(rounded), widthScale: this.props.widthScale }), parameters: { depthTest: false } }); } calculateZLevels(attribute) { const getZLevel = this.props.getZLevel; const pathTesselator = this.state.pathTesselator; attribute.value = pathTesselator._updateAttribute({ target: attribute.value, size: 1, getValue: (object, index) => [getZLevel(object, index) || 0] }); } } PathOutlineLayer.layerName = 'PathOutlineLayer'; PathOutlineLayer.defaultProps = defaultProps; //# sourceMappingURL=path-outline-layer.js.map