diff --git a/src/mol-geo/geometry/direct-volume/direct-volume.ts b/src/mol-geo/geometry/direct-volume/direct-volume.ts index d979035617bbf70081b15529cb5c48880285eff3..ea2c9694c19dd979d2245baba0cde0a8050eb37d 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 ef5d980f8539daaa64af48d9d568b97008932da5..ae67ba72846425707ac4b24f91740c0b111820b5 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 272cdfd03a458a354ba9048c3c3e824c0da55a42..fd594d952c6ad0aa3f886828537e0f833651b53c 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 0000000000000000000000000000000000000000..54dee822b3eaa9f99eeba242441f20a06a1a3de1 --- /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 ecfe127bf764840c2f3521cfd07db4f13dd3f303..7cda2e36ef2d8241561cdbcb1a341cfbf99d1446 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 41bd89bfc7f3f604e0fb5ac0eb4f8c5cd4381cc2..eb22f55a918043f512f28824d857b3fb61d00db1 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 d8b82920149e957d23744a00c24b31a1a1325677..db7abd3706fc058e532bb51ea1087420e1156701 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 f9b34b7031ef4bbeff341fe8f2c3f91477aa05e0..0ec689e49acad26b9c198c9dd031b7557bf92048 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 0ec65356f66f78ab92bff6deeae1849e346bc559..3a2ca5fbd32ecad7ae529eb2b1814c4858420ab8 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 51bfcd7c58ac93e76977d6e6b409dd1b3335832e..4a0fce48c914b64e57884188c71006c2ad18191a 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 e2e7e150af8b051086c3a1827e717e7a074588b4..7175df041fa3cf59c66964a3a0598d49ac20c05f 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 81758eabcd3b6630f7e7cd1cf3f2f819f419695e..d79b00d7da917237b2e5c1b657ccf1683adbd14b 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 85052a17025d578608312aeae2d04d49519c1eee..871e2dee3e9551de259c1273ac869154228df38e 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 d2219d9b6019165b6bafbfde21226b614244c1ba..b3156a22ee6f0cabb1cf1505e09b82570ce865da 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