From a31646ce4a5c25ed04ac5af3fea14521ecd193e0 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Tue, 5 Mar 2019 14:40:23 -0800 Subject: [PATCH] overpaint, geo and gl schema --- .../geometry/direct-volume/direct-volume.ts | 3 + src/mol-geo/geometry/lines/lines.ts | 3 + src/mol-geo/geometry/mesh/mesh.ts | 3 + src/mol-geo/geometry/overpaint-data.ts | 57 +++++++++++++++++++ src/mol-geo/geometry/points/points.ts | 3 + src/mol-geo/geometry/spheres/spheres.ts | 3 + src/mol-geo/geometry/text/text.ts | 3 + src/mol-gl/_spec/renderer.spec.ts | 3 + src/mol-gl/renderable/direct-volume.ts | 4 ++ src/mol-gl/renderable/schema.ts | 21 ++++++- .../shader/chunks/assign-color-varying.glsl | 4 ++ .../shader/chunks/assign-material-color.glsl | 5 ++ .../shader/chunks/color-frag-params.glsl | 4 ++ .../shader/chunks/color-vert-params.glsl | 6 ++ 14 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/mol-geo/geometry/overpaint-data.ts diff --git a/src/mol-geo/geometry/direct-volume/direct-volume.ts b/src/mol-geo/geometry/direct-volume/direct-volume.ts index d97903561..ea2c9694c 100644 --- a/src/mol-geo/geometry/direct-volume/direct-volume.ts +++ b/src/mol-geo/geometry/direct-volume/direct-volume.ts @@ -24,6 +24,7 @@ import { RenderableState } from 'mol-gl/renderable'; import { ColorListOptions, ColorListName } from 'mol-util/color/scale'; import { Color } from 'mol-util/color'; import { BaseGeometry } from '../base'; +import { createEmptyOverpaint } from '../overpaint-data'; const VolumeBox = Box() const RenderModeOptions = [['isosurface', 'Isosurface'], ['volume', 'Volume']] as [string, string][] @@ -101,6 +102,7 @@ export namespace DirectVolume { const { instanceCount, groupCount } = locationIt const color = createColors(locationIt, theme.color) const marker = createMarkers(instanceCount * groupCount) + const overpaint = createEmptyOverpaint() const counts = { drawCount: VolumeBox.indices.length, groupCount, instanceCount } @@ -114,6 +116,7 @@ export namespace DirectVolume { return { ...color, ...marker, + ...overpaint, ...transform, ...BaseGeometry.createValues(props, counts), diff --git a/src/mol-geo/geometry/lines/lines.ts b/src/mol-geo/geometry/lines/lines.ts index ef5d980f8..ae67ba728 100644 --- a/src/mol-geo/geometry/lines/lines.ts +++ b/src/mol-geo/geometry/lines/lines.ts @@ -22,6 +22,7 @@ import { Sphere3D } from 'mol-math/geometry'; import { Theme } from 'mol-theme/theme'; import { Color } from 'mol-util/color'; import { BaseGeometry } from '../base'; +import { createEmptyOverpaint } from '../overpaint-data'; /** Wide line */ export interface Lines { @@ -117,6 +118,7 @@ export namespace Lines { const color = createColors(locationIt, theme.color) const size = createSizes(locationIt, theme.size) const marker = createMarkers(instanceCount * groupCount) + const overpaint = createEmptyOverpaint() const counts = { drawCount: lines.lineCount * 2 * 3, groupCount, instanceCount } @@ -134,6 +136,7 @@ export namespace Lines { ...color, ...size, ...marker, + ...overpaint, ...transform, ...BaseGeometry.createValues(props, counts), diff --git a/src/mol-geo/geometry/mesh/mesh.ts b/src/mol-geo/geometry/mesh/mesh.ts index 272cdfd03..fd594d952 100644 --- a/src/mol-geo/geometry/mesh/mesh.ts +++ b/src/mol-geo/geometry/mesh/mesh.ts @@ -21,6 +21,7 @@ import { Theme } from 'mol-theme/theme'; import { MeshValues } from 'mol-gl/renderable/mesh'; import { Color } from 'mol-util/color'; import { BaseGeometry } from '../base'; +import { createEmptyOverpaint } from '../overpaint-data'; export interface Mesh { readonly kind: 'mesh', @@ -381,6 +382,7 @@ export namespace Mesh { const color = createColors(locationIt, theme.color) const marker = createMarkers(instanceCount * groupCount) + const overpaint = createEmptyOverpaint() const counts = { drawCount: mesh.triangleCount * 3, groupCount, instanceCount } @@ -398,6 +400,7 @@ export namespace Mesh { invariantBoundingSphere: ValueCell.create(invariantBoundingSphere), ...color, ...marker, + ...overpaint, ...transform, ...BaseGeometry.createValues(props, counts), diff --git a/src/mol-geo/geometry/overpaint-data.ts b/src/mol-geo/geometry/overpaint-data.ts new file mode 100644 index 000000000..54dee822b --- /dev/null +++ b/src/mol-geo/geometry/overpaint-data.ts @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { ValueCell } from 'mol-util/value-cell' +import { Vec2 } from 'mol-math/linear-algebra' +import { TextureImage, createTextureImage } from 'mol-gl/renderable/util'; +import { Color } from 'mol-util/color'; + +export type OverpaintData = { + tOverpaint: ValueCell<TextureImage<Uint8Array>> + uOverpaintTexDim: ValueCell<Vec2> + dOverpaint: ValueCell<boolean>, +} + +export function applyOverpaintColor(array: Uint8Array, start: number, end: number, color: Color) { + for (let i = start; i < end; ++i) { + Color.toArray(color, array, i * 4) + array[i * 4 + 3] = 255 + } + return true +} + +export function createOverpaint(count: number, overpaintData?: OverpaintData): OverpaintData { + const overpaint = overpaintData && overpaintData.tOverpaint.ref.value.array.length >= count * 4 + ? overpaintData.tOverpaint.ref.value + : createTextureImage(count, 4) + if (overpaintData) { + ValueCell.update(overpaintData.tOverpaint, overpaint) + ValueCell.update(overpaintData.uOverpaintTexDim, Vec2.create(overpaint.width, overpaint.height)) + ValueCell.update(overpaintData.dOverpaint, count > 0) + return overpaintData + } else { + return { + tOverpaint: ValueCell.create(overpaint), + uOverpaintTexDim: ValueCell.create(Vec2.create(overpaint.width, overpaint.height)), + dOverpaint: ValueCell.create(count > 0), + } + } +} + +const emptyOverpaintTexture = { array: new Uint8Array(4), width: 1, height: 1 } +export function createEmptyOverpaint(overpaintData?: OverpaintData): OverpaintData { + if (overpaintData) { + ValueCell.update(overpaintData.tOverpaint, emptyOverpaintTexture) + ValueCell.update(overpaintData.uOverpaintTexDim, Vec2.create(1, 1)) + return overpaintData + } else { + return { + tOverpaint: ValueCell.create(emptyOverpaintTexture), + uOverpaintTexDim: ValueCell.create(Vec2.create(1, 1)), + dOverpaint: ValueCell.create(false), + } + } +} \ No newline at end of file diff --git a/src/mol-geo/geometry/points/points.ts b/src/mol-geo/geometry/points/points.ts index ecfe127bf..7cda2e36e 100644 --- a/src/mol-geo/geometry/points/points.ts +++ b/src/mol-geo/geometry/points/points.ts @@ -21,6 +21,7 @@ import { PointsValues } from 'mol-gl/renderable/points'; import { RenderableState } from 'mol-gl/renderable'; import { Color } from 'mol-util/color'; import { BaseGeometry } from '../base'; +import { createEmptyOverpaint } from '../overpaint-data'; /** Point cloud */ export interface Points { @@ -82,6 +83,7 @@ export namespace Points { const color = createColors(locationIt, theme.color) const size = createSizes(locationIt, theme.size) const marker = createMarkers(instanceCount * groupCount) + const overpaint = createEmptyOverpaint() const counts = { drawCount: points.pointCount, groupCount, instanceCount } @@ -98,6 +100,7 @@ export namespace Points { ...color, ...size, ...marker, + ...overpaint, ...transform, ...BaseGeometry.createValues(props, counts), diff --git a/src/mol-geo/geometry/spheres/spheres.ts b/src/mol-geo/geometry/spheres/spheres.ts index 41bd89bfc..eb22f55a9 100644 --- a/src/mol-geo/geometry/spheres/spheres.ts +++ b/src/mol-geo/geometry/spheres/spheres.ts @@ -18,6 +18,7 @@ import { Sphere3D } from 'mol-math/geometry'; import { createSizes, getMaxSize } from '../size-data'; import { Color } from 'mol-util/color'; import { BaseGeometry } from '../base'; +import { createEmptyOverpaint } from '../overpaint-data'; /** Spheres */ export interface Spheres { @@ -79,6 +80,7 @@ export namespace Spheres { const color = createColors(locationIt, theme.color) const size = createSizes(locationIt, theme.size) const marker = createMarkers(instanceCount * groupCount) + const overpaint = createEmptyOverpaint() const counts = { drawCount: spheres.sphereCount * 2 * 3, groupCount, instanceCount } @@ -98,6 +100,7 @@ export namespace Spheres { ...color, ...size, ...marker, + ...overpaint, ...transform, padding: ValueCell.create(padding), diff --git a/src/mol-geo/geometry/text/text.ts b/src/mol-geo/geometry/text/text.ts index d8b829201..db7abd370 100644 --- a/src/mol-geo/geometry/text/text.ts +++ b/src/mol-geo/geometry/text/text.ts @@ -24,6 +24,7 @@ import { RenderableState } from 'mol-gl/renderable'; import { clamp } from 'mol-math/interpolate'; import { createRenderObject as _createRenderObject } from 'mol-gl/render-object'; import { BaseGeometry } from '../base'; +import { createEmptyOverpaint } from '../overpaint-data'; type TextAttachment = ( 'bottom-left' | 'bottom-center' | 'bottom-right' | @@ -119,6 +120,7 @@ export namespace Text { const color = createColors(locationIt, theme.color) const size = createSizes(locationIt, theme.size) const marker = createMarkers(instanceCount * groupCount) + const overpaint = createEmptyOverpaint() const counts = { drawCount: text.charCount * 2 * 3, groupCount, instanceCount } @@ -139,6 +141,7 @@ export namespace Text { ...color, ...size, ...marker, + ...overpaint, ...transform, aTexCoord: text.tcoordBuffer, diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts index f9b34b703..0ec689e49 100644 --- a/src/mol-gl/_spec/renderer.spec.ts +++ b/src/mol-gl/_spec/renderer.spec.ts @@ -22,6 +22,7 @@ import { createEmptyMarkers } from 'mol-geo/geometry/marker-data'; import { fillSerial } from 'mol-util/array'; import { Color } from 'mol-util/color'; import { Sphere3D } from 'mol-math/geometry'; +import { createEmptyOverpaint } from 'mol-geo/geometry/overpaint-data'; // function writeImage(gl: WebGLRenderingContext, width: number, height: number) { // const pixels = new Uint8Array(width * height * 4) @@ -52,6 +53,7 @@ function createPoints() { const color = createValueColor(Color(0xFF0000)) const size = createValueSize(1) const marker = createEmptyMarkers() + const overpaint = createEmptyOverpaint() const aTransform = ValueCell.create(new Float32Array(16)) const m4 = Mat4.identity() @@ -70,6 +72,7 @@ function createPoints() { ...color, ...marker, ...size, + ...overpaint, uAlpha: ValueCell.create(1.0), uHighlightColor: ValueCell.create(Vec3.create(1.0, 0.4, 0.6)), diff --git a/src/mol-gl/renderable/direct-volume.ts b/src/mol-gl/renderable/direct-volume.ts index 0ec65356f..3a2ca5fbd 100644 --- a/src/mol-gl/renderable/direct-volume.ts +++ b/src/mol-gl/renderable/direct-volume.ts @@ -20,6 +20,10 @@ export const DirectVolumeSchema = { uMarkerTexDim: UniformSpec('v2'), tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'), + uOverpaintTexDim: UniformSpec('v2'), + tOverpaint: TextureSpec('image-uint8', 'rgba', 'ubyte', 'nearest'), + dOverpaint: DefineSpec('boolean'), + uInstanceCount: UniformSpec('i'), uGroupCount: UniformSpec('i'), diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 51bfcd7c5..4a0fce48c 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/src/mol-gl/renderable/schema.ts @@ -200,8 +200,25 @@ export const SizeSchema = { export type SizeSchema = typeof SizeSchema export type SizeValues = Values<SizeSchema> +export const MarkerSchema = { + uMarkerTexDim: UniformSpec('v2'), + tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'), +} +export type MarkerSchema = typeof MarkerSchema +export type MarkerValues = Values<MarkerSchema> + +export const OverpaintSchema = { + uOverpaintTexDim: UniformSpec('v2'), + tOverpaint: TextureSpec('image-uint8', 'rgba', 'ubyte', 'nearest'), + dOverpaint: DefineSpec('boolean'), +} +export type OverpaintSchema = typeof OverpaintSchema +export type OverpaintValues = Values<OverpaintSchema> + export const BaseSchema = { ...ColorSchema, + ...MarkerSchema, + ...OverpaintSchema, aInstance: AttributeSpec('float32', 1, 1), aGroup: AttributeSpec('float32', 1, 0), @@ -214,12 +231,10 @@ export const BaseSchema = { uAlpha: UniformSpec('f'), uInstanceCount: UniformSpec('i'), uGroupCount: UniformSpec('i'), - uMarkerTexDim: UniformSpec('v2'), + uHighlightColor: UniformSpec('v3'), uSelectColor: UniformSpec('v3'), - tMarker: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'), - drawCount: ValueSpec('number'), instanceCount: ValueSpec('number'), diff --git a/src/mol-gl/shader/chunks/assign-color-varying.glsl b/src/mol-gl/shader/chunks/assign-color-varying.glsl index e2e7e150a..7175df041 100644 --- a/src/mol-gl/shader/chunks/assign-color-varying.glsl +++ b/src/mol-gl/shader/chunks/assign-color-varying.glsl @@ -12,4 +12,8 @@ vColor = vec4(encodeFloatRGB(aInstance), 1.0); #elif defined(dColorType_groupPicking) vColor = vec4(encodeFloatRGB(aGroup), 1.0); +#endif + +#ifdef dOverpaint + vOverpaint = readFromTexture(tOverpaint, aInstance * float(uGroupCount) + aGroup, uOverpaintTexDim); #endif \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/assign-material-color.glsl b/src/mol-gl/shader/chunks/assign-material-color.glsl index 81758eabc..d79b00d7d 100644 --- a/src/mol-gl/shader/chunks/assign-material-color.glsl +++ b/src/mol-gl/shader/chunks/assign-material-color.glsl @@ -4,4 +4,9 @@ vec4 material = vec4(vColor.rgb, uAlpha); #elif defined(dColorType_objectPicking) || defined(dColorType_instancePicking) || defined(dColorType_groupPicking) vec4 material = uPickable == 1 ? vColor : vec4(0.0, 0.0, 0.0, 1.0); // set to empty picking id +#endif + +// mix material with overpaint +#if defined(dOverpaint) && (defined(dColorType_uniform) || defined(dColorType_attribute) || defined(dColorType_instance) || defined(dColorType_group) || defined(dColorType_groupInstance)) + material.rgb = mix(material.rgb, vOverpaint.rgb, vOverpaint.a); #endif \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/color-frag-params.glsl b/src/mol-gl/shader/chunks/color-frag-params.glsl index 85052a170..871e2dee3 100644 --- a/src/mol-gl/shader/chunks/color-frag-params.glsl +++ b/src/mol-gl/shader/chunks/color-frag-params.glsl @@ -8,4 +8,8 @@ #else flat in vec4 vColor; #endif +#endif + +#ifdef dOverpaint + varying vec4 vOverpaint; #endif \ No newline at end of file diff --git a/src/mol-gl/shader/chunks/color-vert-params.glsl b/src/mol-gl/shader/chunks/color-vert-params.glsl index d2219d9b6..b3156a22e 100644 --- a/src/mol-gl/shader/chunks/color-vert-params.glsl +++ b/src/mol-gl/shader/chunks/color-vert-params.glsl @@ -14,4 +14,10 @@ flat out vec4 vColor; #endif #pragma glslify: encodeFloatRGB = require(../utils/encode-float-rgb.glsl) +#endif + +#ifdef dOverpaint + varying vec4 vOverpaint; + uniform vec2 uOverpaintTexDim; + uniform sampler2D tOverpaint; #endif \ No newline at end of file -- GitLab