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