molstar
Version:
A comprehensive macromolecular library.
133 lines (132 loc) • 7.74 kB
JavaScript
/**
* Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { __assign } from "tslib";
import { QuadSchema, QuadValues } from '../../mol-gl/compute/util';
import { createComputeRenderable } from '../../mol-gl/renderable';
import { DefineSpec, TextureSpec, UniformSpec } from '../../mol-gl/renderable/schema';
import { ShaderCode } from '../../mol-gl/shader-code';
import { createComputeRenderItem } from '../../mol-gl/webgl/render-item';
import { Vec2, Vec3 } from '../../mol-math/linear-algebra';
import { ValueCell } from '../../mol-util';
import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { quad_vert } from '../../mol-gl/shader/quad.vert';
import { overlay_frag } from '../../mol-gl/shader/marking/overlay.frag';
import { Color } from '../../mol-util/color';
import { edge_frag } from '../../mol-gl/shader/marking/edge.frag';
import { isTimingMode } from '../../mol-util/debug';
export var MarkingParams = {
enabled: PD.Boolean(true),
highlightEdgeColor: PD.Color(Color.darken(Color.fromNormalizedRgb(1.0, 0.4, 0.6), 1.0)),
selectEdgeColor: PD.Color(Color.darken(Color.fromNormalizedRgb(0.2, 1.0, 0.1), 1.0)),
edgeScale: PD.Numeric(1, { min: 1, max: 3, step: 1 }, { description: 'Thickness of the edge.' }),
ghostEdgeStrength: PD.Numeric(0.3, { min: 0, max: 1, step: 0.1 }, { description: 'Opacity of the hidden edges that are covered by other geometry. When set to 1, one less geometry render pass is done.' }),
innerEdgeFactor: PD.Numeric(1.5, { min: 0, max: 3, step: 0.1 }, { description: 'Factor to multiply the inner edge color with - for added contrast.' }),
};
var MarkingPass = /** @class */ (function () {
function MarkingPass(webgl, width, height) {
this.webgl = webgl;
this.depthTarget = webgl.createRenderTarget(width, height);
this.maskTarget = webgl.createRenderTarget(width, height);
this.edgesTarget = webgl.createRenderTarget(width, height);
this.edge = getEdgeRenderable(webgl, this.maskTarget.texture);
this.overlay = getOverlayRenderable(webgl, this.edgesTarget.texture);
}
MarkingPass.isEnabled = function (props) {
return props.enabled;
};
MarkingPass.prototype.setEdgeState = function (viewport) {
var _a = this.webgl, gl = _a.gl, state = _a.state;
state.enable(gl.SCISSOR_TEST);
state.enable(gl.BLEND);
state.blendFunc(gl.ONE, gl.ONE);
state.blendEquation(gl.FUNC_ADD);
state.disable(gl.DEPTH_TEST);
state.depthMask(false);
var x = viewport.x, y = viewport.y, width = viewport.width, height = viewport.height;
state.viewport(x, y, width, height);
state.scissor(x, y, width, height);
state.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
};
MarkingPass.prototype.setOverlayState = function (viewport) {
var _a = this.webgl, gl = _a.gl, state = _a.state;
state.enable(gl.SCISSOR_TEST);
state.enable(gl.BLEND);
state.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
state.blendEquation(gl.FUNC_ADD);
state.disable(gl.DEPTH_TEST);
state.depthMask(false);
var x = viewport.x, y = viewport.y, width = viewport.width, height = viewport.height;
state.viewport(x, y, width, height);
state.scissor(x, y, width, height);
};
MarkingPass.prototype.setSize = function (width, height) {
var w = this.depthTarget.getWidth();
var h = this.depthTarget.getHeight();
if (width !== w || height !== h) {
this.depthTarget.setSize(width, height);
this.maskTarget.setSize(width, height);
this.edgesTarget.setSize(width, height);
ValueCell.update(this.edge.values.uTexSizeInv, Vec2.set(this.edge.values.uTexSizeInv.ref.value, 1 / width, 1 / height));
ValueCell.update(this.overlay.values.uTexSizeInv, Vec2.set(this.overlay.values.uTexSizeInv.ref.value, 1 / width, 1 / height));
}
};
MarkingPass.prototype.update = function (props) {
var highlightEdgeColor = props.highlightEdgeColor, selectEdgeColor = props.selectEdgeColor, edgeScale = props.edgeScale, innerEdgeFactor = props.innerEdgeFactor, ghostEdgeStrength = props.ghostEdgeStrength;
var edgeValues = this.edge.values;
var _edgeScale = Math.round(edgeScale * this.webgl.pixelRatio);
if (edgeValues.dEdgeScale.ref.value !== _edgeScale) {
ValueCell.update(edgeValues.dEdgeScale, _edgeScale);
this.edge.update();
}
var overlayValues = this.overlay.values;
ValueCell.update(overlayValues.uHighlightEdgeColor, Color.toVec3Normalized(overlayValues.uHighlightEdgeColor.ref.value, highlightEdgeColor));
ValueCell.update(overlayValues.uSelectEdgeColor, Color.toVec3Normalized(overlayValues.uSelectEdgeColor.ref.value, selectEdgeColor));
ValueCell.update(overlayValues.uInnerEdgeFactor, innerEdgeFactor);
ValueCell.update(overlayValues.uGhostEdgeStrength, ghostEdgeStrength);
};
MarkingPass.prototype.render = function (viewport, target) {
if (isTimingMode)
this.webgl.timer.mark('MarkingPass.render');
this.edgesTarget.bind();
this.setEdgeState(viewport);
this.edge.render();
if (target) {
target.bind();
}
else {
this.webgl.unbindFramebuffer();
}
this.setOverlayState(viewport);
this.overlay.render();
if (isTimingMode)
this.webgl.timer.markEnd('MarkingPass.render');
};
return MarkingPass;
}());
export { MarkingPass };
//
var EdgeSchema = __assign(__assign({}, QuadSchema), { tMaskTexture: TextureSpec('texture', 'rgba', 'ubyte', 'linear'), uTexSizeInv: UniformSpec('v2'), dEdgeScale: DefineSpec('number') });
var EdgeShaderCode = ShaderCode('edge', quad_vert, edge_frag);
function getEdgeRenderable(ctx, maskTexture) {
var width = maskTexture.getWidth();
var height = maskTexture.getHeight();
var values = __assign(__assign({}, QuadValues), { tMaskTexture: ValueCell.create(maskTexture), uTexSizeInv: ValueCell.create(Vec2.create(1 / width, 1 / height)), dEdgeScale: ValueCell.create(1) });
var schema = __assign({}, EdgeSchema);
var renderItem = createComputeRenderItem(ctx, 'triangles', EdgeShaderCode, schema, values);
return createComputeRenderable(renderItem, values);
}
//
var OverlaySchema = __assign(__assign({}, QuadSchema), { tEdgeTexture: TextureSpec('texture', 'rgba', 'ubyte', 'linear'), uTexSizeInv: UniformSpec('v2'), uHighlightEdgeColor: UniformSpec('v3'), uSelectEdgeColor: UniformSpec('v3'), uGhostEdgeStrength: UniformSpec('f'), uInnerEdgeFactor: UniformSpec('f') });
var OverlayShaderCode = ShaderCode('overlay', quad_vert, overlay_frag);
function getOverlayRenderable(ctx, edgeTexture) {
var width = edgeTexture.getWidth();
var height = edgeTexture.getHeight();
var values = __assign(__assign({}, QuadValues), { tEdgeTexture: ValueCell.create(edgeTexture), uTexSizeInv: ValueCell.create(Vec2.create(1 / width, 1 / height)), uHighlightEdgeColor: ValueCell.create(Vec3()), uSelectEdgeColor: ValueCell.create(Vec3()), uGhostEdgeStrength: ValueCell.create(0), uInnerEdgeFactor: ValueCell.create(0) });
var schema = __assign({}, OverlaySchema);
var renderItem = createComputeRenderItem(ctx, 'triangles', OverlayShaderCode, schema, values);
return createComputeRenderable(renderItem, values);
}